Tomcat connector 实现原理

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

BootStrap.init()
bootstrap.init() 方法中设置catalinaDaemon

创建 Connector 对象

Bootstrap.main()->Bootstrap.start()->Catalina.start()->Catalina.load()->Catalina.createStartDigester()

createStartDigester() 方法


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

server.xml 配置

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

Connector

构造


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

setProtocol 方法


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

startInternal() 方法

startInternal() 方法
1. 设置tomcat状态为,正在启动
2. 启动 connector。

Http11Protocol

Http11Protocol 构造方法

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

JIoEndpoint 继承 AbstractEndpoint
start()

JIoEndpoint .bind() 方法


在这创建connector的socket服务,使用serverSocket监听入站连接。

JIoEndpoint.startInternal() 方法


1. 判断线程池是否为空,如果为空则创建默认的线程池。(server.xml的connector中配置的线程池)
2. 根据server.xml中的connector中的acceptorThreadCount属性来确定创建几个接受请求处理的线程。
Acceptor类,负责处理接受客户端请求的处理。

server.xml 中配置如下:

acceptorThreadCount 个数建议和CPU的个数一致。

createExecutor() 方法

createExecutor() 方法
默认创建的线程池,最小线程数为10,最大线程数为200,空闲时间为60秒,队列为LinkedBlockingQueue,队列大小默认为Ineteger.MAX_VALUE。

这里需要注意的是,如果队列中的元素没有存满,那么线程的数量一直会是10,而不会自动扩大到200。所以建议大家自己设置一个线程池,而不要用默认的

Acceptor 类
Acceptor.run() 方法

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


把socket封装成SocketWrapper对象 传给SocketProcessor对象,并提交给线程池处理。

SocketProcessor

负责解析http协议信息。
SOcketProcessor重要属性
Paste_Image.png
inputBuffer:包装socket的inputStream,并解析http协议信息。
outputBuffer:包装socket的outputStream,负责响应用户的数据。

run() 方法

run() 方法
在process方法中处理解析http协议信息。

Http11Processor.process() 方法

Http11Protocol.process()->Http11Processor.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
  1. 创建ServerSocket 连接
  2. 创建接受请求的线程 Acceptor对象。
  3. 创建处理请求的线程池 executor。
3. Http11Processor

主要负责解析http协议的
1. 解析请求行 (来确定http协议、请求的url、请求的method)
2. 解析请求头 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"
/>

本人简书blog地址:http://www.jianshu.com/u/1f0067e24ff8    
点击这里快速进入简书

GIT地址:http://git.oschina.net/brucekankan/
点击这里快速进入GIT

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值