工作者操作指南

简介

Tomcat 工作者是一个 Tomcat 实例,它正在等待代表某个 Web 服务器执行 Servlet。例如,我们可以有一个像 Apache HTTP 服务器这样的 Web 服务器,它将 Servlet 请求转发到运行在其后面的 Tomcat 进程(工作者)。

上面描述的场景非常简单;事实上,可以配置多个 Tomcat 工作者来代表某个 Web 服务器提供 Servlet 服务。进行这种配置的原因可能是

  • 我们希望不同的上下文由不同的 Tomcat 工作者提供服务,以提供一个开发环境,其中所有开发人员共享同一个 Web 服务器,但拥有自己的 Tomcat 工作者。
  • 我们希望不同的虚拟主机由不同的 Tomcat 进程提供服务,以在属于不同公司的站点之间提供清晰的分隔。
  • 我们希望提供负载均衡,这意味着运行多个 Tomcat 工作者,每个工作者都在自己的机器上运行,并在它们之间分配请求。

可能还有更多拥有多个工作者的原因,但我认为这个列表已经足够了……Tomcat 工作者是在一个名为 workers.properties 的属性文件中定义的,本教程将解释如何使用它。

本文档最初是Tomcat:最小用户指南的一部分,由 Gal Shachor 编写,但出于组织原因已拆分出来。

定义工作者

可以使用属性文件(conf/目录中有一个名为 workers.properties 的示例文件)将工作者定义到 Tomcat Web 服务器插件中。

该文件包含以下形式的条目

worker.list=<以逗号分隔的工作者名称列表>

# the list of workers
worker.list= worker1, worker2

启动时,Web 服务器插件将实例化其名称出现在worker.list属性中的工作者,这些也是您可以将请求映射到的工作者。该指令可以多次使用。

工作者类型

每个命名工作者还应包含一些条目,以提供有关其自身的附加信息。这些信息包括工作者的类型和其他相关工作者信息。目前存在的以下工作者类型(JK 1.2.5)

类型描述
ajp13此工作者知道如何使用 ajp13 协议将请求转发到进程外 Tomcat 工作者。
lb这是一个负载均衡工作者;它知道如何提供一定程度的容错的灵活负载均衡。
status这是一个用于管理负载均衡器的状态工作者。
ajp12此工作者知道如何使用 ajp12 协议将请求转发到进程外 Tomcat 工作者。它已弃用
ajp14此工作者知道如何使用 ajp14 协议将请求转发到进程外 Tomcat 工作者。它处于实验阶段

定义特定类型的 worker 应使用以下属性格式

worker.worker name.type=<worker type> 其中 worker name 是分配给 worker 的名称,worker type 是表中定义的四种类型之一(worker name 只能包含任何空格字符 [a-zA-Z0-9\-_])。

# Defines a worker named "local" that uses the ajp12 protocol to forward requests to a Tomcat process.
worker.local.type=ajp12
# Defines a worker named "remote" that uses the ajp13 protocol to forward requests to a Tomcat process.
worker.remote.type=ajp13
# Defines a worker named "loadbalancer" that loadbalances several Tomcat processes transparently.
worker.loadbalancer.type=lb

设置工作者属性

定义工作者后,您还可以为它们指定属性。属性可以以以下方式指定

worker.<worker name>.<property>=<property value>

每个工作者都有一组可以设置的属性,如以下小节中所述

ajp12 工作者属性

工作者类型ajp12弃用,您应该改用ajp13

ajp12 类型的 worker 使用 ajp12 协议通过 TCP/IP 套接字将请求转发到进程外 Tomcat worker。它不使用持久连接。

ajp12 工作者属性为

host 属性设置 Tomcat worker 监听 ajp12 请求的主机。

port 属性设置 Tomcat worker 监听 ajp12 请求的端口

lbfactor 属性在与负载均衡工作者一起工作时使用,这是工作者的负载均衡因子。我们将在负载均衡工作者部分中详细介绍。

# worker "worker1" will talk to Tomcat listening on machine www.x.com at port 8007 using 2 lb factor
worker.worker1.type=ajp12
worker.worker1.host=www.x.com
worker.worker1.port=8007
worker.worker1.lbfactor=2

注意:ajp12 的默认端口为 8007

ajp13 工作者属性

ajp13 类型的 worker 使用 ajp13 协议通过 TCP/IP 套接字将请求转发到进程外的 Tomcat worker。ajp12 和 ajp13 之间的主要区别在于

  • ajp13 是一个更二进制的协议,它试图通过将常用字符串编码为小整数来压缩一些请求数据。
  • ajp13 重用打开的套接字,并将它们保持打开状态以供将来请求使用(请记住,当您的 Web 服务器和 Tomcat 之间有防火墙时)。
  • ajp13 对 SSL 信息有特殊处理,以便容器可以实现与 SSL 相关的 method,例如 isSecure()。

请注意,ajp13 是连接到 Tomcat 的推荐协议。

