Tomcat源码分析【十七】请求处理过程分析之简单总结
引言经过几篇的分析,终于将Tomcat请求处理过程分析完了,大概分为四个阶段:
Acceptor接收请求,将请求封装发送到Poller
Acceptor启动后监听请求,阻塞在ServerSocketChannel.accept()方法处,当有新连接时,返回ScoketChannel。
将ScoketChannel封装为NioChannel,注册到Poller
Poller的addEvent方法,将请求加入到PollerEvent队列中。
Poller监听事件,当Socket可读或者可写时,将Socket添加到Worker工作队列
每个Poller维护一个Selector,Poller启动后,阻塞在select方法
将Socket的SocketChannel注册到Selector上,当Socket可读时,Poller对其处理
将Socket封装到SocketProcessor中,加入到worker线程池中处理
Worker对请求进行封装,调用容器的pipeline,将请求交由Container
Http11Processor将Socket解析,封装org.apache.coyote. ...
Tomcat源码分析【十六】请求处理过程分析之创建与执行过滤器链
引言filter是Servlet的规范,是在请求进入容器后,执行Servlet.service方法之前执行。Tomcat处理filter分为三步:
上下文初始化时读取web.xml中的filter数据
请求处理时,根据请求路径找到相应的过滤器
执行过滤器链,调用doFilter方法与目标方法。
初始化filter数据首先在ContextConfig初始化时,读取web.xml配置文件,将其中的filter信息封装为FilterDef存储到StandardContext:
12345678910111213private void configureContext(WebXml webxml) {//略......for (FilterDef filter : webxml.getFilters().values()) { if (filter.getAsyncSupported() == null) { filter.setAsyncSupported("false"); } contex ...
Tomcat源码分析【十五】请求处理过程分析之分配Servlet实例处理请求
引言本篇内容源码在StandardWrapperValve的invoke方法中:
1234//略......//分配一个servlet实例来处理这个请求servlet = wrapper.allocate();//略......
调用StandardWrapper中的方法:
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116/** * Allocate an initialized instance of this Servlet that is ready to have * its <code>service()</code& ...
Tomcat源码分析【四】启动过程分析之主干流程
引言Tomcat启动入口就在脚本startup.sh中,具体脚本可以看tomcat的源码,这个启动脚本主要用来判断环境,找到catalina.sh脚本路径,将启动参数传递给catalina.sh执行。catalina.sh start 最终会执行org.apache.catalina.startup.Bootstrap中的main方法,并把start参数传入。以后分析Tomcat关闭的时候,也是一个套路,最终都会调用到org.apache.catalina.startup.Bootstrap的main方法,并把stop参数传入。
分析main方法:
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879/** * 通过提供的脚本启动Tomcat时的主方法和入口点。 * * @param args 要处理的命令行参数 */ public s ...
Tomcat源码分析【十四】请求处理过程分析之Container
引言经过Acceptor、Poller、SocketProcessor的合作处理,组装好了Request和Response,交由Container处理,Container处理逻辑也在工作线程中实行。本篇文章从下面一段代码开始,位于CoyoteAdapter的service方法中:
12// Calling the containerconnector.getService().getContainer().getPipeline().getFirst().invoke(request, response);
通过debug,发现顺序走入了如下Valve(阀门、关卡):
12345678910StandardEngineValveAbstractAccessLogValveErrorReportValveStandardHostValveAuthenticatorBaseStandardContextValveStandardWrapperValve
下面看核心的四个basic valve:
StandardEngineValve123456789101112131415public f ...
Tomcat源码分析【十三】请求处理过程分析之SocketProcessor
引言Acceptor监听指定端口,获取到SocketChannel,将其封装成NioChannel注册到Poller;Poller接收到Acceptor发过来的NioChannel,将其封装成PollerEvent放入本地队列;Poller消费并处理本地队列PollerEvent,组装SocketProcessor对象,交由工作线程池Executor处理。
本篇主要分析工作线程池处理SocketProcessor对象。先贴上Poller与工作线程池交接的方法processSocket:
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748/** * Process the given SocketWrapper with the given status. Used to trigger * processing as if the Poller (for those endpoints that have one) * selected the ...
Tomcat源码分析【十二】请求处理过程分析之Poller
引言上一篇分析完Acceptor,将获取的Socket封装成NioChannel注册到Poller,在注册的过程中NioChannel会封装成PollerEvent。本篇主要看PollerEvent是怎么处理的。
Poller类实现了Runnable接口,所以主要看其run方法:
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576/** * The background thread that adds sockets to the Poller, checks the * poller for triggered events and hands the associated socket off to an * appropriate processor as events occur. * 后台线程将 ...
Tomcat源码分析【十一】请求处理过程分析之Acceptor
引言这个类其实比较简单,继承自Runnable接口,实现了run方法。方法中主要都是一些状态的变化,这里只看比较重要的两个地方:
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051@Override public void run() { int errorDelay = 0; // Loop until we receive a shutdown command while (endpoint.isRunning()) {//略。。。 try { //略。。。 U socket = null; try { // Accept the next incoming connection from the server ...
Tomcat源码分析【十】请求处理过程分析之NIO网络操作
引言在分析Tomcat的请求处理过程之前,得先复习一下Java NIO的一些知识:
概念NIO最大的特点是面向缓冲区,有三大核心:Channel、Buffer、Selector。
ChannelChannel是双向的,既可以读数据,也可以写数据。这里只关注TCP(Server和Client)相关的ServerSocketChannel和SocketChannel。
Buffer数据总是从通道读取到缓冲区,或者从缓冲区写入通道中。
Selector用于监听多个通道的事件,比如连接打开、数据到达。
TCP客户端服务端例子####ServerHandler与其实现
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889import java.io.IOException;import java.nio.chann ...
Tomcat源码分析【九】Connector连接器
定义Connector官方文档
HTTP连接器元素表示支持HTTP/1.1协议的连接器组件。除了能够执行servlet和JSP页面之外,它还使Catalina能够作为独立的web服务器运行。此组件的特定实例侦听服务器上特定TCP端口号上的连接。可以将一个或多个这样的连接器配置为单个服务的一部分,每个连接器都转发到关联的引擎来执行请求处理并创建响应。如果希望使用AJP协议(如mod_jk 1.2)配置用于连接到web服务器的连接器。 (such as the mod_jk 1.2.x connector for Apache 1.3),请参阅AJP连接器文档。每个传入请求在请求期间都需要一个线程。如果接收到的并发请求多于当前可用的请求处理线程所能处理的,那么将创建更多的线程,直到配置的最大值(maxThreads属性的值)。如果还同时接收到更多的请求,则将它们堆积在连接器创建的服务器套接字中,直到配置的最大值(acceptCount属性的值)。任何进一步的同步请求都会收到“连接拒绝”错误,直到有可用的资源来处理它们。
我们使用Tomcat,一般只用到Web服务器、Servl ...