本文目录导读:

网关转发异常是微服务架构中比较棘手的故障之一,因为涉及客户端、DNS、负载均衡、网关本身以及后端服务等多个环节。
以下是针对“网关转发异常”的系统化排查定位思路,分为快速预检、链路分步排查和常见原因分类三部分。
第一阶段:快速预检(3分钟定位显性问题)
在深入分析之前,先检查几个最容易忽略的环节:
- 网关是否存活?
ping <网关IP>检查网络通断。curl -I http://<网关>/health(假设有健康检查端点)检查进程是否正常。
- 配置是否已生效?
- 最近是否修改过路由规则、限流配置、上游服务地址?检查网关的控制台或配置文件,确认修改已保存并重新加载。
- 检查配置中心(如 Nacos、Apollo)中的配置是否与网关实例一致。
- 基础资源是否充足?
top或htop查看 CPU / 内存,如果CPU打满,可能是突发流量或被攻击。netstat -anp | grep <网关端口>或ss -lntp查看端口监听状态,端口没起来是致命问题。df -h查看磁盘是否写满(如日志文件过大)。
- 客户端是否能解析域名?
nslookup <网关域名>或dig <网关域名>,如果解析失败或解析到了错误的 IP,问题可能在 DNS。
第二阶段:分步排查(由近及远,逐层剥离)
如果基础检查没问题,按照流量经过网关的顺序进行排查:
步骤 1:检查客户端请求是否到达网关(入口)
- 抓包确认: 在网关所在的服务器执行
tcpdump -i any port <网关端口> -nn -c 100,观察是否能抓到客户端的 TCP 握手(SYN)包。 - 可能性:
- 没抓到SYN包: 网络不通、防火墙拦截、客户端发错了IP/端口,检查防火墙规则(iptables / nftables)。
- 抓到SYN但没建立连接: 网关的TCP队列满了(
net.core.somaxconn过小),或连接池耗尽。
步骤 2:检查网关内部处理(核心转发表)
确认请求到达后,网关是否正确路由?
- 查看网关日志(最重要): 很多网关(如 Nginx、Kong、Zuul、Spring Cloud Gateway)会记录请求的
upstream_addr(上游地址)。- 日志显示
upstream_addr: <目标IP>正确,说明路由匹配成功,转问题到步骤3。 - 日志显示
upstream_addr: -、no route、404 Not Found,说明路由规则没匹配上。- 排查点: 检查路由表里路径(Path)、请求方法(Method)、Header 是否写错(如把
/api/user写成了api/user),注意正则表达式冲突。
- 排查点: 检查路由表里路径(Path)、请求方法(Method)、Header 是否写错(如把
- 日志显示
- 检查访问控制:
- 检查是否触发了网关级的 IP 黑名单、UA 封锁、限流规则(通常会返回
429 Too Many Requests或403 Forbidden)。
- 检查是否触发了网关级的 IP 黑名单、UA 封锁、限流规则(通常会返回
步骤 3:检查网关到后端服务的连接(出站)
这是最常见的故障点,假设路由正确,检查网关是否成功连接上后端服务。
- 从网关 ping/curl 后端服务:
curl -v --connect-timeout 3 http://<后端服务IP>:<端口>/health- 超时: 检查网络:是否跨了防火墙?是否在同一个 VPC 或 Kubernetes 集群?K8s 中,pod 重启后 IP 变了,而网关的 Upstream 配置未更新。
- 连接拒绝: 后端进程挂了 / 端口没监听。
- 检查服务发现(如果用了注册中心):
- 网关是从注册中心(如 Nacos、Eureka、Consul)动态获取后端地址的,检查服务列表是否为空或摘除了。
- 排查点:注册中心与网关的网络连通性,服务中心的健康检查是否被误判。
- 检查负载均衡策略:
如果是轮询,轮到了某个异常节点,可以尝试切换负载均衡策略(如 IP Hash)看是否会解决。
步骤 4:检查后端服务响应(出口)
连接成功,但返回了异常状态码。
- 查看网关 Upstream Status:
upstream_status记录了后端返回的状态码。- 502 Bad Gateway: 后端无响应或返回了格式错误的数据,常见原因:后端重启、慢请求导致网关超时、后端返回的响应体过大超过
proxy_buffer_size。 - 503 Service Unavailable: 网关的健康检查失败,自动摘除了节点,或后端连接池耗尽。
- 504 Gateway Timeout: USB 经典问题,网关等待后端响应的超时时间(如
proxy_read_timeout)设置太短,后端处理慢。 - 200/201 但业务异常: 网关转发正常,问题在后端业务逻辑本身。
步骤 5:检查响应返回给客户端
- 检查报文截断: 客户端收到部分结果(Content-Length 与实际不符),通常是 Gzip 压缩、Chunked 传输编码或 Nginx 缓冲区配置问题(如
proxy_buffering关闭导致数据流中断)。 - 检查响应头: 是否在网关层被修改(如 CORS 头冲突、Cookie Domain/Path 被覆盖)。
第三阶段:常见原因归纳表
| 现象 | 大概率原因 | 排查命令 / 工具 |
|---|---|---|
| 全量请求 502/504 | 后端服务整体宕机。 网关与后端网络断开(如K8s Service 后端 Pod IP 变化)。 注册中心中服务列表被清空。 |
curl <backend>、kubectl get pods、检查注册中心控制台 |
| 随机请求 502/504 | 负载均衡轮询到健康检查失败的节点。 后端某个节点启动慢导致超时。 连接池泄漏。 |
查看日志中的 upstream_addr,观察是否集中在某台机器 |
| 大部分请求 404 | 网关路由规则写错(路径大小写、缺斜杠)。 网关配置未热更新生效。 |
对比客户端请求 URL 与路由表规则 |
| 请求超时极慢 | DNS 解析卡顿(网关做了 DNS 缓存但源端很慢)。 SSL/TLS 握手慢(证书链太长)。 后端服务处理慢。 |
time curl -v <url>、ngx_http_log_module 记录各阶段耗时 |
| 跨域问题(CORS) | 网关未配置 Access-Control-Allow-Origin。 或配置与后端服务有冲突(重复 Header)。 |
浏览器 F12 查看网络请求的 Response Header |
| 连接数不够 | 网关的 worker_connections 达到上限。后端服务的连接数达到上限(如 Tomcat max-connections)。 |
ss -s、lsof \| wc -l、后端应用的连接池监控 |
第四阶段:进阶工具
如果上述步骤未能解决,可以使用以下手段进行深度观察:
- 全链路追踪:
- 若接入了 Jaeger / Zipkin / SkyWalking,查看 Trace ID 在不同服务间的耗时。
- 可以精确看到:是网络延迟(送出去很久才收到 Response),还是服务处理慢。
- 抓包分析:
- 在网关服务器使用
tcpdump -w dump.pcap抓包。 - 用 Wireshark 打开,过滤
http.response_in。 - 重点看:三次握手之后,网关发送 HTTP 请求到后端,多久才收到第一个数据包,如果中间有超过几十毫秒的空白,就是网络问题。
- 在网关服务器使用
- 压测重现:
- 如果故障在低负载时才出现,考虑是否和线程泄漏、DNS 缓存变冷有关。
最经典的排查路径
遇到异常 -> 看网关日志 -> 找到 upstream_addr -> 手动 curl 这个地址 -> curl 不通,看网络和端口;curl 通,比较日志中的 upstream_status 和实际请求的耗时。
绝大多数问题最终都归结为:“网关找不到服务了” 或者 “服务找到了,但响应太慢或超时了”。
标签: 故障排查
版权声明:除非特别标注,否则均为本站原创文章,转载时请以链接形式注明文章出处。