我在多个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 et.al.从Apache Httpd支持这样的故障转移场景,即拥有多个主机,并且当一个主机出现故障时不会造成巨大延迟? Apache应该定期检查后台哪些主机已经消失,而不是任何请求。
我确实发现HAProxy似乎更适合这类事情,但我更倾向于坚持使用Apache,原因有很多。
与此同时,我发现我的问题的一部分是由客户端造成的,这些客户端无休止地打开连接,因此没有更多的连接/线程可用。
因此我将问题改为: 您将使用哪些配置选项来最小化此类效果?即在这种情况下,允许多个打开的连接或快速关闭它们?否则,这听起来像是一个非常简单的DOS攻击我的当前配置?
答案 0 :(得分:6)
客户端不会无休止地保持连接打开。检查Apache server-tuning.conf并查找KeepAliveTimeout设置。把它降低到合理的程度。
您对connectiontimeout和重试的更改确实是您必须要做的。我会降低连接时间。 10秒仍然是年龄。如果后端位于同一位置,为什么不在几毫秒内设置它? connectiontimeout = 200ms应该留出足够的时间来建立连接。
答案 1 :(得分:2)
我认为我至少找到了一种解决方法或简单的解决方案。默认情况下,mod_proxy似乎有一个非常长的连接超时(300秒)。如果不进行不同的设置,则需要很长时间才能检测到脱机节点处于“错误”状态。
通过设置一个简短的连接超时并增加重试次数,我可以让它更适合我:
BalancerMember ajp://host1:8280 route=jvmRoute-8280 connectiontimeout=10 retry=600
这将确保快速检测到失败的连接,并且Apache不会经常重试以访问失败的服务器。不幸的是,似乎Apache使用实际请求来检查余额成员,因此当尝试访问先前进入错误状态的服务器时,单个请求可能会很慢。似乎没有心跳或看门狗功能。对于类似这样的事情,其他负载平衡解决方案带来了这些功能,特别是HAProxy
阅读mod_proxy和mod_proxy_balancer了解详情。
此外,通过mod_status和余额管理员通过a page provided by mod_balancer提供的服务器状态对于诊断此功能非常有帮助!
答案 2 :(得分: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/"