0
点赞
收藏
分享

微信扫一扫

tomcat 源码分析

眸晓 2022-04-05 阅读 60

1. tomcat 核心组件

Server

Service

ProtocalHanler

EndPoint

ThreadPoolExecutor

Processor

Adapater

Container

engine

host

context

wrapper

2. tomcat 启动流程

Lifecycle接口实现生命周期
LifeCycleBase生命周期的基类
Container接口实现容器的组合模块
ContainerBase容器的基类
 * <pre>
* start()
* -----------------------------
* | |
* | init() |
* NEW -»-- INITIALIZING |
* | | | | ------------------«-----------------------
* | | |auto | | |
* | | \|/ start() \|/ \|/ auto auto stop() |
* | | INITIALIZED --»-- STARTING_PREP --»- STARTING --»- STARTED --»--- |
* | | | | |
* | |destroy()| | |
* | --»-----«-- ------------------------«-------------------------------- ^
* | | | |
* | | \|/ auto auto start() |
* | | STOPPING_PREP ----»---- STOPPING ------»----- STOPPED -----»-----
* | \|/ ^ | ^
* | | stop() | | |
* | | -------------------------- | |
* | | | | |
* | | | destroy() destroy() | |
* | | FAILED ----»------ DESTROYING ---«----------------- |
* | | ^ | |
* | | destroy() | |auto |
* | --------»----------------- \|/ |
* | DESTROYED |
* | |
* | stop() |
* ----»-----------------------------»------------------------------

核心类图

PlantUml

@startuml tomcat

Bootstrap -> Bootstrap: main()
Bootstrap -> Catalina : load()
Catalina -> StandardServer: initInternal()
StandardServer -> StandardService : initInternal()
StandardService -> StandardEngine : initInternal()
StandardService -> Executor : init()
StandardService -> mapperListener : init()
Bootstrap -> Catalina: start()
Catalina -> StandardServer : startInternal()
StandardServer -> StandardService : startInternal()
StandardService -> StandardEngine : startInternal()
StandardService -> StandardThreadExecutor : startInternal()
StandardService -> mapperListener : startInternal()
StandardEngine -> StandardHost : startInternal()
StandardHost -> HostConfig : lifecycleEvent()
HostConfig -> HostConfig :deployApps()
HostConfig -> StandardContext:
StandardContext -> ServletContainerInitializer : startInternal()
ServletContainerInitializer -> SpringServletContainerInitializer: onStratUp()
@enduml

 

3. tomcat 核心请求流程

 

核心是Pipeline-Valve 是责任链模式

在基类ContainerBase中构建一个Pipeline数组作为责任链

以StandardEngine容器为例 

    /**
* Create a new StandardEngine component with the default basic Valve.
*/

public StandardEngine() {

super();
// 在构造方法中塞入StandardEngineValve 最为最后一个Valve
pipeline.setBasic(new StandardEngineValve());
/* Set the jmvRoute using the system property jvmRoute */
try {
setJvmRoute(System.getProperty("jvmRoute"));
} catch(Exception ex) {
log.warn(sm.getString("standardEngine.jvmRouteFail"));
}
// By default, the engine will hold the reloading thread
backgroundProcessorDelay = 10;

}

执行下一个容器的Valve

还是以StandardEngine为例子

 /**
* Select the appropriate child Host to process this request,
* based on the requested server name. If no matching Host can
* be found, return an appropriate HTTP error.
*
* @param request Request to be processed
* @param response Response to be produced
*
* @exception IOException if an input/output error occurred
* @exception ServletException if a servlet error occurred
*/

@Override
public final void invoke(Request request, Response response)
throws IOException, ServletException {

// Select the Host to be used for this Request
Host host = request.getHost();
if (host == null) {
// HTTP 0.9 or HTTP 1.0 request without a host when no default host
// is defined.
// Don't overwrite an existing error
if (!response.isError()) {
response.sendError(404);
}
return;
}
if (request.isAsyncSupported()) {
request.setAsyncSupported(host.getPipeline().isAsyncSupported());
}

// Ask this Host to process this request
// 执行 host的一个Valve
host.getPipeline().getFirst().invoke(request, response);
}

执行当前容器的Valve

以AbstractAccessLogValve为例子

 /**
* Log a message summarizing the specified request and response, according
* to the format specified by the <code>pattern</code> property.
*
* @param request Request being processed
* @param response Response being processed
*
* @exception IOException if an input/output error has occurred
* @exception ServletException if a servlet error has occurred
*/

@Override
public void invoke(Request request, Response response) throws IOException,
ServletException {
if (tlsAttributeRequired) {
// The log pattern uses TLS attributes. Ensure these are populated
// before the request is processed because with NIO2 it is possible
// for the connection to be closed (and the TLS info lost) before
// the access log requests the TLS info. Requesting it now causes it
// to be cached in the request.
request.getAttribute(Globals.CERTIFICATES_ATTR);
}
if (cachedElements != null) {
for (CachedElement element : cachedElements) {
element.cache(request);
}
}
getNext().invoke(request, response);
}

举报

相关推荐

0 条评论