tomcat主要組件
Server服務器:可以理解成tomcat,一個Server可以包含多個Service服務
Service服務:管理Connetor和Container,一個service有一個Container和多個Connetor
Connetor:連接器,負責接收請求
Container:容器,主要負責處理請求
Session管理器:負責管理session,例如:session的創建和刪除等
上一張架構圖:
架構重點是Connetor和Container
Connetor
Connetor連接器,可以看到http請求過來是由Connetor來接收,Connetor接受之後最會使用HttpProcessor類去解析http請求,這邊往往爲了提高效率,利用了懶加載,如果我們沒有程序沒有調用到請求過來的信息,是不會去解析的。
大概的解析過程:
讀取套接字的輸入流
解析請求行
解析請求頭
解析Cookie
獲取參數
tomcat7中的Connetor部分代碼,tomcat7使用的連接器叫Coyote
/**
* Implementation of a Coyote connector.
*
* @author Craig R. McClanahan
* @author Remy Maucherat
*/
public class Connector extends LifecycleMBeanBase {
private static final Log log = LogFactory.getLog(Connector.class);
protected String protocolHandlerClassName =
"org.apache.coyote.http11.Http11Protocol";
/**
* Alternate flag to enable recycling of facades.
*/
public static final boolean RECYCLE_FACADES =
Boolean.parseBoolean(System.getProperty("org.apache.catalina.connector.RECYCLE_FACADES", "false"));
// ------------------------------------------------------------ Constructor
public Connector() {
this(null);
}
//去實例化了一個org.apache.coyote.http11.Http11Protocol
public Connector(String protocol) {
setProtocol(protocol);
// Instantiate protocol handler
try {
Class<?> clazz = Class.forName(protocolHandlerClassName);
this.protocolHandler = (ProtocolHandler) clazz.getDeclaredConstructor().newInstance();
} catch (Exception e) {
log.error(sm.getString(
"coyoteConnector.protocolHandlerInstantiationFailed"), e);
}
// Default for Connector depends on this (deprecated) system property
if (Boolean.parseBoolean(System.getProperty("org.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH", "false"))) {
encodedSolidusHandling = EncodedSolidusHandling.DECODE;
}
}
}
Http11Protocal的代碼中創建了Processor類
@Override
protected Http11Processor createProcessor() {
Http11Processor processor = new Http11Processor(
proto.getMaxHttpHeaderSize(), proto.getRejectIllegalHeader(),
(JIoEndpoint)proto.endpoint, proto.getMaxTrailerSize(),
proto.getAllowedTrailerHeadersAsSet(), proto.getMaxExtensionSize(),
proto.getMaxSwallowSize(), proto.getRelaxedPathChars(),
proto.getRelaxedQueryChars());
proto.configureProcessor(processor);
processor.setDisableKeepAlivePercentage(proto.getDisableKeepAlivePercentage());
register(processor);
return processor;
}
Container
連接器處理後,會解析請求,生成request對象和response對象,傳遞給Container
四種Container
- Engine :表示servlet引擎,用來管理多個虛擬站點
- Host:代表一個虛擬主機,一個虛擬主機地址下可以部署多個web引用程序
- Context:表示一個web程序,可以簡單的認位tomcat目錄webapps下的xxx.war包就是一個Contxt容器
- Wrapper :表示一個servlet
容器實現了相同的Container接口,並且父容器和子容器利用組合聯繫起來,是1對多的關係,可以看看上面的圖。
下圖是容器類的關係圖。
這樣設置有什麼好處?
可以看到Container容器中有一個start和stop方法,容器使用了組合模式,所以我們在啓動和停止的時候,只要啓動/停止最上層容器就可以啓動/停止所有的容器了。