Bootstrap.main()->Bootstrap.init()

bootstrap.init() 方法中设置catalinaDaemon
创建 Connector 对象
Bootstrap.main()->Bootstrap.start()->Catalina.start()->Catalina.load()->Catalina.createStartDigester()
createStartDigester() 方法

- 创建connector对象,并判断server.xml 中是否配置线程池,如果配置线程池则创建线程池

- 为connector对象设置除executor外的其它属性信息
- 把当前connector添加到StandardService.connectors 数组中。
Connector
构造

通过protocol协议来判断使用那个protocolHandler。
setProtocol 方法

tomcat 默认配置 是以BIO的模式启动的,默认会调用org.apache.coyote.http11.Http11Protocol。
下面我们以Http11Protocol来分析Connector。
startInternal() 方法

- 设置tomcat状态为,正在启动
- 启动 connector。
Http11Protocol

- 在构造方法中创建JIoEndpoint和Http11ConnectionHandler对象
- 设置 socket 参数
AbstractEndpoint.start() 方法
public class JIoEndpoint extends AbstractEndpoint
JIoEndpoint 继承 AbstractEndpoint

JIoEndpoint .bind() 方法

在这创建connector的socket服务,使用serverSocket监听入站连接。
JIoEndpoint.startInternal() 方法

- 判断线程池是否为空,如果为空则创建默认的线程池。(server.xml的connector中配置的线程池)
- 根据server.xml中的connector中的acceptorThreadCount属性来确定创建几个接受请求处理的线程。
Acceptor类,负责处理接受客户端请求的处理。
server.xml 中配置如下:
<Connector port="8080" protocol="HTTP/1.1" acceptorThreadCount="2" redirectPort="8443"/>
acceptorThreadCount 个数建议和CPU的个数一致。
createExecutor() 方法

默认创建的线程池,最小线程数为10,最大线程数为200,空闲时间为60秒,队列为LinkedBlockingQueue,队列大小默认为Ineteger.MAX_VALUE。
这里需要注意的是,如果队列中的元素没有存满,那么线程的数量一直会是10,而不会自动扩大到200。所以建议大家自己设置一个线程池,而不要用默认的
Acceptor 类
Acceptor.run() 方法

- 获取之前创建的serverSocket。
2.设置socket的参数 - 调用processSocket 处理请求的socket
processSocket() 方法

把socket封装成SocketWrapper对象 传给SocketProcessor对象,并提交给线程池处理。
SocketProcessor
负责解析http协议信息。
SOcketProcessor重要属性

inputBuffer:包装socket的inputStream,并解析http协议信息。
outputBuffer:包装socket的outputStream,负责响应用户的数据。
run() 方法

在process方法中处理解析http协议信息。
Http11Processor.process() 方法
Http11Protocol.process()->Http11Processor.process() 代码如下:

获取socket的输入流和输出流
Http11Processor构造方法

在这里,构造Request和Response对象。
解析http协议

解析完后的数据存储到 AbstractInputBuffer的下面两个属性中
protected Request request;
protected MimeHeaders headers;
request对象就是 HttpServletRequest 对象的原型。
解析完之后,调用下面的service方法。

这里的service方法会调用servlet中的service方法并传入request和response对象,然后根据请求的方法来决定调用的是servlet的doGet方法还是doPost或其它的方法。
到此 Connector的整理流程就结束了。
简单梳理下
1. Connector
根据协议来选择协议的处理类,tomcat默认的处理类是Http11Protocol。
2. JIoEndpoint
- 创建ServerSocket 连接
- 创建接受请求的线程 Acceptor对象。
- 创建处理请求的线程池 executor。
3. Http11Processor
主要负责解析http协议的
- 解析请求行 (来确定http协议、请求的url、请求的method)
- 解析请求头 headers
3.并把解析后的结果交给 Container 处理
connector 可配置的部分参数
参数值根据自己项目做响应修改。下面的只是个例子
<Connector port="8080" protocol="HTTP/1.1"
acceptCount="1000"
disableUploadTimeout="true"
enableLookups="false"
keepAliveTimeout="20"
maxThreads="500"
minThreads="500"
maxProcessor="500"
minSpareThreads="20"
maxKeepAliveRequests="1"
connectionTimeout="20"
redirectPort="8443"
allowTrace="false"
acceptorThreadCount="2"
acceptorThreadPriority="7"
socket.tcpNoDelay="true"
threadPriority="8"
tcpNoDelay="true"
compression="on"
emptySessionPath="true"
/>
想了解更多精彩内容请关注我的公众号

网友评论