如何正确将 Apache Httpd 配置为负载均衡器,其中某些主机可能不可用



我在多个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 不记得其中一个主机不可用,并反复尝试向丢失的主机发送请求,而不是将其发送到其中一个可用主机并在稍后的某个时间尝试失败的主机。

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

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


更新

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

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

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

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

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

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

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

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

阅读mod_proxy和mod_proxy_balancer了解更多详情。

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

似乎你忘记了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/"

最新更新