Tomcat启动分析(四) - Server、Service与E
2018-09-13 本文已影响4人
buzzerrookie
在分析Lifecycle接口之后,本文分析Server与Service组件的初始化和启动过程。
Server
Server表示整个容器,Server接口的唯一实现类是StandardServer类,它继承了LifecycleMBeanBase类。它的initInternal方法很简单,初始化解析server.xml过程中添加的各Service。
@Override
protected void initInternal() throws LifecycleException {
super.initInternal();
// 省略与JMX有关的代码
// Initialize our defined Services
for (int i = 0; i < services.length; i++) {
services[i].init();
}
}
StandardServer类的startInternal方法也很简单,主要做了以下几件事:
- 触发CONFIGURE_START_EVENT事件;
- 启动命名服务(好像与JNDI有关,不太确定);
- 启动解析server.xml过程中添加的各Service。
@Override
protected void startInternal() throws LifecycleException {
fireLifecycleEvent(CONFIGURE_START_EVENT, null);
setState(LifecycleState.STARTING);
globalNamingResources.start();
// Start our defined Services
synchronized (servicesLock) {
for (int i = 0; i < services.length; i++) {
services[i].start();
}
}
}
Service
Service处于Server和Engine之间,用来将Connector绑定到Engine上。Service接口的唯一实现类是StandardService类,它同样继承了LifecycleMBeanBase类。它的initInternal方法做了以下几件事:
- 初始化解析server.xml过程中添加的Engine;
- 初始化解析server.xml过程中添加的各Executor;
- 初始化解析server.xml过程中添加的各Connector。
@Override
protected void initInternal() throws LifecycleException {
super.initInternal();
if (engine != null) {
engine.init();
}
// Initialize any Executors
for (Executor executor : findExecutors()) {
if (executor instanceof JmxEnabled) {
((JmxEnabled) executor).setDomain(getDomain());
}
executor.init();
}
// Initialize mapper listener
mapperListener.init();
// Initialize our defined Connectors
synchronized (connectorsLock) {
for (Connector connector : connectors) {
try {
connector.init();
} catch (Exception e) {
String message = sm.getString("standardService.connector.initFailed", connector);
log.error(message, e);
if (Boolean.getBoolean("org.apache.catalina.startup.EXIT_ON_INIT_FAILURE"))
throw new LifecycleException(message);
}
}
}
}
StandardService类的startInternal方法做了以下几件事:
- 启动解析server.xml过程中添加的Engine;
- 启动解析server.xml过程中添加的各Executor;
- 启动解析server.xml过程中添加的各Connector。
@Override
protected void startInternal() throws LifecycleException {
if(log.isInfoEnabled())
log.info(sm.getString("standardService.start.name", this.name));
setState(LifecycleState.STARTING);
// Start our defined Container first
if (engine != null) {
synchronized (engine) {
engine.start();
}
}
synchronized (executors) {
for (Executor executor: executors) {
executor.start();
}
}
mapperListener.start();
// Start our defined Connectors second
synchronized (connectorsLock) {
for (Connector connector: connectors) {
try {
// If it has already failed, don't try and start it
if (connector.getState() != LifecycleState.FAILED) {
connector.start();
}
} catch (Exception e) {
log.error(sm.getString(
"standardService.connector.startFailed",
connector), e);
}
}
}
}
Executor
Tomcat的Executor接口继承了Java的Executor接口,其唯一实现类是StandardThreadExecutor类,它同样继承了LifecycleMBeanBase类。它的initInternal方法很简单,没有做自己的事情。
@Override
protected void initInternal() throws LifecycleException {
super.initInternal();
}
StandardThreadExecutor类的startInternal方法如下:
@Override
protected void startInternal() throws LifecycleException {
taskqueue = new TaskQueue(maxQueueSize);
TaskThreadFactory tf = new TaskThreadFactory(namePrefix,daemon,getThreadPriority());
executor = new ThreadPoolExecutor(getMinSpareThreads(), getMaxThreads(), maxIdleTime, TimeUnit.MILLISECONDS,taskqueue, tf);
executor.setThreadRenewalDelay(threadRenewalDelay);
if (prestartminSpareThreads) {
executor.prestartAllCoreThreads();
}
taskqueue.setParent(executor);
setState(LifecycleState.STARTING);
}
- TaskThreadFactory实现了ThreadFactory接口,新线程的名字是namePrefix加计数,namePrefix在XML中有对应属性可以设置;
- 用上述线程工厂为自己创建了一个ThreadPoolExecutor。