Apache Tomcat 作為最流行的 Servlet 容器,其架構設計蘊含豐富的設計模式智慧。本系列分兩部分,第一部分聚焦 總體架構、組件生命周期管理、Connector 請求處理線程模型、Container 容器層級協作,還原 Tomcat 如何高效分發請求、支撐高併發。
Server (生命周期總控)
└─ Service (對外服務單元)
├─ Connector[] (多連接器:HTTP/AJP/HTTPS...)
│ └─ 職責:網絡通信、請求/響應對象構建、線程調度
└─ Container (單容器:Engine)
└─ 職責:Servlet 請求處理、多級子容器管理
關鍵點:
public interface Service {
void addConnector(Connector connector);
void removeConnector(Connector connector);
void setContainer(Container container);
Container getContainer();
String getName();
// 生命周期方法在 Lifecycle 接口中定義
}
StandardService 實現了 Service + Lifecycle + 事件監聽機制,核心邏輯:
setContainer:雙向綁定 Container↔Service,同步綁定到所有 Connector,管理 Container 生命周期。addConnector:雙向綁定 Connector↔Service/Container,動態數組擴容(System.arraycopy 實現類 ArrayList 擴容),初始化並啟動 Connector。StandardServer 管理 Service[] 數組,同樣採用動態擴容數組,實現 Lifecycle 統一啟停所有 Service。Tomcat 5+ 引入 MBeanRegistration 整合 JMX 管理。
public interface Lifecycle {
void start() throws LifecycleException;
void stop() throws LifecycleException;
// 事件監聽
void addLifecycleListener(LifecycleListener listener);
void removeLifecycleListener(LifecycleListener listener);
void fireLifecycleEvent(String type, Object data);
}
設計模式:模板方法模式(定義啟停骨架)+ 觀察者模式(生命周期事件通知)。
public void start() {
if (started) return;
fireLifecycleEvent(BEFORE_START_EVENT, null);
fireLifecycleEvent(START_EVENT, null);
started = true;
for (Service service : services) {
if (service instanceof Lifecycle) ((Lifecycle)service).start(); // 遞歸啟動
}
fireLifecycleEvent(AFTER_START_EVENT, null);
}
public void stop() {
if (!started) return;
fireLifecycleEvent(BEFORE_STOP_EVENT, null);
fireLifecycleEvent(STOP_EVENT, null);
started = false;
for (Service service : services) {
if (service instanceof Lifecycle) ((Lifecycle)service).stop(); // 遞歸停止
}
fireLifecycleEvent(AFTER_STOP_EVENT, null);
}
所有組件(Server/Service/Connector/Container/Valve...)均實現 Lifecycle,形成樹狀生命周期管理,啟動時自頂向下,停止時自底向上。
Connector (對外接口)
└─ Processor (協議處理:Http11Processor)
└─ Protocol (具體協議邏輯)
自定義 Request/Response 隔離 Servlet API,便於協議擴展。
// HttpConnector.start() 創建最小處理器池
while (curProcessors < minProcessors) {
HttpProcessor processor = newProcessor();
recycle(processor); // 放入可用池
}
// HttpProcessor.assign(Socket) - 生產者喚醒消費者
synchronized void assign(Socket socket) {
while (available) wait(); // 等待空閒
this.socket = socket;
available = true;
notifyAll(); // 喚醒 run() 處理
}
// HttpProcessor.run() - 消費者循環
public void run() {
while (!stopped) {
Socket socket = await(); // 從可用池獲取
process(socket); // 解析請求、調用 Container
connector.recycle(this); // 歸還池
}
}
本質:生產者-消費者模式 + 對象池模式。available 旗標充當信號量,wait/notifyAll 實現線程協作。recycle 避免頻繁創建 Processor 對象。
private void process(Socket socket) {
// 1. 輸入流包裝 SocketInputStream
// 2. 解析請求行、Headers
// 3. 構建 Request/Response
// 4. 關鍵調用
if (ok) connector.getContainer().invoke(request, response); // 轉交 Container
// 5. 輸出響應、關閉流
}
| 層級 | 組件 | 職責 | 對應配置 |
|---|---|---|---|
| 1 | Engine | 頂級容器,代表完整 Servlet 引擎,管理多個 Host | <Engine> |
| 2 | Host | 虛擬主機,管理多個 Web 應用,部署/展開 WAR | <Host> |
| 3 | Context | Web 應用上下文,管理 Servlet 實例,解析 web.xml | <Context> |
| 4 | Wrapper | 單個 Servlet 封裝,負責加載、初始化、調用、銷毀 | <servlet> in web.xml |
父子關係:Engine → Host → Context → Wrapper
Pipeline(管道),包含多個 Valve(閥門)server.xml 中可自定義 Valve(如訪問日志、請求傾印)<Engine>
<Valve className="org.apache.catalina.valves.RequestDumperValve"/>
<Host>
<Valve className="org.apache.catalina.valves.FastCommonAccessLogValve" .../>
</Host>
</Engine>
請求處理時序:
所有路由信息存儲在 request 對象中,避免了早期 Mapper 集中式路由的性能瓶頸。
addChild 只接受 Host;setParent 拋異常(頂級無父)。Deployer 接口,負責 WAR 部署/展開/啟動/停止。start():初始化資源、啟動子容器、啟動 Pipeline。backgroundProcess()(後台線程周期調用):reloadable=true 時檢測類文件變更,觸發 reload()(stop→start)熱部署。loadServlet():類加載 → 實例化 → servlet.init() → 可選預載入 service()。ServletConfig 為 StandardWrapperFacade,限制 Servlet 訪問容器信息範圍。StandardWrapperValve:調用 Filter 鏈 → servlet.service()。本文梳理了 Tomcat 的宏觀架構、生命周期體系、Connector 線程模型、Container 四級容器與 Valve/Pipeline 責任鏈。下篇將深入剖析 Tomcat 中經典設計模式的具體應用場景(觀察者、命令、適配器、狀態、外觀等),並結合源碼展示模式如何解決具體架構難題。