用Docker部署Golang微服务API网关,核心是轻量构建、网络隔离、配置外置与插件可插拔;推荐Gin自研或APISIX/Kong成熟方案,需多阶段构建、注册中心联动、定制Transport、内置安全与可观测性。

用Docker部署Golang微服务API网关,核心是“轻量构建 + 网络隔离 + 配置外置 + 插件可插拔”。不靠堆配置,而靠结构清晰、启动可控、故障不扩散。
选择合适的网关框架并精简构建
推荐用 Gin 搭建自研网关,或直接选用 APISIX/Kong 这类成熟网关。若选自研:
- 用多阶段 Dockerfile:第一阶段用 golang:1.21 编译,第二阶段用 alpine:latest 运行,镜像体积可压到 15MB 以内
- 编译时加 CGO_ENABLED=0 GOOS=linux GOARCH=amd64,确保二进制无动态依赖
- 禁用调试模式:GIN_MODE=release 必须设在容器环境变量中,避免 panic 泄露堆栈
容器网络与服务发现联动
网关不能只做反向代理,还要能动态找后端服务。Docker 原生网络不够用,需结合注册中心:
- 启动 etcd 或 consul 容器(如 docker run -d --name etcd -p 2379:2379 quay.io/coreos/etcd),供网关拉取服务地址
- 网关启动时通过环境变量注入注册中心地址:ETCD_ADDR=etcd:2379,并在代码中用 go-micro/registry/etcd 初始化
- Docker 网络统一用自定义 bridge(docker network create gateway-net),让网关、etcd、后端服务在同一网络互通
转发层必须定制 Transport,不能用默认
网关转发失败,八成出在 http.Transport 配置上。默认值会让连接卡死、超时误判、重试失控:
立即学习“go语言免费学习笔记(深入)”;
- Timeout 设为 6 秒(略高于下游 P99 延迟),太短导致正常请求被丢弃
- IdleConnTimeout 设为 30 秒,与主流后端(如 Gin、Spring Boot)的 keep-alive timeout 对齐
- MaxIdleConnsPerHost 至少设为 100,防止高并发下文件描述符耗尽
- 重试逻辑单独写中间件:仅对 502/503/504 + net.ErrClosed + context.DeadlineExceeded 重试 1 次,并加 jitter 避免雪崩
安全与可观测性从容器启动就内置
别等上线再补日志和监控,Docker 启动时就要埋点到位:
- JWT 验证失败常见原因是服务器时间不同步——启动容器前加 ntpdate -s time.windows.com,并在 JWT 中间件里用 jwt.WithValidator 容忍 ±1.5 秒偏差
- 所有日志输出到 stdout/stderr,由 Docker 日志驱动统一收集(如 json-file 或 fluentd)
- 暴露 /metrics 接口,集成 Prometheus:在容器启动命令中加 -e METRICS_ADDR=:9090,并挂载 prometheus.yml 配置
- 链路追踪用 Jaeger:通过环境变量 JAEGER_ENDPOINT=http://jaeger:14268/api/traces 直连



















