Workers HowTo

簡介

Tomcat 工作器是 Tomcat 執行個體,用於代表某些 Web 伺服器執行 servlet。例如,我們可以讓 Web 伺服器(例如 Apache HTTP Server)將 servlet 要求轉發到在它後方執行的 Tomcat 程序(工作器)。

上述情境非常簡單;事實上,可以設定多個 Tomcat 工作器來代表特定 Web 伺服器提供 servlet 服務。此類設定的理由可能是

  • 我們希望不同的工作器提供不同的內容,以提供開發環境,讓所有開發人員共用同一 Web 伺服器,但擁有自己的 Tomcat 工作器。
  • 我們希望不同的虛擬主機由不同的 Tomcat 程序提供服務,以清楚區分屬於不同公司的網站。
  • 我們希望提供負載平衡,也就是在每台機器上執行多個 Tomcat 工作器,並在它們之間分配要求。

可能還有更多理由需要多個工作器,但我猜這份清單已經足夠了...Tomcat 工作器定義在稱為 workers.properties 的屬性檔中,本教學說明如何使用它。

這份文件最初是 Gal Shachor 所寫的Tomcat:極簡使用者指南的一部分,但出於組織原因而分開。

定義工作器

透過屬性檔案定義 Tomcat 網路伺服器外掛程式中的工作人員(範例檔案 workers.properties 可在 conf/ 目錄中取得)。

檔案包含下列格式的項目

worker.list=<以逗號分隔的工作人員名稱清單>

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

啟動時,網路伺服器外掛程式會建立名稱出現在 worker.list 屬性中的工作人員,這些工作人員也是您可以對應要求的工作人員。此指令可用於多次。

工作人員類型

每個已命名的工作人員也應該有幾個項目提供額外的相關資訊。此資訊包括工作人員的類型和其他相關工作人員資訊。目前存在的下列工作人員類型(JK 1.2.5)

類型說明
ajp13此工作人員知道如何使用 ajp13 協定將要求轉送至外部處理的 Tomcat 工作人員。
lb這是負載平衡工作人員;它知道如何提供具有一定容錯程度的彈性負載平衡。
status這是管理負載平衡器的狀態工作人員。
ajp12此工作人員知道如何使用 ajp12 協定將要求轉送至外部處理的 Tomcat 工作人員。此協定已棄用。
ajp14此工作人員知道如何使用 ajp14 協定將要求轉送至外部處理的 Tomcat 工作人員。此協定為實驗性質。

定義特定類型的工作人員應使用下列屬性格式

worker.worker name.type=<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 型工作人員透過 TCP/IP Socket 上的 ajp12 協定,將要求轉發至 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 型工作人員透過 TCP/IP Socket 上的 ajp13 協定,將要求轉發至 Tomcat 工作人員。ajp12 和 ajp13 之間的主要差異在於

  • ajp13 是更二進位的協定,它會嘗試透過將經常使用的字串編碼為小整數,來壓縮一些要求資料。
  • ajp13 會重複使用開啟的 Socket,並將其保留為未來要求使用(請記住,當您的網路伺服器和 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 工作人員通訊。相反地,它負責管理多個「真實」工作人員。此管理包括

  • 在網路伺服器中實例化工作人員。
  • 使用工作人員的負載平衡係數,執行加權循環負載平衡,其中較高的 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