Tomcat启动过程

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了。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值