排查 502 Bad Gateway 的常见思路

巴辉特 2024-04-24 00:08:08

浏览器侧看到请求超时,status code 502,即 bad gateway,可能的原因有哪些呢?本文从 SRE 视角给一些常见的排查思路。先上一张省流卡片,把核心思路罗列出来,大家可以保存这个卡片,真遇到故障时可以对照思路排查。

  • 使用 Chrome 开发者工具确认报错的接口,拿到基础信息
  • 修改 Chrome 生成的 cURL 命令直接请求后端,绕过 Nginx,快速确认是负载均衡的问题还是后端问题
  • 查看 Nginx 的 error.log,在 access log 中检索报错的接口
  • 如果是 Nginx 层面的问题,查看 Nginx 的配置文件,确认是否有超时配置
  • 如果是后端服务的问题,根据 response 做基本判断
    • Connection refused 大概率是后端服务没启动
    • Empty reply from server 大概率是后端服务在处理请求的时候 panic 了,或者被 OOM kill 了
    • 如果后端返回 502,说明后端至少没 crash,可以继续查看后端服务日志
  • dmesg –T |grep –i "out of memory" 确认是否是 OOM 问题

我录制了一个视频,来讲解整个排查的过程,大家可以通过 SRETalk 视频号查看。下面我们逐一展开这些思路。

使用 Chrome 开发者工具确认报错的接口

首先,我们需要确认报错的接口是哪个。打开 Chrome 开发者工具,切换到 Network 标签页,勾选 Preserve log 和 Disable cache,刷新页面,找到报错的接口,查看其请求和响应信息。

排查 502 Bad Gateway 的常见思路 - 图1

在报错的请求上面右键,可以拷贝 cURL 命令:

排查 502 Bad Gateway 的常见思路 - Chrome cURL

修改 Chrome 生成的 cURL 命令直接请求后端

这个方式可以绕过中间网络环节,快速确认是否是后端的问题。如果后端是正常的,那就是中间网络环节的问题,尤其是在一些复杂的网络环境下(比如你的服务前面可能还有其他的负载均衡、WAF 等),这个方法非常有效。

当然,Chrome 生成的 cURL 命令,需要做一些修改才能使用,核心改动就是 URL 中的目标地址,把它改成后端服务的地址,就可以直接测试后端,注意,尽量在 nginx 所在的机器上运行 cURL,模仿真实的网络链路。如果把目标地址改成 127.0.0.1,那就相当于直接请求 nginx,这样可以快速确认是否是 nginx 前面的某个环节的问题。

如果接口是 POST 或者 PUT 请求,生成的 cURL 命令中可能会有 --raw-data 参数,不同的 cURL 版本参数可能不同,如果 --raw-data 参数不支持,可以改成 --data 参数。

查看 Nginx 的日志

Nginx 的日志分为 error.log 和 access.log,error.log 一般记录了 Nginx 的错误信息,access.log 记录了 Nginx 的访问日志。这俩日志都要看,error.log 通常内容比较少,access.log 内容比较多,可以通过 grep 等命令筛选出报错的接口。

access log 中要记录 upstream status 和 nginx 直接返回给前端的 status,如果发现 access log 中缺少这些信息,那就要修改 Nginx 的 log_format,增加这些信息。

Nginx 层面也有超时控制,可以通过配置文件查看,比如 proxy_connect_timeout、proxy_read_timeout、proxy_send_timeout 等。

后端服务的问题

使用 curl 请求后端服务,根据 response 可以做一些基本判断,通常都会给 curl 命令添加 -v 参数,这样可以看到请求和响应的详细信息。

如果后端服务没启动,curl 会报 Connection refused 错误,如果后端服务在处理请求的时候 panic 了,或者被 OOM kill 了,curl 会报 Empty reply from server 错误。这些都是常见报错。

如果是 OOM 了,一般系统日志中能够看到,可以通过 dmesg –T |grep –i "out of memory" 或者 grep -i 'out of memory' /var/log/messages 来确认。

后端服务如果在容器里

如果后端服务是在容器里,可以通过 docker logs 命令查看容器日志。如果容器里的 1 号进程是 supervisord,问题就会更复杂,可能 supervisord 托管的进程挂了,但是 supervisord 本身没挂,这时候从外部来看,容器是正常的,但是容器里的服务是不正常的。需要进入容器里排查。

最后

对于一些常见的 Linux、SRE 知识,我录制了一些视频放到 SRETalk 视频号了,求个关注,等视频号粉丝数达到规定可以推流直播了,后面给大家直播讲解更多的 SRE 知识。

20240424100520

快猫星云 联系方式 快猫星云 联系方式
快猫星云 联系方式
快猫星云 联系方式
快猫星云 联系方式
快猫星云
OpenSource
开源版
Flashcat
Flashcat
FlashDuty
Flashduty