查看您在 Apache 和 Jboss 之间的 AJP 配置,如 https://developer.jboss.org/wiki/OptimalModjk12Configuration 中所述
问题
JBoss Web 的 (Tomcat) server.xml AJP sn-p:
<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 VM)以清除所有
挂线程;特别是如果你缺乏适当的超时
实施。
其他不太常见的原因包括:
- 巨大的响应数据导致读取/使用套接字输入流的时间增加,例如例如非常大的 XML 数据。这可以是
通过分析响应数据的大小轻松证明
- 网络延迟导致数据从服务提供商传输到 Java EE 生产系统的时间增加。这个可以
通过在您的生产之间运行一些网络嗅探器来证明
服务器和服务提供商,并确定任何主要的滞后/延迟
问题
无论您遇到什么问题,首先要做的就是检查您的超时配置!
你能做什么?
你需要为 Jboss 和 Apache 做一些配置。
JBoss端
server.xml 的主要关注点是设置 connectionTimeout
它设置底层套接字的 SO_TIMEOUT。所以当一个连接在
Tomcat 在指定的时间内没有请求
connectionTimeout,然后连接断开。这是必要的
因为如果连接在一段时间内没有被使用
那么有可能在 mod_jk 端半关闭。
如果连接未关闭,则会出现线程膨胀
随着时间的推移,这可能会达到 Tomcat 中的 maxThreads 计数,然后 Tomcat 将
无法接受任何新连接。一个连接超时
600000(10 分钟)是一个很好的开始数字。可能有
连接回收速度不够快的情况,
在这种情况下,connectionTimeout 可以降低到 60000 或 1
分钟。
在Tomcat中设置connectionTimeout时,mod_jk也应该有
connect_timeout/prepost_timeout 设置,它允许检测
Tomcat 连接已关闭并阻止重试请求。
maxThreads 的推荐值为每个 CPU 200,所以这里我们假设
服务器是单核机器。如果是四核,我们
可以将该值推至 800,甚至更多,具体取决于 RAM 和其他
机器规格。
<Connector port="8009"
address="${jboss.bind.address}"
emptySessionPath="true"
enableLookups="false"
redirectPort="8443"
protocol="AJP/1.3"
maxThreads="200"
connectionTimeout="600000"></Connector>
Apache 端
worker.properties 文件
查看 cmets 内联。
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 用于探测连接
errors 和 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。这并不总是 100%
准确,因此您还应该查看 /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 正在使用 worker,它是
<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 是否也用于其他模块,尤其是在
资源泄露案例。
在链接中,您可以找到另一个配置来进一步优化此场景。