选nginx,因其支持http/https/grpc七层调度、可透传header、具备丰富健康检查能力;lvs仅限四层tcp/udp转发,无法处理应用层逻辑。

Go 微服务本身不提供负载均衡能力,必须靠外部组件实现;Nginx 适合 HTTP/HTTPS/gRPC 流量调度,LVS 只能做四层转发,不能透传 header 或做健康检查——选哪个,取决于你跑的是什么协议、要不要真实 IP、有没有 TLS 卸载需求。
Nginx 配置 HTTP/HTTPS 负载均衡的关键点
直接写 upstream 就算“配了”,但线上出问题基本都卡在这几处:
-
max_fails=1 fail_timeout=10s是默认陷阱:Go 进程一次 panic 就退出,Nginx 10 秒内探活失败 1 次就剔除节点,导致服务雪崩;应改为max_fails=3 fail_timeout=30s,并确保 Go 进程由 systemd 管理、配置Restart=always - 漏掉
proxy_next_upstream error timeout http_500 http_502 http_503 http_504:某个实例 GC STW 或慢 SQL 卡住时,Nginx 不会自动切到其他节点,用户直接看到超时或 502 - 用了
ip_hash却没加proxy_set_header X-Real-IP $remote_addr:后端 Go 用c.ClientIP()拿到的是 Nginx 本机地址,不是用户真实 IP - HTTP/2 或 gRPC 必须显式开启:
listen 8000 http2;和grpc_pass grpc://upstream_name;,否则降级为 HTTP/1.1,gRPC 流会断
Nginx 配置 gRPC 负载均衡的硬性前提
Nginx 1.13.10+ 才真正支持 gRPC proxy,低于这个版本会静默降级、连接复用失效、metadata 丢失:
在 Golang 中使用 samber/hot 进行内存缓存,支持 LRU、LFU、TinyLFU、W‑TinyLFU、S3FIFO、ARC、TwoQueue、SIEVE、FIFO 等淘汰算法,提供 TTL、缓存加载器及分片功能。
- upstream 中每个
server必须监听 HTTP/2(即 Go 服务启动时用http.ListenAndServeTLS或启用 h2c) -
location /下必须用grpc_pass grpc://upstream_name;,不能用proxy_pass -
http2_max_requests默认是 1000,高并发下容易触发连接重置,建议设为10000或更高 - 必须配
error_page 502 = /error502grpc;+ 内部 location 返回标准 gRPC 错误码(grpc-status: 14),否则客户端收不到可识别的错误
LVS 仅适用于纯 TCP 层转发场景
LVS(如 DR 模式)只工作在 OSI 四层,它不知道 HTTP header、不解析 URL、不校验 TLS 证书、也不感知 Go 服务是否真活着:
- 无法传递
X-Forwarded-For或X-Real-IP,后端 Go 只能拿到 LVS VIP 的源地址 - 健康检查只能靠 TCP connect,不能调
/healthz接口;Go 实例进程挂了但端口还通,LVS 仍会转发流量过去 - 不支持 HTTP/2 或 gRPC;如果 Go 服务启用了 TLS,LVS 无法卸载,客户端必须直连证书,无法统一管理
- 适合场景极少:比如内部服务间裸 TCP 通信、或 Go 做长连接网关且前端已有 TLS 终结(如 CDN 已卸载 HTTPS)
Go 端口管理别写死,尤其在容器/K8s 环境
硬编码 :8080 在本地开发可以,一上生产就是定时炸弹:
- 本地调试:用
http.ListenAndServe(":0", nil)让系统分配空闲端口,启动后打印l.Addr().Port,再填进 Nginx upstream - Docker:Dockerfile 别写
EXPOSE 8080,运行时用-p 8080让宿主机随机映射,查实际端口用docker port <container></container> - Kubernetes:Nginx Ingress Controller 自动同步 Service endpoints,upstream 直接写 DNS 名如
myapp.default.svc.cluster.local:8080,完全不用手维护 IP 列表
最常被忽略的是健康检查闭环:Nginx 的 health_check 模块或第三方模块(如 nginx-plus)才能真正探测 /healthz;如果只靠 TCP 探活,Go 进程卡在 GC 或锁竞争时,LVS 和基础版 Nginx 都会把它当成“健康”节点继续导流。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!