# worker "worker2" will talk to Tomcat listening on machine www2.x.com at port 8009 using 3 lb factor
worker.worker2.type=ajp13
worker.worker2.host=www2.x.com
worker.worker2.port=8009
worker.worker2.lbfactor=3
# worker "worker2" uses connections, which will stay no more than 10mn in the connection pool
worker.worker2.connection_pool_timeout=600
# worker "worker2" ask operating system to send KEEP-ALIVE signal on the connection
worker.worker2.socket_keepalive=1
# mount can be used as an alternative to the JkMount directive
worker.worker2.mount=/contexta /contexta/* /contextb /contextb/*

注意:在 ajp13 协议中,默认端口为 8009

lb Worker 属性

负载均衡 worker 并不真正与 Tomcat worker 通信。相反,它负责管理多个“真实” worker。这种管理包括

  • 在 Web 服务器中实例化 worker。
  • 使用 worker 的负载均衡因子,执行加权轮询负载均衡,其中较高的 lbfactor 表示更强大的机器(将处理比例更多的请求)。
  • 保持属于同一会话的请求在同一个 Tomcat worker 上执行(会话粘性)。
  • 识别失败的 Tomcat worker,暂停对其的请求,并在 lb worker 管理的其他 worker 上进行故障转移。

总体结果是,由同一个 lb worker 管理的 worker 是负载均衡的(基于它们的 lbfactor 和当前用户会话),并且还会发生故障转移,因此单个 Tomcat 进程死亡不会“杀死”整个站点。下表指定了 lb worker 可以接受的一些属性

  • balance_workers 是负载均衡器需要管理的 worker 的逗号分隔列表。只要这些 worker 应该只通过负载均衡器 worker 使用,就没有必要将它们也放入 worker.list 属性中。此指令可以多次用于同一个负载均衡器。
  • sticky_session 指定了是否将带有 SESSION ID 的请求路由回同一个 Tomcat 工作器。当 Tomcat 使用可以跨多个 Tomcat 实例持久化会话数据的会话管理器时,将 sticky_session 设置为 false。默认情况下,sticky_session 设置为 true

# The worker balance1 while use "real" workers worker1 and worker2
worker.balance1.balance_workers=worker1, worker2

状态工作器属性

状态工作器不与 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>

属性文件宏

您可以在属性文件中定义“宏”。这些宏允许您定义属性,并在以后构建其他属性时使用它们。

# property example, like a network base address
mynet=194.226.31
# Using the above macro to simplify the address definitions
# for a farm of workers.
worker.node1.host=$(mynet).11
worker.node2.host=$(mynet).12
worker.node3.host=$(mynet).13

分层属性配置

工作器可以引用其他工作器的配置。如果工作器“x”引用工作器“y”,则它会继承“y”的所有配置参数,除了明确为“x”设置的参数。

# worker toe defines some default settings
worker.toe.type=ajp13
worker.toe.socket_keepalive=true
worker.toe.connect_timeout=10000
worker.toe.recovery_options=7
# workers tic and tac inherit those values
worker.tic.reference=worker.toe
worker.tac.reference=worker.toe

请注意,引用包含对引用配置属性的完整前缀,而不仅仅是引用工作器的名称。

引用可以嵌套,最大深度为 20。注意避免循环!

对于单个工作器允许多次出现的属性不能从工作器和引用中合并。属性仅从引用继承,如果它尚未为引用工作器设置。

引用在配置负载均衡器时特别有用。尝试理解以下两级引用

# We only use one load balancer
worker.list=lb
# Let's define some defaults
worker.basic.port=8009
worker.basic.type=ajp13
worker.basic.socket_keepalive=true
worker.basic.connect_timeout=10000
worker.basic.recovery_options=7
# And we use them in two groups
worker.lb1.domain=dom1
worker.lb1.distance=0
worker.lb1.reference=worker.basic
worker.lb2.domain=dom2
worker.lb2.distance=1
worker.lb2.reference=worker.basic
# Now we configure the load balancer
worker.lb.type=lb
worker.lb.method=B
worker.lb.balanced_workers=w11,w12,w21,w22
worker.w11.host=myhost11
worker.w11.reference=worker.lb1
worker.w12.host=myhost12
worker.w12.reference=worker.lb1
worker.w21.host=myhost21
worker.w21.reference=worker.lb2
worker.w22.host=myhost22
worker.w22.reference=worker.lb2

一个示例 worker.properties

由于自己处理 worker.properties 并不容易,因此 JK 附带了一个示例 worker.properties 文件。

您也可以在这里找到一个示例 workers.properties 文件,它定义了

  • 两个使用主机 localhost 和端口 8109 和 8209 的 ajp13 工作器
  • 一个在两个 ajp13 工作器上进行负载均衡的 lb 工作器
# Define 3 workers, 2 real workers using ajp13, and one being a load balancing worker 
worker.list=node1, node2, lbworker
# Set properties for node1 (ajp13)
worker.node1.type=ajp13
worker.node1.host=localhost
worker.node1.port=8109
worker.node1.connection_pool_timeout=600
worker.node1.socket_keepalive=1
# Set properties for node2 (ajp13)
worker.node2.type=ajp13
worker.node2.host=localhost
worker.node2.port=8209
worker.node2.connection_pool_timeout=600
worker.node2.socket_keepalive=1
# Set properties for lbworker which uses node1 and node2
worker.lbworker.type=lb
worker.lbworker.balance_workers=node1,node2