【问题标题】:AJP run out of threadAJP 线程耗尽
【发布时间】:2014-10-28 09:21:51
【问题描述】:

我有两个使用 mod_jk 运行的 apache 负载平衡代理服务器(名为 A1、A2)和两个 Jboss Web 服务器(名为 J1、J2)。

Jboss 版本是 jboss-eap-5.1。 Apache 版本是 2.2.15。 操作系统:Red Hat Enterprise Linux Server 6.4 版(圣地亚哥) A1 和 A2 都将请求(端口 80)从外部重定向到 J1、J2(都是端口 8080)。 A1、A2 的设置相同(HostIP 除外)。 J1,J2也有同样的设置(HostIP和jvmRoute除外)

我对这种架构有一些问题。 J1和J2可以很好地处理A1的请求(接收请求->创建线程处理->处理完成->关闭线程)。

但是 A2 的要求很奇怪。进程完成后,线程没有关闭。并且网络连接保持在 ESTABLISHED。 我用jstack PID查了一下,下面的语句很多:

"ajp-XX.XX.72.12-8009-240" daemon prio=10 tid=0x00007f791418e800 nid=0x7793 runnable [0x00007f7875d5c000]
   java.lang.Thread.State: RUNNABLE
    at java.net.SocketInputStream.socketRead0(Native Method)
    at java.net.SocketInputStream.read(SocketInputStream.java:129)
    at org.apache.coyote.ajp.AjpProcessor.read(AjpProcessor.java:1036)
    at org.apache.coyote.ajp.AjpProcessor.readMessage(AjpProcessor.java:1115)
    at org.apache.coyote.ajp.AjpProcessor.process(AjpProcessor.java:383)
    at org.apache.coyote.ajp.AjpProtocol$AjpConnectionHandler.process(AjpProtocol.java:385)
    at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:451)
    at java.lang.Thread.run(Thread.java:662)`

将上述 PID(nid=0x7793 ) 与 ps -efT | 进行比较grep 30611 ,可以得到以下信息: `xxxx 17869 30611 17821 0 20:40? 00:00:00 /usr/local/java/bin/java -program.name=run.sh ...

当我使用 netstat -A inet 时,有很多这样的连接:

Proto Recv-Q Send-Q Local Address               Foreign Address             State      
tcp        0      0 npouiap2:8009               10.100.84.34:49666          ESTABLISHED 
tcp        0      0 npouiap2:8009               10.100.84.34:50374          ESTABLISHED 
tcp        0      0 npouiap2:8009               10.100.84.34:50507          ESTABLISHED 

【问题讨论】:

    标签: multithreading apache jboss5.x ajp


    【解决方案1】:

    问题可能是线程没有空闲,因为默认情况下 AJP 连接 是持久的。

    您可以尝试以下选项之一:

    1. 在 JBoss 上增加 maxThreads"max threads" 相同 (具体指令因 MPM 而异)在 httpd 上
    2. 开启mod_jk'sdisable reuse option

    选项 2 最容易应用并验证问题是否仍然存在。

    【讨论】:

    • 您好 Sierra,感谢您的回复。问题是 A1,A2 具有相同的设置,但只有来自 A2 的连接会导致 AJP 线程挂起。我认为这可能不是由 maxThreads 的设置引起的。选项 2 似乎解决了 A1、A2 上的连接挂起问题。但情况是连接挂在 J1、J2 上。
    • @nsnosheep 你试过停止A1服务器,只处理A2的请求吗? apache 错误日志中是否有任何消息?
    • @Sierra 我无法停止 A1 服务器。因为它运行在我公司的生产环境,并提供7*24服务。我在 J1 和 J2 上运行了 tcpdump。发现如果从 A1 发送请求,J1 和 J2 会同时收到包(一个收到 11 个包,另一个收到 3 个包)。如果从 A2 发送请求,则 J1 或 J2 中只有一个会收到包(14 个包)。我查看了那些包,发现来自 A2 的包有 3 个没有从 A1 发送的 SYN 包。
    • @nsnosheep AJP 是常量协议。一旦建立连接,就永远不会释放,而是重用。好吧,除非您设置基本上不是“连接”超时的 connectionTimeout,而是通过持久连接发出的 2 个 http 请求之间的超时。为此,我认为 A1 在某些时候占用了 JBoss 的所有线程。如果我错了,您可以尝试添加禁用重用选项 y 测试。
    • 嗨,塞拉利昂。我已经考虑过了。明天我将与负责 Infra 的同事讨论。但有一点很奇怪。如果 A1 占用了 JBoss 的所有线程,为什么我仍然可以从 A2 发送请求并获取内容?感谢您的回答。 :D
    猜你喜欢
    • 1970-01-01
    • 2015-02-19
    • 1970-01-01
    • 2016-12-26
    • 2013-06-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多