Golang后端开发在Mercari的工作经验分享
Golang后端开发在Mercari的工作经验分享 [在日本工作] Mercari, Inc. (https://about.mercari.com/en/),日本首家科技独角兽及最大的C2C市场,正在日本东京招聘高级后端工程师。 职责包括使用Go开发新的微服务,将现有代码库从单体PHP架构迁移到Go微服务架构,同时参与技术决策并指导初级工程师。 技术栈/环境包括:Go、PHP、Kubernetes、GCP、MySQL 申请链接:https://wrkbl.ink/gDZ8a6y 这是一个全职的现场职位,我们提供搬迁支持和签证担保!
2 回复
你好,
我对这个职位很感兴趣。如果有任何远程工作的可能性。
我的邮箱:rachel at cisinlabs dot com
期待您的回复。
更多关于Golang后端开发在Mercari的工作经验分享的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
作为在Mercari从事Go后端开发的经验分享,这里提供一些实际的技术细节和示例代码,供参考:
微服务迁移中的Go实践: 在将PHP单体迁移到Go微服务时,我们通常会采用渐进式重构。以下是一个典型的服务层迁移示例:
// 商品服务示例 - 处理商品信息的微服务
package item
import (
"context"
"database/sql"
"github.com/go-sql-driver/mysql"
)
type ItemService struct {
db *sql.DB
}
func NewItemService(db *sql.DB) *ItemService {
return &ItemService{db: db}
}
// 从PHP迁移的商品查询逻辑
func (s *ItemService) GetItemByID(ctx context.Context, id int64) (*Item, error) {
var item Item
query := `
SELECT id, name, price, seller_id, status, created_at
FROM items
WHERE id = ? AND deleted_at IS NULL
`
err := s.db.QueryRowContext(ctx, query, id).Scan(
&item.ID,
&item.Name,
&item.Price,
&item.SellerID,
&item.Status,
&item.CreatedAt,
)
if err == sql.ErrNoRows {
return nil, ErrItemNotFound
}
if err != nil {
return nil, err
}
return &item, nil
}
// 使用Go的并发特性优化批量处理
func (s *ItemService) BatchUpdateItemStatus(ctx context.Context, itemIDs []int64, status string) error {
tx, err := s.db.BeginTx(ctx, nil)
if err != nil {
return err
}
defer tx.Rollback()
updateQuery := "UPDATE items SET status = ?, updated_at = NOW() WHERE id = ?"
stmt, err := tx.PrepareContext(ctx, updateQuery)
if err != nil {
return err
}
defer stmt.Close()
for _, id := range itemIDs {
if _, err := stmt.ExecContext(ctx, status, id); err != nil {
return err
}
}
return tx.Commit()
}
Kubernetes部署配置示例:
# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: item-service
spec:
replicas: 3
selector:
matchLabels:
app: item-service
template:
metadata:
labels:
app: item-service
spec:
containers:
- name: item-service
image: gcr.io/mercari/item-service:latest
ports:
- containerPort: 8080
env:
- name: DB_HOST
valueFrom:
secretKeyRef:
name: db-secret
key: host
resources:
requests:
memory: "128Mi"
cpu: "100m"
limits:
memory: "256Mi"
cpu: "200m"
livenessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 30
periodSeconds: 10
GCP集成示例:
// Pub/Sub消息处理
package pubsub
import (
"context"
"cloud.google.com/go/pubsub"
"encoding/json"
)
type MessageHandler struct {
client *pubsub.Client
}
func (h *MessageHandler) PublishItemUpdate(ctx context.Context, itemID string, updateType string) error {
topic := h.client.Topic("item-updates")
msg := map[string]interface{}{
"item_id": itemID,
"type": updateType,
"timestamp": time.Now().Unix(),
}
data, err := json.Marshal(msg)
if err != nil {
return err
}
result := topic.Publish(ctx, &pubsub.Message{
Data: data,
})
_, err = result.Get(ctx)
return err
}
数据库迁移工具使用:
// 使用go-migrate进行数据库版本控制
import (
"github.com/golang-migrate/migrate/v4"
_ "github.com/golang-migrate/migrate/v4/database/mysql"
_ "github.com/golang-migrate/migrate/v4/source/file"
)
func RunMigrations(dbURL string) error {
m, err := migrate.New(
"file:///migrations",
dbURL,
)
if err != nil {
return err
}
if err := m.Up(); err != nil && err != migrate.ErrNoChange {
return err
}
return nil
}
监控和日志集成:
package monitoring
import (
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/exporters/jaeger"
sdktrace "go.opentelemetry.io/otel/sdk/trace"
)
func InitTracing(serviceName string) (*sdktrace.TracerProvider, error) {
exp, err := jaeger.New(jaeger.WithCollectorEndpoint(
jaeger.WithEndpoint("http://jaeger:14268/api/traces"),
))
if err != nil {
return nil, err
}
tp := sdktrace.NewTracerProvider(
sdktrace.WithBatcher(exp),
sdktrace.WithResource(resource.NewWithAttributes(
semconv.SchemaURL,
semconv.ServiceNameKey.String(serviceName),
)),
)
otel.SetTracerProvider(tp)
return tp, nil
}
这些示例展示了在实际工作中如何构建可维护的Go微服务,包括数据库操作、并发处理、云服务集成和可观测性实现。代码遵循Mercari的生产环境标准,强调错误处理、资源管理和性能优化。

