Performance JBoss CPU利用率问题
我正在使用JBossAS4.2.3和seam框架。我的CPU使用率随着用户数量的增加而增加,仅80个用户的CPU使用率就达到99%。我们还将Hibernate、EJB3和Apache与mod_jk一起用于负载平衡 当我进行线程转储时,所有可运行线程都在使用以下跟踪执行相同的活动:Performance JBoss CPU利用率问题,performance,jboss,cpu-usage,josso,Performance,Jboss,Cpu Usage,Josso,我正在使用JBossAS4.2.3和seam框架。我的CPU使用率随着用户数量的增加而增加,仅80个用户的CPU使用率就达到99%。我们还将Hibernate、EJB3和Apache与mod_jk一起用于负载平衡 当我进行线程转储时,所有可运行线程都在使用以下跟踪执行相同的活动: at java.net.SocketInputStream.socketRead0(Native Method) at java.net.SocketInputStream.read(SocketInputStrea
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.read(SocketInputStream.java:129)
at org.apache.coyote.ajp.AjpProcessor.read(AjpProcessor.java:1012)
at org.apache.coyote.ajp.AjpProcessor.readMessage(AjpProcessor.java:1091)
at org.apache.coyote.ajp.AjpProcessor.process(AjpProcessor.java:384)
at org.apache.coyote.ajp.AjpProtocol$AjpConnectionHandler.process(AjpProtocol.java:366)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:446)
at java.lang.Thread.run(Thread.java:662)
我无法用堆栈跟踪来解释这一点。我还发现,即使用户已注销,CPU利用率仍然与处于相同状态的线程相同。这些线程正在尝试从套接字连接读取数据。在这种情况下,他们正在等待下一个请求从Apache中的
mod_jk
发送到服务器。这很正常,它们可能不是CPU使用的原因
此时,您确实需要通过探查器运行应用程序
如果您无法在系统上运行探查器(即,它是一个生产箱),下一个最好的方法是开始每隔几秒钟进行许多堆栈转储,然后手动匹配线程ID来完成它们。您需要查找正在运行代码且在转储之间似乎没有更改的线程
这是一项非常乏味的任务,并不总是能得到明确的结果,但是如果没有探查器或某种工具,您将无法找到所有CPU的去向。查看Apache和Jboss之间的AJP配置,如中所述 问题 JBoss Web的(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>
上述workers.properties中的关键点是我们增加了限制
对于mod_jk制作的连接。对于基本配置,套接字
超时默认为无限。其他重要属性包括
ping_模式和ping_超时,用于处理探测
错误和连接池超时,必须设置为相等
使用prefork mpm时,server.xml的connectionTimeout。当这些
在x的连接处于非活动状态后,两个值相同
在一定时间内,mod_jk和Tomcat中的连接将在
同时,防止半封闭连接
Apache配置
请注意,AJP连接的maxThreads应与
在Apache的httpd.conf中设置的MaxClient。需要设置MaxClient
在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是预工作。这并不总是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>
StartServers 8
MinSpareServers 5
MaxSpareServers 20
MaxClients 200
MaxRequestsPerChild 0
或者,如果Apache正在使用worker,那么它就是
<IfModule worker.c>
StartServers 2
MaxClients 200
MinSpareThreads 25
MaxSpareThreads 75
ThreadsPerChild 25
MaxRequestsPerChild 0
</IfModule>
StartServers 2
MaxClients 200
Minspare25
MaxSpareThreads 75
螺纹预裂25
MaxRequestsPerChild 0
MaxRequestsPerChild为0,这是使用时的建议值
mod_jk as mod_jk保持开放的持久连接。中的关键值
上面的配置是MaxClients和maxrequestsprchild,即
其余的值保留为默认值。请注意,MaxRequestsPerChild
建议为0,但该值可能需要大于0
这取决于Apache是否也用于其他模块,尤其是在
资源泄漏的案例
在该链接中,您可以找到另一种配置,以进一步优化此场景 有没有可能是我的请求太重了,以至于它一直在读取它们。我的apache和jboss实例也在同一个物理框中。如果你一直进行堆栈转储,你会看到更多的活动,而不仅仅是
socketRead0
jboss上至少会有其他内容。残酷的事实是,您需要首先查看应用程序所在的线程,jboss和apache以及jboss并不会在授权方案中增加巨大的CPU开销。通常我希望等待线程处于等待状态,然后是Tomcat(或jboss)等待org.apache.tomcat.util.net.JIoEndpoint$Worker
。我看到过这样的情况,其中一个AJP deamon线程也“卡在”socketRead0中,状态为RUNNABLE,其他线程都处于上述等待状态。再次感谢大家。我看到我的所有socket.read0()总是可运行的。另外,我的LBS方法是worker.properties中的。我们还使用JoSSo进行身份验证。当我们运行负载测试时,我们发现即使发生注销,利用率也不会下降。对此有什么想法吗。您可以暂时切换到使用mod_proxy/mod_proxy_http来替换mod_jk并连接到httpjboss的连接器,如果CPU使用量大大减少,那么mod_jk/AJP设置确实存在问题
<IfModule prefork.c>
StartServers 8
MinSpareServers 5
MaxSpareServers 20
MaxClients 200
MaxRequestsPerChild 0
</IfModule>
<IfModule worker.c>
StartServers 2
MaxClients 200
MinSpareThreads 25
MaxSpareThreads 75
ThreadsPerChild 25
MaxRequestsPerChild 0
</IfModule>