SpringBoot HTTP 400排查方式
目录
- 背景
- 问题分析
- 定位
- 解决方案
- 总结
背景
前段时间朋友咨询他们公司某个HTTP接口偶现400错误,有没有什么好的分析方法和解决方案,使用的是Spring Cloud体系。最近有时间总结下这个问题的处理过程。
为了分析问题,笔者使用 Spring Boot 3.0.2还原报错场景进行讲解。
问题分析
从朋友反馈的情况看,返回400状态错误码的接口并不是一直出错,出www.devze.com错的概率在5%左右,得出并不是系统的错误,从状态码400来看是调用方出错了,请求头或者请求参数错误。
从服务器上查tomcat的错误日志,找到类似下图的错误。
从错误日志看到,调用方的请求头个数超过了Tomcat默认设置的个数(100个)。
定位
根据以上分析,需要在服务器上抓包,看调用方到底使用了什么参数。
在服务器上使用 tcpdump工具抓包分析http请求具体信息来 定位问题。
因为不能从服务器上下载文件,使用如下命令查看http请求信息。
tcpdump -A -s0 port 8080
在服务器上查看到类似如下的http请求信息,通过Header信息发送是使用的某个链路追踪工具添加的链路调用请求信息,每经过一次调用就会添加一个同名的Header,调用链路多了的话就会导致Header个数超过Tomcat的默认值,从而导致Tomcat抛出400错误。
以下是使用Postman模拟超过100个Header的请求日志信息中的部分。
18:27:56.864393 IP 192.16javascript8.1.103.64156 > Fedora.webcache: Flags [.], seq 1:1461, ack 1, win 513, length 1460: HTTP: GET / HTTP/1.1 E....b@...S....g...d.....'......P....=..GET / HTTP/1.1 Header0: 0 Header1: 1 Header2: 2 Header3: 3 Header4: 4 ... Header95: 95 Header96: 96 Header97: 97 Header98: 98 Header99: 99 User-Agent: PostmanRuntime/7.29.2 Accept: */* Postman-Token: f
如果可以下载文件的话,使用下面的命令抓包,在开发机上使用wireshark工具分析http请求包信息是最好的。
sudo tcpdump port 8080 -w http.400.cap
解决方案js
找到问题原因之后,就好解决了。
解决方案有两种:
- 找链路追踪工具的团队解决Header的问题
- 设置Tomcat Header个数
由于不是本公司系统且需要及时解决该问题,没办法解决链路追踪工具的问题,给朋友推荐自定义配置的方式设置Tomcat最大Header数量,代码如下:
/** * 自定义Tomcat配置参数 */ @ConditionalOnProperty(value = {"server.tomcat.max-header-enab编程客栈le"}, havingValue = "true", matchIfMissing = false) public class TomcatConfigure { /** * 最大Header数量 */ @Value("${server.tomcat.max-header-count:100}") private int maxHeaderCount; @Bean public WebServerFactoryCustomizer<ConfigurableWebServerFactory> tomcatCustomizer() { return new WebServerFactoryCustomizer<ConfigurableWebServerFactory>() { @Override public void customize(ConfigurableWebServerFactory factory) { TomcatConnectorCustomizer customizer = new TomcatConnectorCustomizer() { @Override javascript public void customize(Connector connector) { Http11NioProtocol protocol = (Http11NioProtocol) connector.getProtocolHandler(); protocol.setMaxHeaderCount(maxHeaderCount); } }; ((TomcatServletWebServerFactory) factory).addConnectorCustomizers(customizer); } }; } }
在应用启动参数上加
**-Dserver.tomcat.max-header-enable=true -Dserver.tomcat.max-header-count=200**
重启服务后解决该问题。
总结
在这个故障排查过程中,需要对HTTP协议有较深的掌握,对HTTP状态、请求头等非常熟悉;熟练使用一些网络工具,如tcpdump、wireshark等。
在解决过程中需要开发人员熟练使用Spring Boot(有源码经验最好),这样可以对Spring Boot做扩展,给需要的组件做个性化定制开发。
以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程客栈(www.devze.com)。
精彩评论