go微服务需基于限界上下文拆分,各服务数据自持、演化独立;grpc调用必须透传context以保障超时与trace-id传递,禁用time.sleep。

Go 本身不提供微服务,只提供能搭微服务的零件。你写完 http.ListenAndServe 或跑通 gin.Default().Run,离真正可运维的微服务还差很远——边界没划清、超时没控住、日志查不动、服务挂了没人知道。
怎么拆服务才不是“分布式单体”
按“用户”“订单”“支付”建三个服务,结果每个都要查对方数据库、互相调 /user/{id}/orders 这类接口,就是典型的伪微服务。真正的拆分依据是限界上下文(Bounded Context):一个服务只负责一个完整业务闭环,数据自持、演化独立。
- 识别动作场景:比如「密码重置」和「头像上传」生命周期不同、一致性要求不同,就该拆成
authn和profile两个服务 - 每个服务配独立数据库 schema,禁止跨服务直连别人 DB
- 代码路径反映边界:
github.com/yourorg/authn,不是github.com/yourorg/backend/users -
internal/目录严禁被其他服务 import;api/下只放.proto或 REST 接口定义
gRPC 客户端调用总超时?先看 context 传没传对
context deadline exceeded 错误八成不是 timeout 设太短,而是 ctx 根本没透传下去。A → B → C 链路中,只要中间某层用了 context.Background() 或忘了把入参 ctx 传给下游 client,超时信号就断了。
Go语言(Golang)1.26.0版本提供 Go 官方 Windows amd64 MSI 安装包下载入口,版本号 1.26.0,可用于旧项目维护、兼容性测试和指定版本开发环境配置。
- 所有 gRPC 调用必须显式传原始
ctx:client.CreateOrder(ctx, req),不能 new 新 context - 需要透传 trace-id 等 metadata,用
metadata.AppendToOutgoingContext(ctx, "trace-id", id),别塞进 request struct - handler 里模拟耗时别用
time.Sleep,它不响应ctx.Done();改用select { case - 本地开发时,
grpc.DialContext必须加grpc.WithInsecure(),否则 TLS 握手失败直接卡死
服务注册到 Consul/Nacos 总失败?检查这三处硬编码
注册失败日志看着像网络问题,实际多是配置细节错位。尤其是 Docker 环境下,localhost 在容器里根本解析不到宿主机。
- Nacos 地址必须带
/nacos后缀:http://127.0.0.1:8848/nacos,写成http://127.0.0.1:8848就 404 - Nacos 默认开启鉴权,
nacos.NewDefaultNacosConfig()不带账号密码 → 403 拒绝注册 - Docker 内连接 Consul 别写
http://localhost:8500,换成宿主机 IP 或host.docker.internal - 服务名只允许小写字母、数字、短横线;含下划线(如
user_rpc)会被拒绝
日志一查就懵?结构化 + traceID 是底线
用 log.Printf 打日志,出问题只能靠 grep 猜,上下游链路完全断裂。真正可用的日志必须字段统一、可过滤、可关联。
- 弃用标准库
log,选zerolog或zap:原生支持字段、level、采样,性能差一个数量级 - HTTP 入口统一从
X-Request-ID或X-B3-TraceId提取 traceID,注入context.Context并透传到底层 - 日志字段命名强制一致:
service、method、status_code、duration_ms,别混用resp、ret、result - 健康检查端点
/health必须返回严格200(健康)或503(不健康),Kubernetes 的livenessProbe全靠这个判断是否重启
最常被跳过的其实是服务启动时的可观测性埋点:没 /metrics、没结构化日志、没 trace ID 透传,等于把系统扔进黑盒。等报障再补,连哪个服务挂了都得靠 curl 猜。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!










