记录一次单点499保持故障!
首先nginx错误日志中在服务器推送高峰时都会存在499报错,但从499状态码的解释
上来看一直是由于客户端的主动断开导致服务端还未处理完成导致,故在这之前我对499
状态码没有进一步探索根源。
然而在一次日志排查中发现,在非高峰期间也会存在499超过告警阈值,而且时间次数
是不固定的。并且发现这个告警集中在一台api机器中,这与上述高峰时期499的告警明显
不同,如果是因为上面的原因那么为什么会只会出现在这台机器中呢?最后发现之前对于
499状态码的定义为客户端主动断开行为是错误的认知。
在这先对于499与504状态码做一个分析!
499:首先499其实并不是HTTP协议的标准状态码,499其实是nginx自定义的一个状
态码,对于解释通过查资料大致的意思是:在客户端请求的时候因为客户端的主动行为导致
结束请求,而此时客户端还未处理完这个请求,导致499报错,也就是说和服务端是没有关
系的。应该都是客户端的原因导致。
504:对于504的解释为upsteam处理时间过长,nginx等待upsteam处理的返回时间超
时了;所以无论是代码执行出错,还是服务出错,还是处理时间过长,如果是这类服务端的
问题应该返回的都是504并非499。
而站在这次出现的问题角度来说不应该是upsteam处理时间过长,应该返回504嘛,为
什么这台机器返回了499呢?(如果说是应为客户端主动断开那么应该是分散在各个应用服
务器上,并不应该是单点报错)
对于这次的报错,我也去查阅资料,查到的解决方案如下:
proxy_ignore_client_abort(代理忽略客户端终止)参数,该参数默认为off,将其设置为on 后,对于客户端主动断开请求的情况,nginx会ignore而以upstream实际返回的状态为准。但是有没有发现,设置这个参数处理能在nginx log中记录的状态码完全按照upsteam返回确定。但他并非表示是499以外的一些情况。所以对于目前这个场景,对于解决问题实际上是没有任何帮助的。
那么分析关键其实在与nginx对于upsteam的超时时间是否设置合理,分析到这里,那么赶紧去看nginx的配置文件。
发现这台机器的nginx配置文件确实是没有配置关于upsteam的超时时间的信息。
那么nginx中对于504判断的依据超时时间是多少呢?通过查资料发现,如果我们不去配置那么模式超时时间为60s。也就是说如果我们没有配置504的超时时间,按照默认的来,那么只有服务器在处理请求超过60s的情况下再回返回504的报错,然而对于客户端请求超时时间的配置则为15s(配置文件中已经修改,这15秒包括从请求到外网数据传输的时间),那么如果按这样的配置去走的话如果一个请求处理了15s那么就会直接断开连接并记录499,那么也就意味这这台机器这样配置永远都不会到达60s的阈值,那么他自然就不会判断为504。
那么我们这次的499是否出现以下情况呢:
- 用户在等待请求的页面等待虽然不超过15s但是因为处理的慢,用户等不及了直接关闭app来结束这次请求。
- 用户耐心等待了15s,但是因为超过了请求超时的15s的阈值,服务端主动结束了当前访问请求!
那么通过分析发现近期单台故障是由于响应缓慢所引起,既然是由于客户端的保持时间15s远远小于nginx的upsteam超时时间60s所引发,那么这应该是属于一个明显的配置不当,那么既然是配置不当,势必会出现下方的问题:
用户由于某些原因主动断开了请求与客户端超时时间15s混在了一起,导致无法区分,到底是客户端的原因还是服务端的原因导致!
那我们是否可以将客户端的超时时间调大到65s,或者是把upsteam的处理超时时间缩短到15s以内来解决这个问题呢?
首先调大客户端的处理时间显然是不合理的,如果一个服务15s还没有处理完成请求,那么这个服务百分之百是有问题的。
所以正确的做法应该是将upsteam的处理超时时间调整到15s以内。(一般来说服务端处理一个请求一旦超过1s就已经属于超长请求了,所以不但默认60s不行,就连我们所设置的客户端15s超时时间也不行。当然我们所设置的客户端超时时间15s也是考虑到客户端的一些网络因素,以及服务端的负载所设置,举个例子,你要同时给很多人分西瓜,而有一个人你把西瓜拿起来给他,但应为他调皮一直不从你的手里拿,那么多多少少也会影响你分西瓜的速度。)
所以经过多方面考虑,最终敲定一个upsteam的超时时间为5s 。(修改经验不足,以及服务端各个接口的耗时情况)
那么这样处理以及可以很大程度上解决上面的问题。
1.可以将客户端的种种原因导致超时499与服务端处理时长的504做到区分。
2.如果说nginx等待upsteam中的其中一台机器达到5s触发超时时,也会主动转交给另一个机器处理并且返回。这样的话在单一的upsteam因为负载过大的原因导致处理超时时,其他正常的upsteam可以作为返回兜底15s处理其超时请求。
总结:很多时候问题出现了,如果不去找到问题的真正原因,按照网络中的一些解决方法去处理,可能会是掩耳盗铃,导致问题实际没有解决,给往后的运维增加压力。如果在时间运行的情况下还需要多探索,多思考!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?