A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

本帖最后由 大蓝鲸小蟀锅 于 2020-4-14 10:12 编辑

tomcat启动流程

1.tomcat启动在load阶段 , 从 bootstrap ---> catalina --> server --> service --> container --> engine   
                                                                                                                       --> connect --> processHandle --> endpoint        
在bootstrap的main方法开始运行整个Tomcat容器的.
在bootstrap执行的第一步 , 就打破了java的双亲委派机制. 因为tomcat感觉自己加载的类,不会再jvm的classload中, 不需要去到jvm的classload中寻找, 提高执行效率.

会通过反射加载catalina类,  执行load方法 解析server.xml文件, 用来创建server对象.

对应关系:
         一个server对应 多个service是 一对多.
         一个service对应 多个connect , 一个container.



service与engine是一对一.  service与connector是一对多.


容器container的初始化就结束了, load方法,只会把container加载到engine.


连接connector,会去加载 processHandle.


protocolHandler是创建使用是的什么协议 , 我们的tomcat就能接受到什么协议. 通过构造方法可以看到 , 8.0之后默认使用的是Http11NioProtocol协议




protocolHandler中存在一个socket的监听器endPonit, 有消息会及时响应给connectionHandler.  endpoint就是在http1Protocol构造方法中new出来的.


endpoint就是用来监听socket的, 有请求过来时, 通知processHandle. 通过bind()方法, 监听ip地址和端口号.


processHandle,用来处理不同的链接协议 , 去找到process , 然后process通过mapperListener找到container , 在通过container的责任链模式向下传递. 交由engine , host , context , wrapper.


2.tomcat在start阶段.
也是从bootstrap一层一层调用下来.  其中connector已经加载完成, 所以主要工作是在engine. 因为在load阶段container已经启动到engine.





container执行start流程, 主要是用来加载我们对应的容器.
engine --> host  一对多.
host --> context   多对多
context --> wrapper 多对多.
其中 host是用来加载我们部署的文件 , 包括部署的解析.  我们有三种部署war工程方式, 都是通过host来解析的, server.xml , war包, directory.  如果部署多个, 则会对应多个host.
context是用来解析web.xml文件, 并把其中的filter , servlet, 解析成为wrapper , 添加成为子容器 , 进行启动.



由standardService的startInternal()方法可知, engine启动后, 会启动Connector.
因为connector是用来接收连接的. 如果有连接进来, 但是你的wrapper还没部署好, 不就返回404了?

connector启动protocolHandler , protocolHandler启动endpoint , 真正的接收请求链接 , 就在endpoint中.

8.0之后的tomcat, IO编程模型的协议, 默认使用的是nio , 但是也包含nio2, nio2的效率会更高一点, 所以我们在启动时 ,可以自己去配置nio2的协议.


Poller 实际上是对Nio中的 selector进行的一层封装 , 用来分配请求来的信息, 请求过来, 都是通过selector来进行分配. 而且Poller也是一个Runnable的实现类, 所以执行代码在run()中.

创建接收请求的acceptor , 其实acceptor是一个Runnable的一个实现. 所以调用start来开启, 执行他的run方法.  至此connector.start()方法走完.




附图: 一个是tomcat的组件结构.







0 个回复

您需要登录后才可以回帖 登录 | 加入黑马