共用的抽象模型(客戶及伺服器端)- 超時處理
Akka HTTP 的超時處理
Akka HTTP 有好幾個內建的超時處理機制可用於防禦針對伺服器端的惡意攻擊或者開發中引出的錯誤。其中幾個只是簡單的配置項(可以用代碼修改相關值),另外幾個則是通過流式 API (在開發者代碼中直接以相關模式實現)進行處理。
通用的超時處理
閑置超時
idle-timeout 是一個全局配置,可以設定任意一個連接的最長閑置時間。換成另一種說法,如果一個連接在開啟狀態下沒有任何的 請求/響應 數據在超過 idle-timeout 規定的時長內寫入,這個連接就會被自動關閉。
無論是客戶端,還是伺服器端,相關配置對於連接的使用方式都是一樣的,而且可以獨立對應不同的環境通過以下的鍵值進行配置
akka.http.server.idle-timeoutakka.http.client.idle-timeoutakka.http.host-connection-pool.idle-timeoutakka.http.host-connection-pool.client.idle-timeout
注意事項
對於客戶端的連接池設置,閑置時段的判斷起始點是當連接池中已經沒有需要處理的請求在等待寫入為準。
伺服器端相關超時處理
請求超時
請求超時處理:這是限制一個路由上生成一個 HttpResponse 的所需最大時長的一種機制。如果超過限期還沒生成相關響應,伺服器會自動往連接上寫入一個 Service Unavailable 的 HTTP 響應並關閉連接以防止溢出或者防止連接無限期地存在。舉個例子,如果有個開發上的錯誤導致一個 Future 永遠不結束,這將使真正需要的響應永遠不會往連接送出。
(譯註:這句防止溢出也太泛泛了...具體而言,如果所有的連接都不關閉的話,無論網路連接,文件句柄,線程/進程,還是內存總量都有可能溢出。這些具體的配置要看具體的操作系統,應用程序,以及用戶量做具體調整)
當請求處理超時,系統會往連接寫入如下的默認 HttpResponse
HttpResponse(StatusCodes.ServiceUnavailable, entity = "The server was not able " + "to produce a timely response to your request.
Please try again in a short while!")
通過設定 akka.http.server.request-timeout 的相關參數(默認為 20 秒),可以配置一個作用用於所有路由的全局請求超時值。
注意事項
請注意,如果客戶端在同一個連接上送出多個請求(R1,R2,R3,...),而在第 n 個請求時激發了請求超時,伺服器會返回默認響應並關閉連接,以致第 n+1 個(及後續)請求無任何處理。
請求超時的值也可以在代碼中通過 TimeoutDirectives 在任意一個路由中動態修改。
綁定超時處理
綁定超時是指:(通過任何一個 Http().bind* 函數)完成綁定相關 TCP 埠所需過程的時間長短超過規限。該值可以通過 akka.http.server.bind-timeout 設置
客戶端相關超時處理
連通超時
連通超時是指:完成建立相關 TCP 兩端連接所需過程的時間長短超過規限。一般來說很少需要對相關參數進行調整。但可以對無法在有限時間內建立的連接以錯誤的形式突顯,以便進行異常處理。
該值可以通過 akka.http.client.connecting-timeout 設置
(譯註:翻譯到這裡,有點醉了,這完全就是要開發人員對 TCP 規範各步驟起碼有個基本的認知啊,這算啥解釋... 不想搞太深的可以先參考一下祖宗級的概念 Berkeley Socket)
推薦閱讀:
※最經典的前端面試題之一,你能答出什麼幺蛾子?
※前端工程師應該對 HTTP 了解到什麼程度?從哪些途徑去熟悉更好?
※ApiTestEngine 演化之路(1)搭建基礎框架
※MaxCompute - ODPS重裝上陣 第三彈 - 複雜類型
※什麼是HTTP隧道,怎麼理解HTTP隧道呢?