跳到主要內容

收到未預期的重複 HTTP Request

參考文章:What happens when no response is received for a request?

最近碰上的一個問題是後端接收到重覆的 request
在前端的JavaScript留下的 log 也確認送出的 request 只有一個
那麼後端收到重複的 request 的原因反而令人困惑

其實這個問題的原因我在之前就聽過類似的例子
不過直到這次採到痛點才又回想起來
也多虧於此,沒花太多時間就克服了這個問題

根據 HTTP 1.1 RFC 8.2.4 的協定
If an HTTP/1.1 client sends a request which includes a request body, but which does not include an Expect request-header field with the “100-continue” expectation, and if the client is not directly connected to an HTTP/1.1 origin server, and if the client sees the connection close before receiving any status from the server, the client SHOULD retry the request.

也就是HTTP裡有著上述的規範
當 Server 接收了 request 後,理所當然的需要吐出 response
瀏覽器端使用了 Collision Avoidance 的規則
當超過一定時間沒有接收到 response 後,會自動重發 request
所以就會有 JavaScript 的 log 紀錄只有發出一個 request,但 Server 卻收到很多個的狀況

如果後端的頁面需要進行一項長時間的作業
就算你送出這個 request 後並不需要取得任何回應內容也一樣
考量到瀏覽器需要在一定時間內得到回應,那麼可以採取的方式有兩種
第一種就是強迫頁面 flush buffer,先吐些東西讓瀏覽器能接收
當然在這個狀況下,如何讓瀏覽器接收後續的內容就是另一個問題
第二種則是將需要進行長時間作業的部份另外開一個 Thread 進行

這不是常發生的狀況,但是發生後若不熟HTTP的spec就很難找出原因
重複的 request 表示很可能會將系統效能用在沒有意義的重複運算,甚至跟資料同步也有影響
進行後端架構設計時,絕對要避免這個狀況

留言

  1. 這個實務上通常怎麼解決啊?
    如果有時候只是網路突然延遲了造成這樣的情況呢?

    回覆刪除
    回覆
    1. 這個狀況應該蠻難因網路延遲而產生
      首先前提是 request 已經送到 server 進行 handshake
      再來經過好幾分鐘沒收到回應才會發生

      如果網路有障礙,應該在第一次連線的 handshake 步驟就有問題
      或者是在第二次送 request 發現連不上而改跳404之類的訊息

      這次我是腦包要寫一個回傳想查詢的資料庫資料整合的功能
      測試時的資料少所以沒問題
      等上線後碰到查詢幾千筆資料的需求就出包了
      最後是改成另外開Thread的架構處理

      刪除

張貼留言