tomcat的请求流程
Endponit是一个无限循环. 当有socketBind()的 ip , port请求链接过来时, 会接收到 socket.accept() . 此时就是接受一个请求的过程.
其中重要方法: setSocketOptions()
那么把NioSocket放入到Poller的队列中是如何处理的呢? poller是一个runnable的实现类, 那么run方法中,肯定在while循环.
poller的run方法中,就是不停的从PollerEventQueue中取出任务, 去启动这个线程, 就是把这个pollerEvent事件中携带的socket和 poller中的select进行绑定.
先跳转到pollerEvent.run() . 把socket和 poller.selector做一个关联.
这个run方法并不是无限循环. 如果他也是无限循环, 那么就卡死了. 在执行完后, 回到poller.run()中,其中执行分配任务的操作.
poller.run()方法就在无限循环的去做这件事情, 当tomcat关闭后 , 跳出while循环 , 执行 countDown,关闭此线程.
使用线程池去执行socket的相关连接.
在doRun方法中和connectionHandler进行了关联. 相当于把socket传递给了protocolHandler.
关联到connectionHandler, 需要找到使用的协议, 通过socket判断是什么协议, 通过对应的协议去执行.( 此方法太长, 截取重要部分.)
这个processor就是通过协议获得的协议处理器, 接下来就到我们寻找容器的地方. 通过适配器(coyoteAdapter)找到对应的container.(方法过长,截取部分)
找到Http11Processor中的service方法, 在此方法中,会看到我们熟悉的503 , 404 , 400 , 500 等.(代码过长 , 截取部分)
此时就开始接受请求阶段已经完成, 接下来是容器阶段, 以责任链模式,一层一层去寻找处理的地方. engine去找到host
host找到context
通过context找到 wrapper
通过warpper找到对应的filter 和 servlet
这个applicationFilterChain就是类似于下方的图的形式 , 然后通过doFilter方法一个一个执行. 通过 pos < n , 限制性filter ,再执行servlet
然后就就请求到我们实现httpSerlvet的框架中, 因为是面向接口编程嘛.
接下来我们执行完后, 通过outputstream , 将数据向上一层一层刷出, 最终刷出到socketBuffer中.
至此整个tomcat的请求结束.
附上请求流程图:
|
|