工作器指南

简介

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

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

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

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

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

定义工作器

可以使用属性文件(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.工作器名称.type=<工作器类型> 其中工作器名称是分配给工作器的名称,工作器类型是表中定义的四种类型之一(工作器名称只能包含字符 [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 类型的工作器使用 ajp12 协议通过 TCP/IP 套接字将请求转发到进程外 Tomcat 工作器。它不使用持久连接。

ajp12 工作器属性有:

host 属性设置 Tomcat 工作器监听 ajp12 请求的主机。

port 属性设置 Tomcat 工作器监听 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 类型的工作器使用 ajp13 协议通过 TCP/IP 套接字将请求转发到进程外 Tomcat 工作器。ajp12 和 ajp13 之间的主要区别在于:

  • ajp13 是一种更二进制化的协议,它尝试通过将常用字符串编码为小整数来压缩部分请求数据。
  • ajp13 重用开放套接字并使其保持开放以处理未来的请求(请记住当您的 Web 服务器和 Tomcat 之间有防火墙时)。
  • ajp13 对 SSL 信息有特殊处理,以便容器可以实现与 SSL 相关的方法,例如 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 工作器属性

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

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

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

  • balance_workers 是负载均衡器需要管理的以逗号分隔的工作器列表。只要这些工作器只应通过负载均衡工作器使用,就不需要将它们也放入 worker.list 属性中。此指令可以为同一个负载均衡器多次使用。
  • sticky_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