11

我在多个 Java Tomcat 实例前使用 Apache Httpd 实例作为代理。Apache 充当 Tomcat 实例的负载平衡器。

apache 配置基本上如下所示

<Proxy balancer://mycluster>
    BalancerMember ajp://host1:8280 route=jvmRoute-8280
    BalancerMember ajp://host2:8280 route=jvmRoute-8280
    BalancerMember ajp://host3:8280 route=jvmRoute-8280
</Proxy>
<VirtualHost *:80>
ProxyPass / balancer://mycluster/
ProxyPassReverse / balancer://mycluster/
</VirtualHost>

当在 Tomcat 实例中配置 AJP 端口时,这基本上可以工作。请求被发送到其中一台主机,负载分布在 Tomcat 实例中。

但是,我看到每当其中一台主机不可用时,似乎在 Httpd 内部造成了很长的延迟,即 Apache 似乎不记得其中一台主机不可用,并且反复尝试将请求也发送到丢失的主机而不是将其发送到可用的主机之一,并在稍后的某个时间尝试失败的主机。

有没有办法配置 mod_proxy 等。从 Apache Httpd 支持这样的故障转移场景,即拥有多个主机并且在一个主机发生故障时不会造成巨大的延迟?最好 Apache 应该定期在后台检查哪些主机已经消失,而不是任何请求。

我确实发现HAProxy似乎更适合这种事情,但出于一些不相关的原因,我更愿意坚持使用 Apache。


更新

与此同时,我发现我的部分问题是由客户端造成的,客户端使连接无休止地打开,因此没有更多的连接/线程可用。

因此,我将问题更改为:您将使用哪些配置选项来最大程度地减少此类事情的影响?即在这种情况下允许许多打开的连接还是快速关闭它们?否则这听起来像我当前配置的一个非常简单的 DOS 攻击?

4

3 回答 3

6

客户端不会无休止地保持连接打开。检查您的 Apache server-tuning.conf 并查找 KeepAliveTimeout 设置。把它降低到合理的程度。

您对 connectiontimeout 和 retry 的更改确实是您必须做的。我会降低连接超时。10秒仍然是年龄。如果后端位于同一位置,为什么不以毫秒为单位进行设置?connectiontimeout=200ms 应该留出足够的时间来建立连接。

于 2013-01-31T09:43:48.097 回答
2

我想我至少找到了一种解决方法或简单的解决方案。默认情况下,mod_proxy 似乎有很长的连接超时时间(300 秒)。如果不进行不同的设置,则需要很长时间才能检测到离线节点处于“错误”状态。

通过设置一个较短的连接超时并增加重试次数,我可以让它更好地为我工作:

BalancerMember ajp://host1:8280 route=jvmRoute-8280 connectiontimeout=10 retry=600

这将确保相当快地检测到失败的连接,并且 Apache 不会过于频繁地重试以到达失败的服务器。不幸的是,Apache 似乎使用实际请求来检查余额成员,因此当它尝试到达先前进入错误状态的服务器时,有时单个请求可能会很慢。似乎没有心跳或看门狗功能。对于这样的事情,其他负载平衡解决方案带来了这样的功能,特别是HAProxy

阅读mod_proxymod_proxy_balancer了解更多详情。

此外,通过mod_status的服务器状态和通过 mod_balancer 提供的页面的平衡管理器对诊断这个有很大帮助!

于 2013-01-26T23:53:21.430 回答
1

好像忘记了ping标签(其实叫 CPING - 100-Continue)

像这样:

<Proxy "balancer://www">
    BalancerMember "http://192.168.0.100:80" max=128 ttl=300 retry=60 connectiontimeout=5 timeout=300 ping=2
    BalancerMember "http://192.168.0.101:80" max=128 ttl=300 retry=60 connectiontimeout=5 timeout=300 ping=2
    BalancerMember "http://192.168.0.102:80" max=128 ttl=300 retry=60 connectiontimeout=5 timeout=300 ping=2
    BalancerMember "http://192.168.0.103:80" max=128 ttl=300 retry=60 connectiontimeout=5 timeout=300 ping=2
    BalancerMember "http://192.168.0.104:80" max=128 ttl=300 retry=60 connectiontimeout=5 timeout=300 ping=2
    BalancerMember "http://192.168.0.105:80" max=128 ttl=300 retry=60 connectiontimeout=5 timeout=300 ping=2
    BalancerMember "http://192.168.0.106:80" max=128 ttl=300 retry=60 connectiontimeout=5 timeout=300 ping=2
    SetEnv proxy-nokeepalive 1
</Proxy>
ProxyPass "/www/" "balancer://www/"
ProxyPassReverse "/www/" "balancer://www/"
于 2017-11-03T11:38:49.867 回答