Apache HTTP Server 版本 2.4
描述 | mod_proxy 用于负载均衡的扩展 |
---|---|
状态 | 扩展 |
模块标识符 | proxy_balancer_module |
源文件 | mod_proxy_balancer.c |
兼容性 | 在 2.1 及更高版本中可用 |
此模块需要mod_proxy
的服务,它为所有支持的协议提供负载均衡。最重要的协议是
mod_proxy_http
mod_proxy_ftp
mod_proxy_ajp
mod_proxy_wstunnel
负载均衡调度算法不是由此模块提供,而是由其他模块提供,例如
因此,为了获得负载均衡的能力,mod_proxy
、mod_proxy_balancer
以及至少一个负载均衡调度算法模块必须存在于服务器中。
在您保护您的服务器之前,请勿启用代理。开放代理服务器对您的网络和整个互联网都存在危险。
目前,有 4 种负载均衡器调度算法可供使用:请求计数 (mod_lbmethod_byrequests
)、加权流量计数 (mod_lbmethod_bytraffic
)、待处理请求计数 (mod_lbmethod_bybusyness
) 和心跳流量计数 (mod_lbmethod_heartbeat
)。这些通过负载均衡器定义的 lbmethod
值进行控制。有关更多信息,请参阅 ProxyPass
指令,尤其是关于如何配置负载均衡器和负载均衡器成员的信息。
负载均衡器支持粘性。当请求被代理到某个后端时,来自同一用户的后续所有请求都应该被代理到同一个后端。许多负载均衡器通过一个将客户端 IP 地址映射到后端的表来实现此功能。这种方法对客户端和后端是透明的,但存在一些问题:如果客户端本身隐藏在代理后面,则负载分配不均;如果客户端使用在会话期间更改的动态 IP 地址,则粘性错误;如果映射表溢出,则粘性丢失。
模块 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 或请求参数的名称
这被分配给从当前请求解析的 route。
这被分配给当前请求使用的负载均衡器的名称。该值类似于 balancer://foo
。
这被分配给当前请求使用的工作者的名称。该值类似于 http://hostA:1234
。
这被分配给将用于当前请求的工作者的 route。
如果会话路由与工作者路由不匹配 (BALANCER_SESSION_ROUTE != BALANCER_WORKER_ROUTE) 或会话还没有建立路由,则将其设置为 1。这可以用来确定何时/是否需要在使用粘性会话时向客户端发送更新的路由。
此模块需要mod_status
的服务。负载均衡器管理器允许动态更新负载均衡器成员。您可以使用负载均衡器管理器更改特定成员的平衡因子,或将其置于离线模式。
因此,为了获得负载均衡器管理的能力,mod_status
和 mod_proxy_balancer
必须存在于服务器中。
要为来自 example.com 域的浏览器启用负载均衡器管理,请将以下代码添加到您的 httpd.conf
配置文件中
<Location "/balancer-manager"> SetHandler balancer-manager Require host example.com </Location>
现在,您可以使用 Web 浏览器访问页面 http://your.server.name/balancer-manager
来访问负载均衡器管理器。请注意,只有在 <Location ...>
容器之外定义的负载均衡器才能由管理器动态控制。
使用基于 cookie 的粘性时,您需要配置包含有关使用哪个后端的信息的 cookie 的名称。这通过添加到 ProxyPass
或 ProxySet
的 stickysession 属性完成。cookie 的名称区分大小写。负载均衡器提取 cookie 的值,并查找 route 等于该值的成员工作者。 route 也必须在 ProxyPass
或 ProxySet
中设置。cookie 可以由后端设置,也可以如上面的 示例 中所示由 Apache Web 服务器本身设置。
一些后端使用稍微不同的粘性 cookie 形式,例如 Apache Tomcat。Tomcat 将 Tomcat 实例的名称添加到其会话 ID cookie 的末尾,用一个点 (.
) 与会话 ID 分隔。因此,如果 Apache Web 服务器在粘性 cookie 的值中找到一个点,它只使用点后面的部分来搜索路由。为了让 Tomcat 知道其实例名称,您需要在 Tomcat 配置文件 conf/server.xml
中将属性 jvmRoute
设置为连接到相应 Tomcat 的工作者的 route 的值。Tomcat(更普遍地,基于 servlet 的 Java Web 应用程序)使用的会话 cookie 的名称是 JSESSIONID
(大写),但可以配置为其他名称。
实现粘性的第二种方法是 URL 编码。Web 服务器在请求的 URL 中搜索查询参数。参数的名称再次使用 stickysession 指定。参数的值用于查找 route 等于该值的成员工作者。由于提取和操作响应中包含的所有 URL 链接并不容易,因此通常由生成内容的后端完成向每个链接添加参数的工作。在某些情况下,可以使用 mod_substitute
或 mod_sed
通过 Web 服务器完成此操作。但这会对性能产生负面影响。
Java 标准以略微不同的方式实现 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 和请求参数都为同一个请求提供路由信息,则使用来自请求参数的信息。
如果您遇到粘性错误,例如用户丢失了应用程序会话并需要重新登录,您首先要检查这是否是由于后端有时不可用,还是您的配置错误。要了解后端可能存在的稳定性问题,请检查您的 Apache 错误日志以查找代理错误消息。
要验证您的配置,首先检查粘性是基于 cookie 还是基于 URL 编码。下一步是使用增强的 LogFormat
在访问日志中记录相应的数据。以下字段很有用
%{MYCOOKIE}C
MYCOOKIE
的 cookie 中的值。名称应与 stickysession 属性中给出的名称相同。%{Set-Cookie}o
%{BALANCER_SESSION_STICKY}e
%{BALANCER_SESSION_ROUTE}e
%{BALANCER_WORKER_ROUTE}e
%{BALANCER_ROUTE_CHANGED}e
1
。会话丢失的常见原因是会话超时,这通常可以在后端服务器上配置。
如果日志级别设置为debug
或更高,负载均衡器还会将有关处理粘性的详细信息记录到错误日志中。这是一种解决粘性问题的好方法,但对于高负载生产服务器来说,日志量可能过高。