SpringBoot HTTP 400排查方式
背景
前段時間朋友咨詢他們公司某個HTTP接口偶現(xiàn)400錯誤,有沒有什么好的分析方法和解決方案,使用的是Spring Cloud體系。最近有時間總結下這個問題的處理過程。
為了分析問題,筆者使用 Spring Boot 3.0.2還原報錯場景進行講解。
問題分析
從朋友反饋的情況看,返回400狀態(tài)錯誤碼的接口并不是一直出錯,出錯的概率在5%左右,得出并不是系統(tǒng)的錯誤,從狀態(tài)碼400來看是調用方出錯了,請求頭或者請求參數(shù)錯誤。
從服務器上查tomcat的錯誤日志,找到類似下圖的錯誤。

從錯誤日志看到,調用方的請求頭個數(shù)超過了Tomcat默認設置的個數(shù)(100個)。
定位
根據(jù)以上分析,需要在服務器上抓包,看調用方到底使用了什么參數(shù)。
在服務器上使用 tcpdump工具抓包分析http請求具體信息來 定位問題。
因為不能從服務器上下載文件,使用如下命令查看http請求信息。
tcpdump -A -s0 port 8080
在服務器上查看到類似如下的http請求信息,通過Header信息發(fā)送是使用的某個鏈路追蹤工具添加的鏈路調用請求信息,每經過一次調用就會添加一個同名的Header,調用鏈路多了的話就會導致Header個數(shù)超過Tomcat的默認值,從而導致Tomcat拋出400錯誤。
以下是使用Postman模擬超過100個Header的請求日志信息中的部分。

18:27:56.864393 IP 192.168.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
如果可以下載文件的話,使用下面的命令抓包,在開發(fā)機上使用wireshark工具分析http請求包信息是最好的。
sudo tcpdump port 8080 -w http.400.cap

解決方案
找到問題原因之后,就好解決了。
解決方案有兩種:
- 找鏈路追蹤工具的團隊解決Header的問題
- 設置Tomcat Header個數(shù)
由于不是本公司系統(tǒng)且需要及時解決該問題,沒辦法解決鏈路追蹤工具的問題,給朋友推薦自定義配置的方式設置Tomcat最大Header數(shù)量,代碼如下:
/**
* 自定義Tomcat配置參數(shù)
*/
@ConditionalOnProperty(value = {"server.tomcat.max-header-enable"}, havingValue = "true", matchIfMissing = false)
public class TomcatConfigure {
/**
* 最大Header數(shù)量
*/
@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
public void customize(Connector connector) {
Http11NioProtocol protocol = (Http11NioProtocol) connector.getProtocolHandler();
protocol.setMaxHeaderCount(maxHeaderCount);
}
};
((TomcatServletWebServerFactory) factory).addConnectorCustomizers(customizer);
}
};
}
}
在應用啟動參數(shù)上加
**-Dserver.tomcat.max-header-enable=true -Dserver.tomcat.max-header-count=200**
重啟服務后解決該問題。
總結
在這個故障排查過程中,需要對HTTP協(xié)議有較深的掌握,對HTTP狀態(tài)、請求頭等非常熟悉;熟練使用一些網(wǎng)絡工具,如tcpdump、wireshark等。
在解決過程中需要開發(fā)人員熟練使用Spring Boot(有源碼經驗最好),這樣可以對Spring Boot做擴展,給需要的組件做個性化定制開發(fā)。
以上為個人經驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關文章
java中throws與try...catch的區(qū)別點
在本篇文章里小編給大家整理了一篇關于java中throws與try...catch的區(qū)別點的內容,需要的朋友們跟著學習下。2020-02-02
springboot+mybatis+redis 二級緩存問題實例詳解
Mybatis默認沒有開啟二級緩存,需要在全局配置(mybatis-config.xml)中開啟二級緩存。本文講述的是使用Redis作為緩存,與springboot、mybatis進行集成的方法。需要的朋友參考下吧2017-12-12
解決springboot運行出現(xiàn)錯誤:找不到或無法加載主類com.xxxx.xxxx.Application問題
文章介紹了在服務器上運行一個未使用的Java項目時遇到的“找不到或無法加載主類”錯誤,并提供了兩種解決方法:通過Maven install或build …、Goals輸入install并跳過測試來重新構建項目2024-11-11
druid執(zhí)行SQL出現(xiàn)錯誤但不影響返回結果的問題及解決
這篇文章主要介紹了druid執(zhí)行SQL出現(xiàn)錯誤但不影響返回結果的問題及解決方案,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2023-12-12
springboot使用redisTemplate操作lua腳本
本文主要介紹了springboot使用redisTemplate操作lua腳本,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2022-08-08

