On this page
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的服务,并且它为所有受支持的协议提供负载平衡。最重要的是:
HTTP,使用mod_proxy_http
FTP,使用mod_proxy_ftp
AJP13,使用mod_proxy_ajp
WebSocket,使用mod_proxy_wstunnel
此模块未提供负载平衡调度程序算法,而是由其他算法提供的,例如:
因此,为了获得负载平衡的能力,服务器中必须存在mod_proxy,mod_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 个环境变量:
-
- 为该请求分配用于当前请求的 stickysession 值。它是用于粘性会话的 cookie 或请求参数的名称
-
- 分配了从当前请求中解析出的路由。
-
- 为当前请求分配了平衡器的名称。该值类似于
balancer://foo
。
- 为当前请求分配了平衡器的名称。该值类似于
-
- 分配给当前请求使用的工作程序的名称。该值类似于
http://hostA:1234
。
- 分配给当前请求使用的工作程序的名称。该值类似于
-
- 这分配了将用于当前请求的工作程序的路由。
-
- 如果会话路由与工作路由不匹配(BALANCER_SESSION_ROUTE!= BALANCER_WORKER_ROUTE)或会话尚未构建的路由,则将其设置为 1.这可用于确定使用粘性会话时何时/是否需要向 Client 端发送更新的路由。
启用 Balancer Manager 支持
该模块需要 mod_status的服务。平衡器 Management 器可以动态更新平衡器成员。您可以使用 Balancer Manager 更改特定成员的平衡因子,或将其置于离线模式。
因此,为了获得负载平衡器 Management 的能力,服务器中必须存在mod_status和mod_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 的名称,其中包含有关使用哪个后端的信息。这可以通过添加到ProxyPass或ProxySet的 stickysession 属性来完成。 Cookie 的名称区分大小写。平衡器提取 cookie 的值,并查找路由等于该值的成员 worker。还必须在ProxyPass或ProxySet中设置路由。 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_substitute或mod_sed通过 Web 服务器执行此操作可能是可行的。但是,这可能会对性能产生负面影响。
Java 标准实现的 URL 编码略有不同。他们使用以分号(;
)作为分隔符的 URL 信息附加到 URL,并在后面添加会话 ID。与 cookie 一样,Apache Tomcat 可以在此路径信息中包含配置的jvmRoute
。为了让 Apache 找到这种路径信息,您需要在ProxyPass或ProxySet中将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将适当的数据记录在访问日志中。以下字段很有用:
%{MYCOOKIE}C
- Cookie 中名称为
MYCOOKIE
的值。名称应与 stickysession 属性中提供的名称相同。
- Cookie 中名称为
%{Set-Cookie}o
- 这将记录后端设置的所有 cookie。您可以跟踪后端是否设置了期望的会话 cookie,以及将其设置为哪个值。
%{BALANCER_SESSION_STICKY}e
- 用于查找路由信息的 cookie 或 request 参数的名称。
%{BALANCER_SESSION_ROUTE}e
- 在请求中找到的 Route 信息。
%{BALANCER_WORKER_ROUTE}e
- 选择的 Worker 的 Route。
%{BALANCER_ROUTE_CHANGED}e
- 如果请求中的路由与工作方的路由不同,则设置为
1
,即无法将请求粘性处理。
- 如果请求中的路由与工作方的路由不同,则设置为
丢失会话的常见原因是会话超时,通常可以在后端服务器上对其进行配置。
如果日志级别设置为debug
或更高,则平衡器还将有关处理粘性的详细信息记录到错误日志中。这是解决粘性问题的简便方法,但是对于高负载下的生产服务器,日志量可能很高。