客戶端上傳文件發生Connection reset by peer: socket write error問題排查

1.問題描述

研發在測試環境進行測試,通過內網上傳文件能正常收到nginx返回的錯誤信息,nginx做了30MB大小的上傳限制

{
    "return_code": 20010,
    "returnDesc": "Request body too large. It should not exceed [30 MB]"
}

通過走公網域名訪問應用程序就會報錯:

java.net.SocketException: Connection reset by peer: socket write error

2.問題排查

首先在客戶端抓包發現服務器在tcp連接中返回了RST包

由於nginx服務器做了上傳文件大小限制,那麼推測上傳文件太大超過了nginx的限制,於是nginx返回了文件太大的報錯,但此時應用程序仍然在發送數據流,因此nginx發現自己的響應沒有得到回饋,於是返回了RST包。如果此時客戶端正在往Socket套接字的輸入流中寫數據則會提示“Connection reset by peer”。

那爲什麼內網測試能收到正常返回的數據呢?收到正常返回數據說明client正常完成了一次請求,由於內網速度遠遠大於外網速度,文件又不是足夠的大,因此client在發送完數據流後正常響應了nginx的response。

3.一波三折

又有同事反饋說,通過postman以同樣的外網環境調用接口上傳文件時,postman能正常接收到返回的數據

同樣的環境,爲啥客戶端去訪問卻報錯,postman能正常接收到數據呢,難道postman有什麼異常處理機制?抓包發現通過postman去調用接口的時候鏈接並沒有被RST,而是正常關閉的,並且並沒有發生文件的上傳

4.問題解決

在網上查詢了半天,發現http協議中有這麼一個header:Expect:100-continue:

嘗試在代碼中加入這個header,問題得以解決:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章