负载均衡器是一个不直接与 Tomcat 通信的工作者。相反,它负责管理多个“真实”工作者,这些工作者被称为负载均衡器的成员或子工作者。
这种管理包括
- 在 Web 服务器中实例化工作者。
- 使用工作者的负载均衡因子,执行加权负载均衡(根据目标定义的强度分配负载)。
- 保持属于同一会话的请求在同一个 Tomcat 上执行(会话粘性)。
- 识别故障的 Tomcat 工作者,暂停对它们的请求,并在负载均衡器管理的其他工作者上进行故障转移。
- 通过状态工作者接口提供负载均衡器本身和所有成员的状态和负载指标。
- 允许通过状态工作者接口动态重新配置负载均衡。
由同一个负载均衡器工作者管理的工作者是负载均衡的(基于它们配置的均衡因子和当前请求或会话负载),并且还通过提供对同一负载均衡器其他成员的故障转移来防止故障。因此,单个 Tomcat 进程死亡不会“杀死”整个站点。
负载均衡器提供的一些功能即使在只使用单个成员工作者(负载均衡不可行)的情况下也是很有趣的。
基本负载均衡器属性
通过将工作程序的 type
设置为 lb,可以将工作程序配置为负载均衡器。
下表指定了一些用于配置负载均衡器工作程序的属性
- balance_workers 是负载均衡器成员工作程序名称的逗号分隔列表。这些工作程序通常类型为 ajp13。成员工作程序不需要出现在
worker.list
属性中,将负载均衡器添加到其中就足够了。 - sticky_session 指定是否应将具有 SESSION ID 的请求路由回创建该会话的同一 Tomcat 实例。当 Tomcat 使用可以跨多个 Tomcat 实例共享会话数据的会话管理器时,或者当您的应用程序是无状态时,您可以将 sticky_session 设置为 false。默认情况下,sticky_session 设置为 true。
- lbfactor 可以添加到每个成员工作程序中,以配置成员的个体强度。较高的
lbfactor
将导致更多请求被均衡到该工作程序。因子必须由整数给出,负载将按给定的因子比例分配。较高的因子会导致更多请求。
# The load balancer worker balance1 will distribute
# load to the members worker1 and worker2
worker.balance1.type=lb
worker.balance1.balance_workers=worker1, worker2
worker.worker1.type=ajp13
worker.worker1.host=myhost1
worker.worker1.port=8009
worker.worker2.type=ajp13
worker.worker1.host=myhost2
worker.worker1.port=8009
jvmRoute
属性的值设置为 Tomcat 实例的名称。Tomcat 的名称需要与相应的负载均衡器成员的名称相同。在上面的示例中,主机“myhost1”上的 Tomcat 需要 jvmRoute="worker1"
,主机“myhost2”上的 Tomcat 需要 jvmRoute="worker2"
。
有关所有负载均衡器配置属性的完整参考,请参阅工作程序 参考。
高级负载均衡器工作程序属性
负载均衡器支持复杂的拓扑结构和故障转移配置。使用成员属性 distance
,您可以对成员进行分组。负载均衡器将始终将请求发送到距离最小的成员。只有当所有这些成员都出现故障时,它才会均衡到配置的下一个更高距离的成员。这允许在不同数据中心位置的 Tomcat 实例之间定义优先级。
在使用共享会话时,无论是通过使用会话复制还是持久会话管理器(例如,通过数据库),通常会将 Tomcat 集群分成复制组。如果成员出现故障,负载均衡器需要知道哪些其他成员共享会话。这使用 domain
属性进行配置。所有具有相同域的工作程序都被认为共享会话。
出于维护目的,您可以告诉负载均衡器不允许在某些成员上建立任何新会话,甚至完全不使用它们。这由成员属性activation
控制。值Active允许正常使用成员,disabled将不会在其上创建新会话,但仍允许粘性请求,而stopped将不再向成员发送任何请求。在维护之前的一段时间内将激活从“active”切换到“disabled”将耗尽工作程序上的会话并最大程度地减少中断。根据应用程序的使用模式,耗尽将花费从几分钟到几小时的时间。在维护之前立即将工作程序切换到停止将减少 mod_jk 记录错误日志。
最后,您还可以通过将activation
设置为disabled并结合其他工作程序的redirect
属性来配置热备用工作程序。
# The advanced router LB worker
worker.list=router
worker.router.type=lb
worker.router.balance_workers=worker1,worker2
# Define the first member worker
worker.worker1.type=ajp13
worker.worker1.host=myhost1
worker.worker1.port=8009
# Define preferred failover node for worker1
worker.worker1.redirect=worker2
# Define the second member worker
worker.worker2.type=ajp13
worker.worker2.host=myhost2
worker.worker2.port=8009
# Disable worker2 for all requests except failover
worker.worker2.activation=disabled
worker1 上的redirect
标志告诉负载均衡器在 worker1 出现问题时将请求重定向到 worker2。在所有其他情况下,worker2 不会收到任何请求,因此充当热备用。
关于将activation
设置为disabled的最后说明:与请求一起发送的会话 ID 作为请求 URL 的一部分(;jsessionid=...
)或通过 cookie 发送。当使用书签或长时间运行的浏览器时,可能会发送带有指向已禁用成员的旧且无效会话 ID 的请求。由于负载均衡器没有有效会话列表,因此它会将请求转发到已禁用的成员。因此,耗尽时间比预期更长。为了处理此类情况,您可以在 Web 应用程序中添加一个 Servlet 过滤器,该过滤器检查请求属性JK_LB_ACTIVATION
。此属性包含字符串“ACT”、“DIS”或“STP”之一。如果您检测到“DIS”并且请求的会话不再活动,请删除会话 cookie 并使用自引用 URL 重定向。然后,重定向的请求将不再携带会话信息,因此负载均衡器不会将其发送到已禁用的工作程序。请求属性JK_LB_ACTIVATION
已在 1.2.32 版本中添加。
状态工作程序属性
状态工作程序不与 Tomcat 通信。相反,它负责工作程序管理。当与负载均衡器工作程序结合使用时,它特别有用。
# Add the status worker to the worker list
worker.list=jkstatus
# Define a 'jkstatus' worker using status
worker.jkstatus.type=status
接下来是将请求挂载到 jkstatus 工作程序。对于 Apache HTTP 服务器,请使用
# Add the jkstatus mount point
JkMount /jkmanager/* jkstatus
为了获得更高级别的安全性,请使用
# Enable the JK manager access from localhost only
<Location /jkmanager/>
JkMount jkstatus
Require ip 127.0.0.1
</Location>