
事件回溯
1.nginx默认配置upstream时,会有失败检测,超过失败次数,则会在一定时间内不进行转发
2.参考我们线上配置为30秒内1次失败不再对该服务提供者进行转发
upstream preview {
server s1:20000 weight=2 fail_timeout=30s max_fails=1;
server s2:20000 weight=2 fail_timeout=30s max_fails=1;
server s3:20000 weight=1 fail_timeout=30s max_fails=1;
}
3.基于我们的配置,还是会有一次失败会透露给用户,因此再次基础上增加了proxy_nexy_upstream
location / {
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-Proto https;
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
proxy_pass http://preview;
}
4.结果我们还是收到了用户反馈的出现502的情况
5.基于反馈问题,我们拉取了nginx的日志,拉取日志的过程也出现了两次错误
# 错误的日期,错误的状态码
cat /opt/log/preview_access.log|grep 07/Apr/2020:10|grep "/dcs.web"|awk '{if($9=502) print $0}'|grep -v "/dcs.web/onlinefile"
# 错误的状态码复写
cat /opt/log/preview_access.log|grep 08/Jul/2020:|grep "/dcs.web"|awk '{if($9=502) print $0}'
# 正确的日志命令
cat /opt/log/preview_access.log|grep 08/Jul/2020:10 | grep "/dcs.web"|awk '{if($9==502) print $0}'
6.跟开发确认,哪些是对我们的请求,得到的回复是[GET /dcs.web/$id]这样的数据格式,对比拿到的错误日志,发现无论哪台服务器均会收到502的错误
7.再次跟前端业务要求反馈用户请求数据,拿到数据对比也没有找到具体数据
8.中午之后,善军重新查找日志,发现所有的nginx的502总共只有5条数据,多次对比拉取日志命令发现,获取数据时,命令错误,误将http状态码重新赋值为502
9.再次重新拉取请求日志,以及对比错误日志,发现502日志均为POST请求,错误日志中出现的get请求均正常返回200给到客户端
10.再次跟开发确认,到底哪个是我们提供的接口,需要做数据对比检查的,反馈两个接口均需要。
11.此时,已经真相大白了,出错的POST请求响应502均为服务挂掉的ip,则可知服务挂掉时候的POST请求未重试转发,且已知proxy_next_upstream不会对非幂等请求进行转发
12.修改proxy_next_upstream配置,针对【/dcs.web/onlinefile】接口,增加【non_idempotent】配置
总结
1.确认受影响范围([GET /dcs.web/$id],[POST /dcs.web/onlinefile]),遗漏接口跟踪,导致忽略重点问题POST请求
2.日志抓取,一定要确认抓到到正确的日志,否则一切都是徒劳
3.一定要猜想之后,找到证据,证明猜想,才能定位正确问题,否则一切始终都是猜想
4.proxy_next_upstream的non_idempotent是否可以配置,要根据接口是否能够支持幂等重试来决定,不能全部配置