Spring Zuul 性能調優,如何提升平均響應時間200% ?


最近負責公司的 Gateway 項目,我們用 Spring Zuul 來做 HTTP 轉發,但是發現請求多的時候,AWS 的健康檢查就失敗了,但是實際上程序還在跑,在日志上也沒有任何東西錯誤打印出來出來。通過本身上報的性能數據發現,backend_processing_time 非常高,正常的情況下,這個數據約等於下游服務的響應時間。但是下游服務的響應時間都在500毫秒左右,所以問題出在 Zuul 本身上。

 

 

我們的 backend_processing_time 實際上就是取的 Zuul 本身的 SimpleHostRoutingFilter 的執行時間,如果花在網絡通信上的時間不多,那么一定是這個 Filter 本身在哪里卡住了。我閱讀了這個 Filter 的源碼,發現實際上這個 Filter 本身是用的 Apache HTTP Client 來執行網絡請求的,而且是用的池化的鏈接。

在 Zuul 的配置里,有這么一個配置 `zuu.host.max-per-route-connections` 這個配置對應的就是  Apache HTTP Client 中的 DefaultMaxPerRoute,文檔這么寫到:

 A request for a route for which the manager already has a persistent connection available in the pool will be serviced by leasing a connection from the pool rather than creating a brand new connection.

PoolingHttpClientConnectionManager maintains a maximum limit of connections on a per route basis and in total. Per default this implementation will create no more than 2 concurrent connections per given route and no more 20 connections in total. For many real-world applications these limits may prove too constraining, especially if they use HTTP as a transport protocol for their services.

 這個類似於數據庫的鏈接池,一般而言從鏈接池拿鏈接的時候,都會有個超時時間,過了這個超時時間,會拋異常。其實這個超時時間也是有的,對應的是  Apache HTTP Client 中的 `getRequestTimeout`。問題是,在 Zuul 中,這個超時時間為-1,並且不能設置。根據 Apache HTTP Client 中的文檔,

Returns the timeout in milliseconds used when requesting a connection from the connection manager. A timeout value of zero is interpreted as an infinite timeout. A timeout value of zero is interpreted as an infinite timeout. A negative value is interpreted as undefined (system default).

所以當 HTTP 鏈接拿完以后,線程就等在那里,造成整個系統 Hang 住。解決辦法就是,提升這個max-per-route-connections的數值,以下是兩次壓測的結果

 

max-connection-per-route = 20

max-connection-per-route = 300

從壓測結果得知,評價響應時間提升了200%,P90 提升了 100%。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM