背景说明
内部使用的一个系统,应用有许多
请求整体流程:
前端-->nginx-->spring cloud gateway-->应用A
前端-->nginx-->spring cloud gateway-->应用B
前端-->nginx-->spring cloud gateway-->应用C
...
前端-->nginx-->spring cloud gateway-->应用N
许多用户访问接口都正常响应,但是有一个用户异常,请求应用A一直不成功,请求其它应用是成功的,异常请求是GET,且有查询中文参数,查看日志 发现,这个异常用户的请求在nginx日志一直报400 435,而且是nginx有日志,spring cloud gateway 也有日志,但是应用无任何日志,看不到异常用户的请求,而对于其他正常用户所有链路都可以看到请求的日志,而且这个用户在别的终端,pc打开应用都是这个400 435报错,另外,这个问题用户请求别的应用都是正常
问题排查
查询了一下nginx400的原因,基本都是说请求头过大,但是前端大佬说肯定不是这个,也没深究
接下来就是用curl 模拟异常用户去请求,无论从链路上哪个节点请求,请求都是成功的,而且都有日志
奇怪
再然后又使用postman模拟用户请求,无论从链路上哪个节点请求,请求都是成功的,而且都有日志
奇怪
本地搭建了环境,和生产完全一致,本地排查
查询了两天,也查询了nginx日志,nginx和网关对header的限制相关信息
查不出来什么问题,也没有复现出用户出现的问题,但是这个问题用户只要访问应用A就会看到报错400 435,一开始不知道435是啥意思?查了一下就是响应长度,400是状态码,刚开始一直以为是用户请求参数问题,但是从网关看,这个异常用户的参数和正常用户没有任何差别,一直也怀疑是请求头过大,但不知道是谁限制了请求头,nginx?网关?还是应用?
问题解决
第三天,搞了两天,头大,没思路,第三天一切推到重来,复盘,从零开始查,我想,那会不会就是请求头过大呢?
因为前两天对nginx网关等对请求头处理也了解一些了,应用的日志也加上了请求头信息输出,那就开始模拟请求头过大吧
一模拟,还真出现了,但是这个是谁限制的,nginx?改了nginx header的配置,增大了一百倍,测试header绝对超不了,还是报错400 435,那就不是nginx的限制
那就可能是网关或者应用的限制,因为网关日志正常,那就不是网关的限制,应该是应用的限制
这里也很奇怪?既然用户请求头超限,网关为啥不报错?这个后面解释
改了应用对header的限制,果然一切正常,有点激动
但是,header过大异常的时候本地应用A是有一个错误日志的,但是查应用A生产日志没有相关报错,而且这个报错,只有请求第一次进来会报错,只要应用不重启,后续header过大导致异常并不会有错误日志
所以,不能百分百确认生产也是这个问题
但是目前也查不到别的解决方案,基本已经快崩溃了,只能先验证一下
验证前想,会不会是ngixn对这个用户的header做了缓存(瞎猜),先重启nginx,问题用户请求应用A还是异常400 435
那就改应用对header限制,重启应用A,让问题用户请求应用A,问题解决
经过仔细对比,是网关给往header添加了用户信息,这个问题用户的信息比别人多,正好header超限了
那就修改header配置(100k)
server:
max-http-header-size: 102400
至此,问题解决
但是还有一些问题需要排查,为啥别的应用没问题