Golang如何做API网关_Golang API网关教程【必看】
使用 httputil.NewSingleHostReverseProxy 必须自定义 Director:重写 req.URL.Scheme/Host/Path,透传 X-Forwarded-For,删除 hop-by-hop header,搭配 gorilla/mux 或 chi 路由,调优 Transport,并严格控制中间件顺序与日志错误处理。用 httputil.NewSingleHostReverseProxy 做转发,但不重写 Director 就等于没做它默认只改 req.URL.Host,其他一概不动——req.URL.Path 还是原始路径,req.Host 还是网关自己的 Host,Authorization 和 X-Forwarded-For 通通不透传。后端服务收不到完整路径、拿不到真实 IP、甚至因 Host 不匹配拒绝请求,全是这个原因。必须显式设置 req.URL.Scheme 和 req.URL.Host,否则可能走 HTTPS 却连 HTTP 后端req.URL.Path 要用 strings.TrimPrefix(req.URL.Path, "/api/v1") 截掉网关层前缀,再交给后端;别直接赋 req.URL.EscapedPath(),否则带前缀的路径全发过去手动补 req.Header.Set("X-Forwarded-For", clientIP(req)),clientIP 要从 X-Real-IP 或 X-Forwarded-For 最左非私有 IP 取,不能只信 RemoteAddr删掉 hop-by-hop header:req.Header.Del("Connection")、req.Header.Del("Keep-Alive")、req.Header.Del("Proxy-Authenticate")路由分发别用 http.ServeMux,选 gorilla/mux 或 chi 不是图方便,是避坑http.ServeMux 遇到 /user/ → user-srv 这种转发,会自动裁剪前缀,但下游服务如果依赖完整路径(比如生成重定向 URL),就崩了;它也不支持路径参数、方法限定、子路由隔离,所有逻辑最后都挤进 if 判断里,两周后没人敢动。gorilla/mux 的 r.PathPrefix("/users").Handler(proxy) + proxy.Director 显式控制路径拼接,比硬编码 http.HandleFunc 更可控chi 的 router.Mount("/v1/users", userRouter) 会自动剥离前缀,userRouter 里的 Director 只需处理 /users/{id} 段,不用再切一次 /v1所有路由最后统一接 http.HandlerFunc(proxyHandler),转发逻辑收口,避免每个 handler 重复写 httputil 初始化路径变量务必加正则约束,比如 {id:[0-9]+},防正则回溯炸 CPUTransport 不调优,网关就是故障放大器默认 http.DefaultTransport 对微服务场景几乎无效:DNS 缓存永久生效、空闲连接不释放、整请求超时卡死在 30 秒、大文件上传直接 OOM——不是性能差,是根本不可控。Transport.DialContext 设 Timeout: 5 * time.Second,建连失败快抛,别等 30 秒IdleConnTimeout: 30 * time.Second,和后端 keep-alive timeout 对齐,避免僵死连接占满 fdMaxIdleConnsPerHost: 100,防止并发高时耗尽文件描述符别在 Transport 里塞重试逻辑,用中间件单独做:只对 502/503/504 和 net.ErrClosed、context.DeadlineExceeded 重试一次,且带 jitter中间件链顺序错了,鉴权就白加把鉴权中间件放在路由匹配之前,所有请求(包括 /healthz、/metrics)都得解析 JWT,CPU 白烧;放错位置还容易漏日志、跳过限流,或者 panic 后整个网关挂掉。 文心快码 文心快码(Comate)是百度推出的一款AI辅助编程工具
更多推荐
所有评论(0)