审查的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