這段時間簡單的看了一下Tomcat的源碼,在這里做個筆記!
1. tomcat 架構圖
Catalina: tomcat的頂級容器,main()方法中就是通過,創建Catalina 對象實例,來啟動或者關閉 tomcat;
Server: 是管理tomcat所有組件的容器,包含一個或多個的service;
Service: Service是包含Connector和Container的集合,Service用適當的Connector接收用戶的請求,再發給相應的Container來處理;
Connector: 主要功能是 ◇socket的接收 ◇根據協議類型處理socket ◇封裝相應的request和response,交給Container;
Container: Engine容器接收來自Connector的請求,並且通過Pipeline依次傳遞給子容器的Pipeline;
Engine: 在Engine的Pipeline中的Valve的invoke方法中,根據request.getHost()來定位下一個host;
Host: 一個Web服務器虛擬機,管理着具體的 web application;
Context: 就是我們所部屬的具體Web應用的上下文,每個請求都是在具體的上下文中處理;
Wrapper:對應着Web的每一個 Servlet;
接下來,主要學習tomcat中的兩個最主要的容器,Connector和Container容器。
2. Connector容器
Connector容器主要解決的問題就是Socket的接收,為了能夠很好的處理各種協議和並發異步接收,Connector加入了兩個組件 ProtocolHandler和EndPoint。
ProtocolHandler的主要作用就是根據各個協議的定義按照一定的格式句分析協議頭,封裝成request和response對象;
AbstractEndPoint 致力於高並發的解決socket的接收和處理;
2.1 AbstractEndPoint
EndPoint 中兩個協同合作的Runnable:
(1) Accepter負責用ServerSocket.accept()來接收客戶請求,並且把建立連接之后的Socket交由Poller處理;
(2) Poller負責接收請求,並處理;
protected class Acceptor extends AbstractEndpoint.Acceptor (Acceptor implements Runnable) public class Poller implements Runnable
Accepter和Poller的具體寫作示意圖(個人拙見)
從上圖中,我們可以發現,Acceptor接收到一個用戶的socket請求之后,將這個Socket封裝成PollerEvent,放入events隊列中。Poller實際上,一直while(true),當執行events隊列中有PollerEvent的時候,就會從自己的Selector中獲取到一個有數據的Channel,交給ProcessKey()處理。
2.1 ProtocolHandler
每一種協議都有各自具體定義,和具體的協議頭的格式,那么我么在接收到客戶請求之后,就應該根據協議的類型采用相應的解析方法。
ProtocolHandler的具體作用:
◆ 定義具體處理Socket的AbstractEndPoint;
◆ 提供解析請求的AbstractConnectionHandler來獲取具體的協議頭;
◆ 相關的init、start、stop方法
【參考文獻】
[1] http://blog.csdn.net/cutesource/article/details/5006062
[2] http://blog.csdn.net/yanlinwang/article/details/45648039