Apache 模块 mod_proxy_balancer

Description: mod_proxy扩展以实现负载平衡
Status: Extension
Module Identifier: proxy_balancer_module
Source File: mod_proxy_balancer.c
Compatibility: 在 2.1 版和更高版本中可用

Summary

该模块需要 mod_proxy的服务,并且它为所有受支持的协议提供负载平衡。最重要的是:

此模块未提供负载平衡调度程序算法,而是由其他算法提供的,例如:

因此,为了获得负载平衡的能力,服务器中必须存在mod_proxymod_proxy_balancer和至少一个负载平衡调度程序算法模块。

Warning

在拥有保护您的服务器之前,不要启用代理。开放式代理服务器对您的网络和整个 Internet 都是危险的。

负载均衡器调度程序算法

当前,有 4 种负载均衡器调度程序算法可供使用:请求计数(mod_lbmethod_byrequests),加权流量计数(mod_lbmethod_bytraffic),待处理请求计数(mod_lbmethod_bybusyness)和心跳流量计数(mod_lbmethod_heartbeat)。这些是通过 Balancer 定义的lbmethod值控制的。有关更多信息,请参见ProxyPass指令,尤其是有关如何配置 Balancer 和 BalancerMembers 的信息。

负载均衡器的粘性

平衡器支持粘性。当请求被代理到某个后端时,则来自同一用户的所有后续请求都应被代理到同一后端。许多负载均衡器通过将 Client 端 IP 地址 Map 到后端的表来实现此功能。这种方法对 Client 端和后端透明,但存在一些问题:如果 Client 端自身隐藏在代理之后,负载分配将不相等;如果 Client 端使用在会话期间发生变化的动态 IP 地址,则会出现粘性错误;如果 Client 端无法使用,则会丢失粘性。Map 表溢出。

mod_proxy_balancer模块在两种替代方式之上实现了粘性:Cookie 和 URL 编码。提供 cookie 既可以由后端完成,也可以由 Apache Web 服务器本身完成。 URL 编码通常在后端进行。

平衡器配置示例

在深入探讨技术细节之前,这里有一个示例,说明如何使用mod_proxy_balancer在两个后端服务器之间提供负载平衡:

<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"

关于如何使用mod_headers提供具有粘性的负载平衡的另一个示例,即使后端服务器未设置合适的会话 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 个环境变量:

启用 Balancer Manager 支持

该模块需要 mod_status的服务。平衡器 Management 器可以动态更新平衡器成员。您可以使用 Balancer Manager 更改特定成员的平衡因子,或将其置于离线模式。

因此,为了获得负载平衡器 Management 的能力,服务器中必须存在mod_statusmod_proxy_balancer

要为来自 example.com 域的浏览器启用负载均衡器 Management,请将此代码添加到您的httpd.conf配置文件中

<Location "/balancer-manager">
    SetHandler balancer-manager
    Require host example.com
</Location>

现在,您可以使用 Web 浏览器访问页面http://your.server.name/balancer-manager来访问负载平衡器 Management 器。请注意,Manager 只能动态控制<Location ...>容器之外定义的平衡器。

有关负载均衡器粘性的详细信息

使用基于 cookie 的粘性时,您需要配置 cookie 的名称,其中包含有关使用哪个后端的信息。这可以通过添加到ProxyPassProxySet的 stickysession 属性来完成。 Cookie 的名称区分大小写。平衡器提取 cookie 的值,并查找路由等于该值的成员 worker。还必须在ProxyPassProxySet中设置路由。 Cookie 可以由后端设置,也可以由 Apache Web 服务器本身如上example所示设置。

某些后端使用粘性 Cookie 的形式略有不同,例如 Apache Tomcat。 Tomcat 将 Tomcat 实例的名称添加到其会话 ID cookie 的末尾,并在会话 ID 中以点(.)分隔。因此,如果 Apache Web 服务器在粘性 cookie 的值中找到一个点,则仅使用该点后面的部分来搜索路由。为了让 Tomcat 知道其实例名称,您需要将 Tomcat 配置文件conf/server.xml内的属性jvmRoute设置为连接到相应 Tomcat 的辅助程序的路由值。 Tomcat(更常见的是基于 servlet 的 Java Web 应用程序)使用的会话 cookie 的名称为JSESSIONID(大写),但可以配置为其他名称。

实现粘性的第二种方法是 URL 编码。 Web 服务器在请求的 URL 中搜索查询参数。使用 stickysession 再次指定参数的名称。该参数的值用于查找路由等于该值的成员 worker。由于提取和处理响应中包含的所有 URL 链接并不容易,因此通常将参数添加到每个链接的工作是由后端生成内容来完成的。在某些情况下,使用mod_substitutemod_sed通过 Web 服务器执行此操作可能是可行的。但是,这可能会对性能产生负面影响。

Java 标准实现的 URL 编码略有不同。他们使用以分号(;)作为分隔符的 URL 信息附加到 URL,并在后面添加会话 ID。与 cookie 一样,Apache Tomcat 可以在此路径信息中包含配置的jvmRoute。为了让 Apache 找到这种路径信息,您需要在ProxyPassProxySet中将scolonpathdelim设置为On

最后,通过配置 Cookie 的名称和用竖线(|)分隔的 URL 参数的名称,您可以同时支持 cookie 和 URL 编码,如以下示例所示:

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 参数都提供同一请求的路由信息,则使用来自 request 参数的信息。

解决负载均衡器粘性问题

如果您遇到粘性错误,例如用户丢失了应用程序会话并需要再次登录,您首先要检查这是因为后端有时不可用还是您的配置错误。要找出后端可能存在的稳定性问题,请检查 Apache 错误日志中是否存在代理错误消息。

要验证您的配置,请首先检查粘性是基于 Cookie 还是基于 URL 编码。下一步将使用增强的LogFormat将适当的数据记录在访问日志中。以下字段很有用:

丢失会话的常见原因是会话超时,通常可以在后端服务器上对其进行配置。

如果日志级别设置为debug或更高,则平衡器还将有关处理粘性的详细信息记录到错误日志中。这是解决粘性问题的简便方法,但是对于高负载下的生产服务器,日志量可能很高。

首页