gpt4 book ai didi

Apache mod_proxy_ajp 模块过早地将流量发送到备用后端服务器

转载 作者:行者123 更新时间:2023-11-28 22:39:12 25 4
gpt4 key购买 nike

我们有一对运行 mod_proxy_ajp 的 Apache 2.4 网络服务器(web02web03)与一对 Tomcat 7.0 通信。 59 台服务器(app02app03)。

app03 上的 Tomcat 服务器是备用服务器,除非 app02 完全离线,否则不应获取流量。

web02 和 web03 上的 Apache 配置:

<Proxy balancer://ajp_cluster>
BalancerMember ajp://app02:8009 route=worker1 ping=3 retry=60
BalancerMember ajp://app03:8009 status=+R route=worker2 ping=3 retry=60
ProxySet stickysession=JSESSIONID|jsessionid lbmethod=byrequests
</Proxy>

app02 和 app03 上 AJP 的 Tomcat 配置:

<Connector protocol="AJP/1.3" URIEncoding="UTF-8" port="8009" />

我们发现 Apache 开始将流量发送到 app03 的问题,即使 app02 仍然可用但可能有点忙,它也被标记为备用。

Apache SSL 错误日志:

[Thu Sep 12 14:23:28.028162 2019] [proxy_ajp:error] [pid 24234:tid 140543375898368] (70007)The timeout specified has expired: [client 207.xx.xxx.7:1077] AH00897: cping/cpong failed to 10.160.160.47:8009 (app02)
[Thu Sep 12 14:23:28.028196 2019] [proxy_ajp:error] [pid 24234:tid 140543375898368] [client 207.xx.xxx.7:1077] AH00896: failed to make connection to backend: app02
[Thu Sep 12 14:23:28.098869 2019] [proxy_ajp:error] [pid 24135:tid 140543501776640] [client 207.xx.xxx.7:57809] AH01012: ajp_handle_cping_cpong: ajp_ilink_receive failed, referer: https://site.example.com/cart
[Thu Sep 12 14:23:28.098885 2019] [proxy_ajp:error] [pid 24135:tid 140543501776640] (70007)The timeout specified has expired: [client 207.xx.xxx.7:57809] AH00897: cping/cpong failed to 10.160.160.47:8009 (app02), referer: https://site.example.com/cart

我们的 Apache 日志中有数百条这样的消息。

关于使 Apache 坚持 app02 除非它完全离线的设置有什么建议吗?

最佳答案

您在 Tomcat 连接器中遇到线程耗尽导致 httpd 认为 app02 处于错误状态 - 在某种程度上确实如此。

简短的回答是将您的 Tomcat AJP 连接器切换为使用 protocol="org.apache.coyote.ajp.AjpNioProtocol"

长答案是,嗯,相当长。

mod_jk 在 httpd 和 Tomcat 之间使用持久连接。对此的历史论据是性能。它节省了为每个请求建立新的 TCP 连接的时间。通常,测试表明此参数不成立,并且建立新的 TCP 连接或执行 CPING/CPONG 以确认连接有效所花费的时间(如果使用持久连接则需要这样做)足够接近同一时间。不管怎样,持久连接是 mod_jk 的默认设置。

当使用持久连接时,mod_jk 为每个 httpd 工作线程创建一个连接,并将该连接缓存在工作线程中。

Tomcat 7.x 中的默认 AJP 连接是 BIO 连接器。此连接器使用阻塞 I/O,每个连接需要一个线程。

当 httpd 配置的 worker 多于 Tomcat 的线程数时,就会出现此问题。最初一切正常。当 httpd worker 遇到需要传递给 Tomcat 的第一个请求时,mod_jk 会为该 httpd worker 创建持久连接并为该请求提供服务。需要传递给 Tomcat 的由该 httpd worker 处理的后续请求将使用该缓存连接。请求被(有效地)随机分配给 httpd worker 。随着越来越多的 httpd worker 看到他们的第一个请求需要传递给 Tomcat,mod_jk 为每个 worker 创建必要的持久连接。很可能许多与 Tomcat 的连接大多处于空闲状态。闲置程度取决于 httpd 上的负载以及传递给 Tomcat 的请求的比例。

一切都很好,直到更多的 httpd 工作人员需要创建到 Tomcat 的连接,Tomcat 有线程。请记住,Tomcat AJP BIO 连接器需要每个连接一个线程,因此 maxThreads 实际上是 Tomcat 允许的最大 AJP 连接数。此时 mod_jk 无法创建请求,因此启动故障转移过程。

有两种解决方案。第一个 - 我上面描述的那个 - 是删除每个连接一个线程的限制。通过切换到NIO AJP连接器,Tomcat使用一个Poller线程维护上千个连接,只把有数据需要处理的交给一个线程处理。 Tomcat 处理的限制是 maxThreads 是 Tomcat 可以在该连接器上处理的最大并发请求数。

第二种解决方案是禁用持久连接。 mod_jk 创建一个连接,将它用于单个请求,然后关闭它。这减少了 mod_jk 在 httpd 和 Tomcat 之间的任何一点所需的连接数。

抱歉,上面是一大堆文字。我也在各种演示中介绍了这一点,包括 this one .

关于Apache mod_proxy_ajp 模块过早地将流量发送到备用后端服务器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58033650/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com