记一次请求接口出现400响应码的诡异错误实录

前言

最近业务碰到了一个诡异的400接口请求异常,部门用户通过浏览器访问会出现400响应码错误,部分用户又能正常访问。该接口用postman请求访问,都能正常返回数据。后端写客户端请求该接口,也都能返回正常的数据。本文就来记录一下这次问题

整体简化版请求链路

如图

问题排查过程

因为不管是用postman或者是后端自己写客户端请求,都能返回正常的数据。就说明我们请求的参数是没啥问题,问题可能是出现在请求头上,我们就觉得是不是nginx做了啥限制,于是 官网溜一圈,发现如图的参数

它的中文大意是通常客户端请求缓存的大小1K就够了,但是如果请求包含长cookie或者wap客户端,1k这个值可能就不大够,因此我们适当把该大小调高验证,发现没效果。于是我们把目光转向,client_header_buffer_size下方的large_client_header_buffers

该参数的大体作用:设置用于读取大型客户端请求标头的缓冲区的最大数量和大小。请求行如果超过一个缓冲区的大小,就会向客户端返回414(请求URI太大)错误。请求头字段也不能超过一个缓冲区的大小,否则会向客户端返回400(错误请求)错误。缓冲区仅按需分配。默认情况下,缓冲区大小等于8K字节。如果在请求处理结束后,连接转换为保持活动状态,则释放这些缓冲区。

看到这里我们似乎看到曙光,因此我们果断把该参数加上,并调高相应的配置值,本以为可以高枕无忧,结果配上去,那偌大的400错误,感觉就是在嘲讽我们的天真。

思路似乎断了,就问了一下chatGPT,看它有没有什么想法,可能是我提示不够精确,在它一本正经的胡说八道后,我放弃继续追问。于是还是走回传统的提问方式,去搜索引擎排查一番,然后查到这篇文章 www.likecs.com/ask-3802541...

这篇文章告诉我们当我们做了刚才配置后,还会出现400,此时跟我们的nginx大概没啥关系了,应该是跟后端有关系,他建议是如果是springboot项目,通过在项目中适当调高如下的值

yaml 复制代码
server:
  max-http-header-size:

于是我们死马当活马医,神奇的事发生了,没有再出现400的情况

问题原因梳理

出现请求400的原因,确实是请求头过大的原因,但为什么通过postman或者后端请求就不会有问题,而通过浏览器访问就会有问题,原因就是我们在处理跨域的时候,请求头加了一堆乱七八糟的东西,比如

xml 复制代码
        add_header 'Access-Control-Allow-Headers' 'x-app-id,x-tenant-id,x-user-id,Authorization,Accept,Origin,Keep-Alive,User-Agent,access-control-allow-origin,If-Modified-Since,Cache-Control,Content-Type,Range,systemId,Cookie。。。';

其次为什么会出现部分用户访问出现400,部分用户又不会,就是因为我们请求时,请求头会携带用户jwt token,该token的payload存放一堆跟用户相关的东西,比如权限id列表啥的,这样就导致有些用户的token的长度是比较大

总结

此次400响应码错误的问题,除了技术层面上,还有一些是规范上的,比如请求头加了了一堆无用的参数,其次为了方便,在token上搞了一堆业务数据,有些bug真的是无意识产生的,轻描淡写的一篇文章,可知道当时排查了2,3天,希望这篇文章能给其他小伙伴带来一些帮助或者排查思路吧

附录

nginx-ingress配置header头缓冲大小

yaml 复制代码
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/server-snippet: |-
      underscores_in_headers on;
      large_client_header_buffers 4 1M;
      client_header_buffer_size 16K;
相关推荐
述雾学java11 分钟前
Spring Boot是什么?MybatisPlus常用注解,LambdaQueryWrapper常用方法
java·spring boot·后端
吾零鬼泣1 小时前
腾讯音乐一面
spring boot·java-rocketmq·java-zookeeper
程序员buddha2 小时前
SpringBoot多环境配置文件切换
java·spring boot·后端
Java小白笔记2 小时前
IDEA中创建SpringBoot项目没有Java8
java·spring boot·intellij-idea
twj_one3 小时前
SpringBoot+ELK 搭建日志监控平台
spring boot·后端·elk
咖啡啡不加糖3 小时前
Sentinel原理与SpringBoot整合实战
spring boot·后端·sentinel
悟能不能悟4 小时前
Spring Boot中如何对密码等敏感信息进行脱敏处理
spring boot·后端·python
caihuayuan55 小时前
Vue3 Composition API: 企业级应用最佳实践方案
java·大数据·spring boot·后端·课程设计
只在空想家5 小时前
SpringBoot JAR 启动原理
java·spring boot·后端·jar
zeijiershuai6 小时前
SpringBoot项目配置文件、yml配置文件
java·spring boot·yml