mod_proxy_balancer
描述: | mod_proxy负载均衡扩展 |
状态: | 延期 |
模块标识符: | proxy_balancer_module |
源文件: | mod_proxy_balancer.c |
兼容性: | 可在 version 2.1 及更高版本中使用 |
摘要
此模块需要mod_proxy服务,并为所有支持的协议提供负载平衡。最重要的是:
- HTTP,使用mod_proxy_http
- FTP,使用mod_proxy_ftp
- AJP13,使用mod_proxy_ajp
- WebSocket,使用mod_proxy_wstunnel
此模块不提供负载平衡调度程序算法,但是来自其他模块,例如:
- mod_lbmethod_byrequests
- mod_lbmethod_bytraffic
- mod_lbmethod_bybusyness
- mod_lbmethod_heartbeat
因此,为了获得负载平衡的能力,必须在服务器中存在mod_proxy,mod_proxy_balancer和至少一个负载平衡调度器算法模块。
警告
在有保护你的服务器之前不要启用代理。开放代理服务器对您的网络和整个 Internet 都是危险的。
负载均衡器调度算法
目前,有 4 种负载均衡器调度算法可供使用:请求计数(mod_lbmethod_byrequests),加权流量计数(mod_lbmethod_bytraffic),待决请求计数(mod_lbmethod_bybusyness)和心跳流量计数(mod_lbmethod_heartbeat)。这些是通过 Balancer 定义的lbmethod
value 控制的。有关更多信息,请参阅ProxyPass指令,尤其是有关如何配置 Balancer 和 BalancerMembers 的信息。
负载平衡器粘性
平衡器支持粘性。当请求被代理到某个 back-end 时,来自同一用户的所有后续请求都应该被代理到相同的 back-end。许多负载均衡器通过 table 将 maps client IP 地址实现为 back-ends 来实现此 feature。这种方法对于 clients 和 back-ends 是透明的,但是遇到了一些问题:如果 client 本身隐藏在代理之后,则负载分配不均匀,当 client 使用在 session 期间发生变化的动态 IP 地址时粘性错误,如果映射 table 溢出。
模块mod_proxy_balancer在两种替代方法之上实现粘性:cookies 和 URL 编码。提供 cookie 可以由 back-end 或 Apache web 服务器本身完成。 URL 编码通常在 back-end 上完成。
平衡器配置示例
在深入研究技术细节之前,这里是一个如何使用mod_proxy_balancer在两个 back-end 服务器之间提供负载平衡的示例:
<Proxy "balancer://mycluster"> BalancerMember "http://192.168.1.50:80" BalancerMember "http://192.168.1.51:80" </Proxy> ProxyPass "/test" "balancer://mycluster" ProxyPassReverse "/test" "balancer://mycluster"
另一个如何使用modheaders提供带粘性的负载平衡的示例,即使 back-end 服务器没有设置合适的 session cookie:
Header add Set-Cookie "ROUTEID=.%{BALANCER_WORKER_ROUTE}e; path=/" env=BALANCER_ROUTE_CHANGED <Proxy "balancer://mycluster"> BalancerMember "http://192.168.1.50:80" route=1 BalancerMember "http://192.168.1.51:80" route=2 ProxySet stickysession=ROUTEID </Proxy> ProxyPass "/test" "balancer://mycluster" ProxyPassReverse "/test" "balancer://mycluster"
导出的环境变量
目前有 6 个环境变量导出:
- BALANCERSESSION_STICKY
这被分配了用于当前请求的 stickysession value。它是用于粘性会话的 cookie 或 request 参数的 name - BALANCERSESSIONROUTE
这被分配了从当前请求解析的 route。 - BALANCERNAME
这将分配用于当前请求的平衡器的 name。 value 类似于 balancer://foo。 - BALANCERWORKERNAME
这将分配用于当前请求的 worker 的 name。 value 类似于 http://hostA:1234。 - BALANCERWORKERROUTE
这将分配 worker 的 route,用于当前请求。 - BALANCERROUTE_CHANGED
如果 session route 不匹配 worker route(BALANCERSESSIONROUTE!= BALANCERWORKERROUTE)或 session 尚未建立 route,则设置为 1。这可用于确定 when/if 在使用粘性会话时,client 需要发送更新的 route。
启用 Balancer Manager 支持
该模块需要mod_status的服务。 Balancer manager 可以动态更新平衡器成员。您可以使用 balancer manager 更改特定成员的平衡因子,或将其置于 off line 模式。
因此,为了获得负载均衡器 management 的能力,mod_status和mod_proxy_balancer必须存在于服务器中。
要为 example.com 域中的浏览器启用负载均衡器 management,请将此 code 添加到httpd.conf
configuration 文件中
<Location "/balancer-manager"> SetHandler balancer-manager Require host example.com </Location>
您现在可以使用 Web 浏览器访问页面http://your.server.name/balancer-manager
来访问负载均衡器 manager。请注意,只有在<Location ...>
容器之外定义的 Balancers 才能由 Manager 动态控制。
有关负载均衡器粘性的详细信息
使用基于 cookie 的粘性时,需要配置 cookie 的 name,其中包含有关使用哪个 back-end 的信息。这是通过添加到ProxyPass或ProxySet的 stickysession 属性完成的。 cookie 的 name 是 case-sensitive。平衡器提取 cookie 的 value 并查找 route 等于该 value 的成员 worker。 route 也必须设置在ProxyPass或ProxySet中。 cookie 可以由 back-end 设置,也可以由 Apache web 服务器本身在上面的例中设置。
有些 back-ends 使用稍微不同的粘性 cookie 形式,例如 Apache Tomcat。 Tomcat 将 Tomcat 实例的 name 添加到其 session id cookie 的末尾,用 session id 中的点(.
)分隔。因此,如果 Apache web 服务器在粘性 cookie 的 value 中找到一个点,它只使用点后面的部分来搜索 route。为了让 Tomcat 知道它的实例 name,你需要将 Tomcat configuration 文件conf/server.xml
中的属性jvmRoute
设置为连接到相应 Tomcat 的 worker 的 route 的 value。 Tomcat 使用的 session cookie 的 name(更常见的是基于 servlets 的 Java web applications)是JSESSIONID
(大写),但可以配置为其他东西。
实现粘性的第二种方法是 URL 编码。 web 服务器在请求的 URL 中搜索查询参数。使用 stickysession 再次指定参数的 name。参数的 value 用于查找成员 worker,其中 route 等于该 value。由于提取和操作响应中包含的所有 URL 链接并不容易,通常将参数添加到每个链接的工作由生成内容的 back-end 完成。在某些情况下,使用mod_substitute或mod_sed通过 web 服务器执行此操作可能是可行的。这可能会对 performance 产生负面影响。
Java 标准实现的 URL 编码略有不同。它们使用分号(;
)作为分隔符附加到 URL 的路径信息,并添加 session id。与 cookie 案例一样,Apache Tomcat 可以在此路径信息中包含已配置的jvmRoute
。要让 Apache 找到这种路径信息,您需要在ProxyPass或ProxySet中将scolonpathdelim
设置为On
。
最后,您可以在同一 time 支持 cookies 和 URL 编码,方法是配置 cookie 的 name 和由垂直条(|
)分隔的 URL 参数的 name,如下例所示:
ProxyPass "/test" "balancer://mycluster" stickysession=JSESSIONID|jsessionid scolonpathdelim=On <Proxy "balancer://mycluster"> BalancerMember "http://192.168.1.50:80" route=node1 BalancerMember "http://192.168.1.51:80" route=node2 </Proxy>
如果 cookie 和 request 参数都提供相同请求的路由信息,则使用来自请求参数的信息。
解决负载均衡器粘性问题
如果遇到粘性错误,e.g.用户丢失了 application 会话并需要再次登录,首先要检查是否因为 back-ends 有时不可用或者 configuration 是否错误。要了解 back-ends 可能存在的稳定性问题,请检查 Apache 错误 log 是否存在代理错误消息。
要验证您的 configuration,请首先检查粘性是基于 cookie 还是基于 URL 编码。下一步 step 将使用增强的LogFormat loglog 访问 log 中的相应数据。以下字段很有用:
%{MYCOOKIE}C
含有 name MYCOOKIE 的 cookie 中的 value。 name 应该与 stickysession 属性中给出的相同。%{Set-Cookie}o
这会记录 back-end 设置的任何 cookie。你可以跟踪 back-end sets 你期望的 session cookie,以及它设置的 value。%{BALANCER_SESSION_STICKY}e
用于查找路由信息的 cookie 或 request 参数的 name。%{BALANCER_SESSION_ROUTE}e
请求中找到的 route 信息。%{BALANCER_WORKER_ROUTE}e
选择 worker 的 route。%{BALANCER_ROUTE_CHANGED}e
如果请求中的 route 与 worker 的 route 不同,则设置为 1,i.e。请求无法粘贴处理。
失去 session 的常见原因是 session 超时,通常可在 back-end 服务器上配置。
如果 log level 设置为debug
或更高,则平衡器还会将有关处理粘性的详细信息记录到 error log。这是一种解决粘性问题的简单方法,但对于高负载下的 production 服务器,log 卷可能会很高。