Go不内置负载均衡,需依赖外部组件或手动实现;其http.Server仅负责本机请求分发,真实LB需结合Consul/Etcd等注册中心与Nginx/Envoy等专用组件完成。

Go 本身不内置负载均衡,得靠外部组件或自己调度
Go 的 http.Server 是单进程多协程模型,能轻松扛住数千并发连接,但它只负责「本机内分发」——把请求交给 Handler,并不知道其他机器是否存在、健康与否。真正的负载均衡发生在服务之间,不是语言层面的事。所以别指望 net/http 自带轮询或一致性哈希。
用反向代理(httputil.NewSingleHostReverseProxy)做简易后端路由
适合开发联调或轻量级网关场景,但注意它默认不重试、不健康检查、不支持权重。你得手动封装逻辑:
- 用
sync.Map或atomic.Value缓存后端列表,避免每次请求都查配置 - 在
Director函数里改写req.URL,比如轮询选backends[i%len(backends)] - 捕获
RoundTrip错误,对超时或连接拒绝做简单降级(如返回 503 或 fallback 到备用地址) - 别直接用
http.DefaultTransport,要自定义Timeout和MaxIdleConnsPerHost,否则容易耗尽文件描述符
proxy := httputil.NewSingleHostReverseProxy(&url.URL{Scheme: "http", Host: "127.0.0.1:8081"})
proxy.Transport = &http.Transport{
DialContext: (&net.Dialer{
Timeout: 3 * time.Second,
KeepAlive: 30 * time.Second,
}).DialContext,
MaxIdleConns: 100,
MaxIdleConnsPerHost: 100,
}生产环境必须用专用 LB 组件,Go 只负责注册与心跳
真实高并发下,靠 Go 自己做负载均衡等于重复造轮子。主流做法是:Go 服务启动时向 Consul / Etcd / Nacos 注册自身地址 + 健康端点;由 Nginx / Envoy / Traefik 或云厂商 SLB 来拉取节点、做健康探测、执行加权轮询或 least_conn。Go 这边只需:
- 暴露
/healthzHTTP 接口,返回 200 即视为存活(别做 DB 检查,太重) - 注册时带 TTL,定期刷新(如每 15s PUT 一次 Etcd key)
- 监听注销信号(
os.Interrupt),退出前主动删注册项 - 避免在
init()里做服务发现初始化,会阻塞main()启动
别忽略连接复用和上下文传递的细节
高并发下,每个请求新建 TCP 连接或 HTTP client 是性能杀手。常见错误包括:
iWebShop基于iWebSI框架开发,在获得iWebSI技术平台库支持的条件下,iWebShop可以轻松满足用户量级百万至千万级的大型电子商务网站的性能要求。站点的集群与分布式技术(分布式计算与存储/高可用性/负载均衡)被屏蔽在SI 平台之内,基于iWebShop并且按照SI平台库扩展规范开发的新增功能模块,也将同时获得这种超级计算与处理的能力。作为开源的LAMP电子商务系统,iWebShop
立即学习“go语言免费学习笔记(深入)”;
- 在 handler 里 new
http.Client,导致大量 TIME_WAIT 和 DNS 查询 - 没传
context.WithTimeout给下游调用,一个慢接口拖垮整条链路 - 用
http.DefaultClient但没调Transport超时参数,底层 TCP 握手失败可能卡 3 分钟 - 跨 goroutine 传递
context.Context时用了context.Background()替代 handler 的req.Context(),导致无法取消
真正难的不是写个轮询函数,而是让每个环节都可观察、可中断、可退化——比如 LB 失效时自动切到本地兜底节点,或者健康检查连续失败三次才下线,这些逻辑藏在细节里,不在框架里。









