簡體   English   中英

高度並行的Apache Async HTTP客戶端IOReactor問題

[英]Highly Concurrent Apache Async HTTP Client IOReactor issues

應用說明:

  • 我正在使用由Comsat的Quasar FiberHttpClient(版本0.7.0)包裝的Apache HTTP異步客戶端(版本4.1.1),以便運行和執行一個高度並發的Java應用程序,該應用程序使用光纖在內部將HTTP請求發送到多個HTTP端點
  • 該應用程序在tomcat之上運行(但是,光纖僅用於內部請求分派。tomcat servlet請求仍以標准阻塞方式處理)
  • 每個外部請求在內部打開15-20根光纖,每個光纖建立一個HTTP請求並使用FiberHttpClient進行調度
  • 我正在使用c44xlarge服務器(16個內核)來測試我的應用程序
  • 我正在連接到搶占式保持活動連接的端點,這意味着如果我嘗試通過重用套接字進行維護,則在請求執行嘗試期間會關閉連接。 因此,我禁用了連接回收。
  • 根據以上各節,這是我的光纖http客戶端的調諧(當然,我正在使用的單個實例):

     PoolingNHttpClientConnectionManager connectionManager = new PoolingNHttpClientConnectionManager( new DefaultConnectingIOReactor( IOReactorConfig. custom(). setIoThreadCount(16). setSoKeepAlive(false). setSoLinger(0). setSoReuseAddress(false). setSelectInterval(10). build() ) ); connectionManager.setDefaultMaxPerRoute(32768); connectionManager.setMaxTotal(131072); FiberHttpClientBuilder fiberClientBuilder = FiberHttpClientBuilder. create(). setDefaultRequestConfig( RequestConfig. custom(). setSocketTimeout(1500). setConnectTimeout(1000). build() ). setConnectionReuseStrategy(NoConnectionReuseStrategy.INSTANCE). setConnectionManager(connectionManager). build(); 
  • 將打開文件的ulimit設置為超高(軟值和硬值都為131072)

  • Eden設置為18GB,總堆大小為24GB
  • 操作系統Tcp堆棧也進行了很好的調整:

kernel.printk = 8 4 1 7 kernel.printk_ratelimit_burst = 10 kernel.printk_ratelimit = 5 net.ipv4.ip_local_port_range = 8192 65535 net.core.rmem_max = 16777216 net.core.wmem_max = 16777216 net.core.rmem_default = 16777216 net.core .wmem_default = 16777216 net.core.optmem_max = 40960 net.ipv4.tcp_rmem = 4096 87380 16777216 net.ipv4.tcp_wmem = 4096 65536 16777216 net.core.netdev_max_backlog = 100000 net.ipv4.tcp_max_syn_backets = 20000.net net.ipv4.tcp_tw_reuse = 1 net.ipv4.tcp_tw_recycle = 1 net.ipv4.tcp_fin_timeout = 10 net.ipv4.tcp_slow_start_after_idle = 0 net.ipv4.tcp_sack = 0 net.ipv4.tcp_timestamps = 1

問題描述

  • 在中低負載下,一切都很好,連接被租用,克隆並補充池
  • 除了一些並發點,IOReactor線程(其中的16個)在死亡之前似乎已停止正常運行。
  • 我編寫了一個小線程來獲取池統計信息並每秒打印一次。 在大約25K的租用連接中,實際數據不再通過套接字連接發送, Pending stat clibms也急劇上升到30K掛起的連接請求
  • 這種情況持續存在,並且基本上使應用程序無用。 在某個時候,I / O Reactor線程死亡,不確定何時以及到目前為止我還無法捕獲異常
  • lsof荷蘭國際集團的java程序,我可以看到它有成千上萬的文件描述符,幾乎所有的人都在CLOSE_WAIT(這是有道理的,因為I / O反應螺紋模/停止功能和永遠不會真正關閉它們
  • 在應用程序中斷期間,服務器不會嚴重過載/ cpu緊張

問題

  • 我猜想我正在某個地方達到某種界限,盡管我對它可能駐留在什么地方還是什么地方一無所知。 除了以下
  • 我是否有可能達到OS端口(所有應用請求畢竟都來自單個內部IP)限制並創建一個錯誤,使IO Reactor線程死亡(類似於打開文件的限制錯誤)?

忘了回答這個問題,但是發布問題大約一周后,我得到了什么?

  1. 某種錯誤配置導致io反應器僅產生2個線程。

  2. 即使在提供更多的反應堆線程之后,問題仍然存在。 事實證明,我們的傳出請求主要是SSL。 Apache SSL連接處理將核心處理傳播到JVM的SSL設施,這些設施-效率不足以每秒處理數千個SSL連接請求。 更具體地說,SSLEngine內部的一些方法(如果我沒記錯的話)是同步的。 在高負載下執行線程轉儲顯示IORecator線程在嘗試打開SSL連接時互相阻塞。

  3. 甚至嘗試以連接租用超時的形式創建泄壓閥也不起作用,因為創建的積壓訂單過多,導致應用程序無用。

  4. 將SSL傳出請求處理工作卸載到nginx的情況甚至更糟-因為遠程端點搶先終止了請求,所以無法使用SSL客戶端會話緩存(JVM實現也是如此)。

忍不住將信號燈放在整個模塊的前面,在任何給定的時刻將整個事情限制在6000左右,這解決了問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM