審查的Apache和JBoss之間的AJP的配置,如https://developer.jboss.org/wiki/OptimalModjk12Configuration
問題
JBoss應用的(Tomcat)的server.xml中AJP描述片段:
<Connector port="8009" address="${jboss.bind.address}" protocol="AJP/1.3"
emptySessionPath="true" enableLookups="false" redirectPort="8443" ></Connector> Apache's httpd.conf:
<IfModule prefork.c>
StartServers 8
MinSpareServers 5
MaxSpareServers 20
ServerLimit 256
MaxClients 256
MaxRequestsPerChild 4000
</IfModule>
以上配置,在負載下,可能會導致mod_jk非常慢,並且不響應,導致http錯誤,並導致半連接的 連接。出現這些問題的原因可能是因爲沒有指定用於照顧孤立連接的連接超時 ,沒有在worker.properties中定義的 錯誤處理屬性,也沒有在Apache和Tomcat中設置 連接限制。
但是這麼多的線程可能來自另一個來源。如上所述here:
的懸掛Socket.read(最常見的情況)是一種高 處理時間或遠程服務提供商的不健康狀態。 這意味着您需要立即與服務提供商 聯繫支持團隊,以確認他們的系統是否面臨某些 減速條件。
你的一個應用服務器的線程應該被釋放,一旦遠程 服務提供商的系統問題得以解決,但往往你會 需要重新啓動服務器實例(Java虛擬機),以清除所有 掛線程;特別是如果你缺乏適當的超時執行 。
其他較少見的原因包括:使增加經過時間
- 巨大響應數據讀/消耗的插座的InputStream例如如非常大的XML數據。通過分析響應數據的大小可以很容易地證明這可以是
- 網絡延遲導致從服務提供商到Java EE生產系統的數據傳輸所花費的時間增加。這可以 運行您的生產 服務器之間和服務提供商的一些網絡嗅探器,並確定任何重大的滯後/延遲 問題
無論是你的問題,要做的第一件事就是檢查你的超時被證明組態!
你可以做什麼?
你需要爲Jboss和Apache做一些配置。
的JBoss側
與的server.xml主要關心的是設定爲ConnectionTimeout 它設置底層套接字的SO_TIMEOUT。因此,當 中的連接在012xxconnectionTimeout指定的時間內沒有請求時,則連接將中斷。這是必要的 ,因爲如果連接沒有被用於特定時間段 時間那麼它有可能在mod_jk結束時是半關閉的。
如果連接沒有關閉,將會出現線程膨脹 ,這會隨着時間的流逝而擊中Tomcat中的maxThreads計數,那麼Tomcat將不能接受任何新的連接。連接超時 600000(10分鐘)是一個很好的開始。可能存在 這種情況,其中連接沒有被足夠快地回收,在這種情況下, 可以將connectionTimeout降低到60000分鐘或10分鐘。
在Tomcat中設置connectionTimeout時,mod_jk也應該設置爲 connect_timeout/prepost_timeout,它允許檢測到Tomcat連接已關閉並阻止重試請求。我們假設 服務器是單核心機器。如果它是四核,那麼我們 可以將該值推到800,並且更多取決於RAM和其他 機器規格。
<Connector port="8009"
address="${jboss.bind.address}"
emptySessionPath="true"
enableLookups="false"
redirectPort="8443"
protocol="AJP/1.3"
maxThreads="200"
connectionTimeout="600000"></Connector>
阿帕奇側
worker.properties文件
見註釋行內。
worker.list=loadbalancer,status
worker.template.port=8009
worker.template.type=ajp13
worker.template.lbfactor=1
#ping_timeout was introduced in 1.2.27
worker.template.ping_timeout=1000
#ping_mode was introduced in 1.2.27, if not
#using 1.2.27 please specify connect_timeout=10000
#and prepost_timeout=10000 as an alternative
worker.template.ping_mode=A
worker.template.socket_timeout=10
#It is not necessary to specify connection_pool_timeout if you are running the worker mpm
worker.template.connection_pool_timeout=600
#Referencing the template worker properties makes the workers.properties shorter and more concise
worker.node1.reference=worker.template
worker.node1.host=192.168.1.2
worker.node2.reference=worker.template
worker.node2.host=192.168.1.3
worker.loadbalancer.type=lb
worker.loadbalancer.balance_workers=node1,node2
worker.loadbalancer.sticky_session=True
worker.status.type=status
在上述workers.properties的關鍵點是我們增加了限制 爲mod_jk的使得連接。使用基本配置時,套接字 超時默認爲無限。其他重要屬性是 ping_mode和ping_timeout,它們處理探測連接的錯誤和connection_pool_timeout,必須設置爲 當使用prefork mpm時,server.xml的connectionTimeout。當這兩個值相同時,連接在x 時間內處於非活動狀態後,mod_jk和Tomcat中的連接將同時關閉,並在 處關閉,從而阻止半關閉連接。
Apache配置
記下的AJP連接maxThreads應 在Apache的httpd.conf設置的MaxClients一致。 MaxClients需要在Apache的正確模塊中設置爲 。
這可以通過運行httpd -V
確定:
# httpd -V
Server version: Apache/2.2.3
Server built: Sep 11 2006 09:43:05
Server's Module Magic Number: 20051115:3
Server loaded: APR 1.2.7, APR-Util 1.2.8
Compiled using: APR 1.2.7, APR-Util 1.2.7
Architecture: 32-bit
Server MPM: Prefork
threaded: no
forked: yes (variable process count)
Server compiled with....
-D APACHE_MPM_DIR="server/mpm/prefork"
-D APR_HAS_SENDFILE
-D APR_HAS_MMAP
-D APR_HAVE_IPV6 (IPv4-mapped addresses enabled)
-D APR_USE_SYSVSEM_SERIALIZE
-D APR_USE_PTHREAD_SERIALIZE
-D SINGLE_LISTEN_UNSERIALIZED_ACCEPT
-D APR_HAS_OTHER_CHILD
-D AP_HAVE_RELIABLE_PIPED_LOGS
-D DYNAMIC_MODULE_LIMIT=128
-D HTTPD_ROOT="/etc/httpd"
-D SUEXEC_BIN="/usr/sbin/suexec"
-D DEFAULT_PIDLOG="logs/httpd.pid"
-D DEFAULT_SCOREBOARD="logs/apache_runtime_status"
-D DEFAULT_LOCKFILE="logs/accept.lock"
-D DEFAULT_ERRORLOG="logs/error_log"
-D AP_TYPES_CONFIG_FILE="conf/mime.types"
-D SERVER_CONFIG_FILE="conf/httpd.conf"
它告訴我的服務器MPM爲prefork的。這並不總是準確的,因此您還應該查看/ etc/sysconfig/httpd的輸出爲 ,看下面的行是否存在:HTTPD =/usr/sbin/httpd.worker。如果 它被註釋掉你正在運行prefork,否則如果沒有註釋 工人。
的httpd.conf:
<IfModule prefork.c>
StartServers 8
MinSpareServers 5
MaxSpareServers 20
MaxClients 200
MaxRequestsPerChild 0
</IfModule>
或者Apache是否使用工人,這是
<IfModule worker.c>
StartServers 2
MaxClients 200
MinSpareThreads 25
MaxSpareThreads 75
ThreadsPerChild 25
MaxRequestsPerChild 0
</IfModule>
MaxRequestsPerChild值0,這是建議值使用的mod_jk 作爲時的mod_jk保持開放的持久連接。 上述配置中的關鍵值是MaxClients和MaxRequestsPerChild,其餘的值保留爲默認值。請注意,MaxRequestsPerChild 建議爲0,但該值可能需要大於0 ,具體取決於Apache是否也用於其他模塊,尤其是在 資源泄漏的情況下。
在鏈接中,您可以找到另一個配置來優化更多此場景。
是否有可能我的請求太重以至於始終讀取它們。另外,我的apache和jboss實例位於相同的物理盒子中。 – Dwarakanath 2011-06-13 13:10:34
如果你繼續採用堆棧轉儲,你會看到更多的活動,而不僅僅是'socketRead0' jboss至少會有其他的東西。最殘酷的事實是,首先需要關注應用程序中的線程,jboss和apache以及jboss的線程並不會真正增加事物授權方案中的巨大CPU開銷。 – 2011-06-13 13:21:54
通常我會期待等待的線程處於狀態WAITING,然後是Tomcat(或JBoss)等待'org.apache.tomcat.util.net.JIoEndpoint $ Worker'。我曾見過其中一個AJP deamon線程在狀態爲RUNNABLE的socketRead0中「卡住」的情況,其中所有其他狀態都處於上述WAITING狀態。 – 2011-06-13 13:24:00