一、请求处理流程
Connector中的处理
Tomcat在初始化时会按照xml中配置来初始化不同协议的Connector,Tomcat使用ProtocolHandler来用于扩展不同的协议,包括http协议和ajp协议,在每个协议的内部又依据io类型的不同,分为bio、nio等,组合起来常用的实现类有:Http11Protocol、Http11NioProtocol、AjpProtocol、AjpNioProtocol等。 不同的io内部又是通过不同的EndPoint来处理的,如BIO的JioEndPoint、Nio的NioEndPoint
Connect中的整个请求过程如下图所示:
Container中的处理
在Connector中对请求的协议及参数进行解析后会得到Connector包下的Request和Response对象,经过Adapter的适配,可以得到HttpServletRequest和HttpServletResponse对象,接下来会调用其所在的Service对象下的Container容器的Pipeline进行依次执行
二、Connector中对Http协议处理源码解析
BIO的处理
这里主要以bio的处理为例,主要看的是Http11Protocol中的处理,其对应的EndPoint是JioEndPoint
1.BIO中的启动
(1)初始化一个工作线程池。
注意这个线程池是Connector内部的线程池,最大线程数200
(2)初始化一个栅栏
用来限制链接次数的
(3)启动Acceptor线程
里面的过程就是new了许多Runnable的Acceptor,并开启一个线程跑这个Acceptor,接下来看看Acceptor内部的任务是什么
(4)启动一个守护线程,里面执行超时处理的任务
2.Acceptor中run执行的任务
Acceptor是定义在AbstractEndPoint中的内部抽象类,JioEndPoint等各自进行实现.
(1)判断是否达到最大连接
(2)获取Socket
(3)处理Socket
3.processSocket的处理
代码比较简单,封装成SocketProcessor丢给线程池进行执行(这里的线程池就是前面start中的工作线程池),接下来看看SocketProcessor中是怎么执行的
1. protected boolean processSocket(Socket socket) {
2. // Process the request from this socket
3. try {
4. SocketWrapper<Socket> wrapper = new SocketWrapper<Socket>(socket);
5. wrapper.setKeepAliveLeft(getMaxKeepAliveRequests());
6. wrapper.setSecure(isSSLEnabled());
7. // During shutdown, executor may be null - avoid NPE
8. if (!running) {
9. return false;
10. }
11. //Wrapper包装一下,封装成一个SocketProcessor并交给线程池执行
12. getExecutor().execute(new SocketProcessor(wrapper));
13. } catch (RejectedExecutionException x) {
14. log.warn("Socket processing request was rejected for:"+socket,x);
15. return false;
16. } catch (Throwable t) {
17. ExceptionUtils.handleThrowable(t);
18. // This means we got an OOM or similar creating a thread, or that
19. // the pool and its queue are full
20. log.error(sm.getString("endpoint.process.fail"), t);
21. return false;
22. }
23. return true;
24. }
4.SocketProcessor中的处理
查看其实现的run方法,核心是handler.process方法。那这个Handler又是什么东西呢?
Handler是定义在JioEndPoint中的接口,继承自AbstractEndPoint中定义的Handler接口,他有两个实现分别是ajp和http协议的,上面handler对象就是Http11ConnectionHandler,其process方法在其父类AbstractConnectionHandler中。
在里面会调用Processor的process方法,Processor接口也有很多实现类,这里对应Http11Processor,它的process方法也定义在其父类,AbstractHttp11Processor中,里面会对协议的信息进行解析,并得到org.apache.coyoteo.Request和org.apache.coyoteo.Response对象,接下来对将整个两个对象作为参数,传给Adapter的service方法,Adapter的实现类为CoyoteAdapter
该对象的service方法会将Coyote中的Request和Response转为servlet的Requst对象和Response对象,并调用Service的Contain容器Pipeline的第一个元素进行invoke
NIO的处理
NIO的处理的流程主要是多了一层Poller线程,BIO模式中每个请求都会交给线程池中的一个线程进行处理,线程会阻塞在IO等待上,而NIO则是引入了Selector,当接收到请求时会生成Channel并注册到Selector上,Selector监听到有读写事件时再去调用Handler去处理请求