tomcat bootstrap启动步骤

本文详细介绍了Tomcat的启动步骤,从bootstrap.main开始,经过catalina.init、catalina.load、catalina.start,直至各个容器如Service、Engine、Host、Context的启动。在启动过程中,利用责任链设计模式,通过Lifecycle接口规范组件状态和操作,LifecycleListener作为观察者监听状态变化。Tomcat通过触发before_start、start、after_start事件来依次启动各个组件,确保服务正常对外提供。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

[b]TOMCAT以一个责任链贯穿Server的启动过程。首先是读取配置文件、由Server启动一个service,由service把connector和container组装起来对外界提供服务。[/b]
在tomcat6中connector包括三种不同的connector:
1、Http Connector 基于HTTP协议,负责建立HTTP连接。它又分为BIO Http Connector与NIO Http Connector两种,后者提供非阻塞IO与长连接Comet支持。
2、AJP Connector, 基于AJP协议,AJP是专门设计用来为tomcat与http服务器之间通信专门定制的协议,能提供较高的通信速度和效率。如与Apache服务器集成时,采用这个协议。
3、APR HTTP Connector, 用C实现,通过JNI调用的。主要提升对静态资源(如HTML、图片、CSS、JS等)的访问性能。现在这个库已独立出来可用在任何项目中。Tomcat在配置APR之后性能非常强劲

Container 是容器的父接口,所有子容器都必须实现这个接口,Container 容器的设计最能体现责任链的设计模式;它有四个子容器组件构成,分别是:Engine、Host、Context、Wrapper。这四个组件不是平行的,而是父子关系,  Engine 包含 Host,Host 包含 Context,Context 包含 Wrapper,
通常一个 Servlet class 对应一个 Wrapper,如果有多个 Servlet 就可以定义多个 Wrapper


[b]在启动的过程中service责任链的下一个节点是Engine,再下一个节点是Host、然后context。
等所有的容器都初始化完成了,tomcat也就启动完成[/b]

[b]然而贯穿整个启动过程的责任链由一个简单的接口来实现:lifecycle
lifecycle实际上就是观察者模式中的被观察者 规范了生命周期组件的状态和操作方法
lifecycleListener 监听接口 实际上就是观察者模式中的观察者 监听在生命周期组件的各种状态变化
LifecycleEvent 事件定义接口 可以通过构造函数构造生命周期中的任何一个状态[/b]


[b]1、bootstrap.main[/b]

启动的入口
[b]2、catalina.init[/b]
加载类库 初始化守护线程
 if (daemon == null) {
daemon = new Bootstrap();
try {
daemon.init();
} catch (Throwable t) {
t.printStackTrace();
return;
}
}

[b]3、catalina.load[/b]
catalina就是tomcat的守护线程 load方法加载server.xml配置文档 加载责任链相关的监听信息
                daemon.setAwait(true);
daemon.load(args);
daemon.start();

[b]4、catalina.start[/b]
启动StandardServer.start方法
// Start the new server
if (getServer() instanceof Lifecycle) {
try {
((Lifecycle) getServer()).start();
} catch (LifecycleException e) {
log.error("Catalina.start: ", e);
}
}

[b]5、StandardServer.start[/b]
从这里开始 启动责任链 启动的之前先触发before_start动作、然后触发start动作、接着启动下级容器standardService、然后触发after_start动作
// Validate and update our current component state
if (started) {
log.debug(sm.getString("standardServer.start.started"));
return;
}

// Notify our interested LifecycleListeners
lifecycle.fireLifecycleEvent(BEFORE_START_EVENT, null);

lifecycle.fireLifecycleEvent(START_EVENT, null);
started = true;

// Start our defined Services
synchronized (services) {
for (int i = 0; i < services.length; i++) {
if (services[i] instanceof Lifecycle)
((Lifecycle) services[i]).start();
}
}

// Notify our interested LifecycleListeners
lifecycle.fireLifecycleEvent(AFTER_START_EVENT, null);

[b]6、standardService.start[/b]
先触发before_start动作、然后触发start动作、接着启动下级容器StandardEngine、启动连接器[Connector[HTTP/1.1-8080], Connector[AJP/1.3-8009]]、然后触发after_start动作
// Notify our interested LifecycleListeners
lifecycle.fireLifecycleEvent(BEFORE_START_EVENT, null);
if(log.isInfoEnabled())
log.info(sm.getString("standardService.start.name", this.name));
lifecycle.fireLifecycleEvent(START_EVENT, null);
started = true;

// Start our defined Container first
if (container != null) {
synchronized (container) {
if (container instanceof Lifecycle) {
((Lifecycle) container).start();
}
}
}

synchronized (executors) {
for ( int i=0; i<executors.size(); i++ ) {
executors.get(i).start();
}
}

// Start our defined Connectors second
synchronized (connectors) {
for (int i = 0; i < connectors.length; i++) {
try {
((Lifecycle) connectors[i]).start();
} catch (Exception e) {
log.error(sm.getString(
"standardService.connector.startFailed",
connectors[i]), e);
}
}
}

// Notify our interested LifecycleListeners
lifecycle.fireLifecycleEvent(AFTER_START_EVENT, null);

[b]7、standardEngine.start[/b]
补充说明一下standardEngine、StandardHost、StandardContext都继承了ContainerBase类 ContainerBase类中重写了start方法 standardEngine只要调用super.start() 。容器ContainerBase会递归启动standardEngine下的所有子容器
  // Standard container startup
super.start();


[b]8、containerBase.start [/b]
containerBase.start方法里面除了启动下级子容器外还做了不少动作 例如日志组件、集群功能加载、启动容器后台守护线程


// Validate and update our current component state
if (started) {
if(log.isInfoEnabled())
log.info(sm.getString("containerBase.alreadyStarted", logName()));
return;
}

// Notify our interested LifecycleListeners
lifecycle.fireLifecycleEvent(BEFORE_START_EVENT, null);

started = true;

// Start our subordinate components, if any
if ((loader != null) && (loader instanceof Lifecycle))
((Lifecycle) loader).start();
logger = null;
getLogger();
if ((logger != null) && (logger instanceof Lifecycle))
((Lifecycle) logger).start();
if ((manager != null) && (manager instanceof Lifecycle))
((Lifecycle) manager).start();
if ((cluster != null) && (cluster instanceof Lifecycle))
((Lifecycle) cluster).start();
if ((realm != null) && (realm instanceof Lifecycle))
((Lifecycle) realm).start();
if ((resources != null) && (resources instanceof Lifecycle))
((Lifecycle) resources).start();

// Start our child containers, if any
Container children[] = findChildren();
for (int i = 0; i < children.length; i++) {
if (children[i] instanceof Lifecycle)
((Lifecycle) children[i]).start();
}

// Start the Valves in our pipeline (including the basic), if any
if (pipeline instanceof Lifecycle)
((Lifecycle) pipeline).start();

// Notify our interested LifecycleListeners
lifecycle.fireLifecycleEvent(START_EVENT, null);

// Start our thread
threadStart();

// Notify our interested LifecycleListeners
lifecycle.fireLifecycleEvent(AFTER_START_EVENT, null);


StandardHost.start
StandardContext.start
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值