Tomcat大致流程
一、涉及到的关键类
1.Bootstrap->Catalina->StandardServer->StandardService->StandardEngine,Connector->Http11NioProtocol
->NioEndpoint->Acceptor,Poller
二、初始化 bootstrap.init()
初始化需要的类加载器ClassLoader,以及通过反射构造一个Catalina
三、bootstrap继续执行,实际由Catalina来执行
daemon.setAwait(true);
daemon.load(args);
daemon.start();
四、Catalina执行setAwait与load、start
//setAwait将await标记更改为true,用于开启一个ServerSocket,可以接收一个关闭整个服务的请求
if (await) {
await();
stop();
}
//load主要创建匹配xml的规则,并且解析server.xml创建需要的对象:Server、Service、Connector、Engine...
Digester digester = createStartDigester();
...
digester.parse(inputSource);
//start主要让Server服务器进行start
getServer().start();
五、Server服务器的start,执行startInternal方法,主要开启Service服务
synchronized (servicesLock) {
for (Service service : services) {
service.start();
}
}
六、Service服务的start,执行startInternal方法,主要让Connector start
connector.start();
七、Connector.start()主要让Http11NioProtocol.start()
protocolHandler.start();
八、Http11NioProtocol.start()最终指向NioEndpoint.start(),而NioEndpoint最终执行startInternal方法,所以这里看NioEndpoint.startInternal()
九、NioEndpoint.startInternal(),主要创建缓存容器,与开启俩个任务(消费者与生产者)
//处理器(SocketProcessorBase)缓存容器,该处理器是一个Runnable,可以用来处理socket,查看servlet、filterchain可以查看其run,一步步往下即可
processorCache = new SynchronizedStack<>(SynchronizedStack.DEFAULT_SIZE,
socketProperties.getProcessorCache());
//事件(PollerEvent)缓存容器,提供一个事件PollerEvent,用于封装新的事件信息
eventCache = new SynchronizedStack<>(SynchronizedStack.DEFAULT_SIZE,
socketProperties.getEventCache());
//储存socket
nioChannels = new SynchronizedStack<>(SynchronizedStack.DEFAULT_SIZE,
socketProperties.getBufferPool());
十、俩个任务,其实是消费者线程与生产者线程(接收者线程)
//!!!第一个任务,生产者任务或者说是接收者,接收请求(Acceptor),startAcceptorThreads();
int count = getAcceptorThreadCount();
acceptors = new Acceptor[count];
for (int i = 0; i < count; i++) {
acceptors[i] = createAcceptor();
String threadName = getName() + "-Acceptor-" + i;
acceptors[i].setThreadName(threadName);
Thread t = new Thread(acceptors[i], threadName);
t.setPriority(getAcceptorThreadPriority());
t.setDaemon(getDaemon());
t.start();
}
//接收者任务:Acceptor.run,主要接收请求,然后通过setSocketOptions将该任务添加到容器PollerEvent中,
socket = serverSock.accept();
if (!setSocketOptions(socket)) {
closeSocket(socket);
}
//setSocketOptions方法主要将该socket添加到niochannel,然后注册PollerEvent任务
channel.setIOChannel(socket);
...
getPoller0().register(channel);
//Poller.register将socket封装进任务里,然后添加到缓存容器eventCache,并且通过addEvent方法添加到任务容器里
//获取一个PollerEvent对象,存在的话,就直接封装新的信息,免去实例化的操作
PollerEvent r = eventCache.pop();
ka.interestOps(SelectionKey.OP_READ);//this is what OP_REGISTER turns into.
if ( r==null) {
r = new PollerEvent(socket,ka,OP_REGISTER);
} else {
r.reset(socket,ka,OP_REGISTER);
}
addEvent(r);
//Poller.addEvent(),主要将任务添加到events容器里
events.offer(event);
if (wakeupCounter.incrementAndGet() == 0) {
selector.wakeup();
}
//!!!第二个任务,消费者任务(Poller),getPollerThreadCount()获取容量大小
pollers = new Poller[getPollerThreadCount()];
for (int i=0; i<pollers.length; i++) {
pollers[i] = new Poller();
Thread pollerThread = new Thread(pollers[i], getName() + "-ClientPoller-"+i);
pollerThread.setPriority(threadPriority);
pollerThread.setDaemon(true);
pollerThread.start();
}
//Poller.run主要先查看是否有事件存在,有的话就处理事件
//查看是否有事件存在
hasEvents = events();
//通过processKey方法处理事件
Iterator<SelectionKey> iterator =
keyCount > 0 ? selector.selectedKeys().iterator() : null;
// Walk through the collection of ready keys and dispatch
// any active event.
while (iterator != null && iterator.hasNext()) {
SelectionKey sk = iterator.next();
iterator.remove();
NioSocketWrapper socketWrapper = (NioSocketWrapper) sk.attachment();
// Attachment may be null if another thread has called
// cancelledKey()
if (socketWrapper != null) {
//现在到了处理请求的时候了
processKey(sk, socketWrapper);
}
}
//processKey主要执行processSocket
if (sk.isReadable()) {
if (!processSocket(attachment, SocketEvent.OPEN_READ, true)) {
closeSocket = true;
}
}
//processSocket主要通过使用SocketProcessorBase处理器封装socket,然后提交给线程池执行任务
SocketProcessorBase<S> sc = processorCache.pop();
if (sc == null) {
sc = createSocketProcessor(socketWrapper, event);
} else {
sc.reset(socketWrapper, event);
}
Executor executor = getExecutor();
if (dispatch && executor != null) {
executor.execute(sc);
} else {
sc.run();
}
//SocketProcessorBase任务,SocketProcessor继承了该任务,并且实现doRun方法,SocketProcessorBase.Run最后执行的是doRun,所以看一下doRun
//getHandler()是ConnectionHandler
getHandler().process(socketWrapper, SocketEvent.OPEN_READ);
//ConnectionHandler.process最终由AbstractProcessorLight来执行
processor.process(wrapper, status);
//AbstractProcessorLight.process最终执行checkForPipelinedData
if (dispatches != null) {
DispatchType nextDispatch = dispatches.next();
if (getLog().isDebugEnabled()) {
getLog().debug("Processing dispatch type: [" + nextDispatch + "]");
}
state = dispatch(nextDispatch.getSocketStatus());
if (!dispatches.hasNext()) {
//由这里执行
state = checkForPipelinedData(state, socketWrapper);
}
}
//AbstractProcessorLight.checkForPipelinedData执行Http11Processor.service
service(socketWrapper);
//Http11Processor.service执行CoyoteAdapter.service()
getAdapter().service(request, response);
//CoyoteAdapter.service()最终由StandardEngineValve.invoke
connector.getService().getContainer().getPipeline().getFirst().invoke(
request, response);
//接着连续几个invoke
//StandardHostValve.invoke->StandardContextValve.invoke->StandardWrapperValve.invoke,至此就到了跟Servlet、Filter、filterChain有关的地方了
//StandardWrapperValve.invoke 生成Servlet、Filter、FilterChain的地方了
//1.首先servlet的获取,wrapper里面封装着对应的servlet,以及信息
servlet=wrapper.allocate();
//allocate,singleThreadModel默认为false,这个标记作用是保证servlet是否唯一,为false,那么servlet就是单例的,为true,那么每一次请求都会创建一个servlet
if (!singleThreadModel) {
...
if (instance == null || !instanceInitialized) {
synchronized (this) {
if (instance == null) {
//第一次加载,instance为全局变量
instance = loadServlet();
}
}
}
...
return instance;
}
//2.过滤器链的创建
ApplicationFilterChain filterChain =
ApplicationFilterFactory.createFilterChain(request, wrapper, servlet);
//createFilterChain,过滤器链设计模式,包含一个目标对象,以及多个过滤对象,下面是简化的内容
//实例化过滤器链
filterChain = new ApplicationFilterChain();
//设置目标对象
filterChain.setServlet(servlet);
FilterMap filterMaps[] = context.findFilterMaps();
//遍历filterMaps[]
//封装Filter
ApplicationFilterConfig filterConfig = (ApplicationFilterConfig)context.findFilterConfig(filterMap.getFilterName());
//添加进过滤器链中
filterChain.addFilter(filterConfig);
//3.调用过滤器链,最终执行internalDoFilter
filterChain.doFilter(request.getRequest(),response.getResponse());
//internalDoFilter,p为当前过滤对象的索引,n所有过滤对象,所以当判断不满足时就会执行目标对象,也就是servlet
if(p<n){
...
//执行过滤操作
filter.doFilter(request, response, this);
return;
}
//servlet
servlet.service(request, response);
//4.接下来就是执行HttpServlet.service,至此结束
十一、大致总结
1 main方法启动后,Bootstrap进行初始化操作Init,主要实例化了Catalina,接着进行load以及start操作,以及await更改为true,实际就是让Catalina来执行
2. Catalina首先更改await标记为true,然后主线程就会开启一个ServerSocket(port为8005),用来接收停止整个服务的请求
2.2 Catalina.load,创建xml匹配规则,然后扫描conf/server.xml创建基本的对象:Server、Service、Connector...
2.3 Catalina.start,主要是Server.start->Service.start->Connector.start->Http11NioProtocol.start->NioEndpoint.start
3. NioEndpoint.start开启俩个任务,一个消费者任务(Poller),一个接收者任务(Acceptor)
4. 接收者任务NioEndpoint.Acceptor,开启线程,用于接收请求(Socket),然后将该请求封装成PollerEvent注册给Poller里面的PollerEvent容器
5. 消费者任务Poller,判断任务是否存在,存在的话就进行处理,调用Poller.processKey->AbstractEndpoint.processSocket->获取处理器SocketProcessorBase并且提交给线程池
6. 处理器任务SocketProcessorBase.run->SocketProcessor.doRun->ConnectionHandler.process->AbstractProcessorLight.process->Http11NioProtocol.service
->CoyoteAdapter.service->StandardEngineValve.invoke->StandardHostValve.invoke->StandardContextValve.invoke->StandardWrapperValve.invoke
7.StandardWrapperValve.invoke主要处理servlet以及filterchain,首先通过StandardWrapper.allocate获取servlet,然后创建ApplicationFilterChain过滤器链,最终执行ApplicationFilterChain.doFilter;
8.最后就是到了我们编写的Filter,以及Servlet了,ApplicationFilterChain.doFilter实现比较简单.首先判断是否还有Filter,没有的话就执行Servlet.service;有的话就继续过滤Filter.doFilter并且return,
也就是后面不会调用servlet,所以我们在使用Filter的时候一定要调用过滤器链的doFilter,这样最后没有Filter时,就是调用Servlet.service了。