文章目录
0.前记
在之前的文章中, Tomcat
启动过程, 通过Bootstrap.main
方法中, 先获取到3种类加载器, 然后通过digester
加载server.xml
文件, 然后初始化服务器端的各个组件。
这一篇文章介绍初始化后然后Tomcat
启动的过程。
Bootstrap.main()
1.通过Catalina.start()启动服务器
通过反射调用Catalina.start()
LifecycleBase.start()
- 通过组件的状态进行判断, 为状态模式
- 留给子类一个扩展的接口
startInternal
2.各个组件的启动流程
StandardServer.startInternal()
@Override
protected void startInternal() throws LifecycleException {
fireLifecycleEvent(CONFIGURE_START_EVENT, null);
setState(LifecycleState.STARTING);
globalNamingResources.start(); // 启动JNDI服务
//启动所有service Start our defined Services
synchronized (servicesLock) {
for (Service service : services) {
service.start(); //启动所有的Service
}
}
if (periodicEventDelay > 0) {
monitorFuture = getUtilityExecutor().scheduleWithFixedDelay(
() -> startPeriodicLifecycleEvent(), 0, 60, TimeUnit.SECONDS);
}
}
- 先是
globalNamingResources
开启, 开启JNDI服务 - 启动所有是
service
服务
StandardService.startInternal()
@Override
protected void startInternal() throws LifecycleException {
// Start our defined Container first
if (engine != null) {
synchronized (engine) {
engine.start(); //启动引擎,部署项目
}
}
// Start our defined Connectors second
synchronized (connectorsLock) {
for (Connector connector: connectors) {
// If it has already failed, don't try and start it
if (connector.getState() != LifecycleState.FAILED) {
connector.start();
}
}
}
}
- 开启
engine
- 开启
connector
2.1 开启Engine
StandardEngine.startInternal()
@Override //模板方法的实现,定义引擎的启动方法
protected synchronized void startInternal() throws LifecycleException {
// Standard container startup
super.startInternal();
}
ContainerBase.startInternal()
@Override
protected synchronized void startInternal() throws LifecycleException {
// Start our subordinate components, if any
logger = null;
getLogger();
Cluster cluster = getClusterInternal();
if (cluster instanceof Lifecycle) {
((Lifecycle) cluster).start(); //在此启动集群组件
}
Realm realm = getRealmInternal();
if (realm instanceof Lifecycle) {
((Lifecycle) realm).start();
}
// Start our child containers, if any
Container children[] = findChildren();
List<Future<Void>> results = new ArrayList<>();
for (Container child : children) {
results.add(startStopExecutor.submit(new StartChild(child)));
}
MultiThrowable multiThrowable = null;
for (Future<Void> result : results) {
try {
result.get(); //获取异步的执行结果
} catch (Throwable e) {
log.error(sm.getString("containerBase.threadedStartFailed"), e);
if (multiThrowable == null) {
multiThrowable = new MultiThrowable();
}
multiThrowable.add(e);
}
}
//启动管道 Start the Valves in our pipeline (including the basic), if any
if (pipeline instanceof Lifecycle) {
((Lifecycle) pipeline).start(); //管道的启动,里面所有的阀门启动,阀门设置个状态
}
setState(LifecycleState.STARTING);
// Start our thread
if (backgroundProcessorDelay > 0) {
monitorFuture = Container.getService(ContainerBase.this).getServer()
.getUtilityExecutor().scheduleWithFixedDelay(
new ContainerBackgroundProcessorMonitor(), 0, 60, TimeUnit.SECONDS);
}
}
- 启动集群组件
- 启动realm组件
- 将虚拟主机Host封装为
StartChild
, 这个是一个Callback, 交给了线程池执行。 - 启动自己的
pipline
管道
2.2 开启Connector
Connector.startInternal()
@Override //连接器启动
protected void startInternal() throws LifecycleException {
// Validate settings before starting
// Connector创建对象的无参构造器默认就指定了使用http11protocolHandler
String id = (protocolHandler != null) ? protocolHandler.getId() : null;
if (id == null && getPortWithOffset() < 0) {
throw new LifecycleException(sm.getString(
"coyoteConnector.invalidPort", Integer.valueOf(getPortWithOffset())));
}
setState(LifecycleState.STARTING);
try {
protocolHandler.start(); //协议处理器启动
} catch (Exception e) {
throw new LifecycleException(
sm.getString("coyoteConnector.protocolHandlerStartFailed"), e);
}
}
-
Connector
创建对象的无参构造器默认就指定了使用http11protocolHandler
- 开启协议处理器
protocolHandler
AbstractProticol.start()
@Override
public void start() throws Exception {
if (getLog().isInfoEnabled()) {
getLog().info(sm.getString("abstractProtocolHandler.start", getName()));
logPortOffset();
}
endpoint.start(); //端点启动
monitorFuture = getUtilityExecutor().scheduleWithFixedDelay(
() -> {
if (!isPaused()) {
startAsyncTimeout();
}
}, 0, 60, TimeUnit.SECONDS);
}
AbstractEndPoint,start()
NioEndpoint.startInternal()
@Override
public void startInternal() throws Exception {
if (!running) { //开始启动端点
running = true;
paused = false;
if (socketProperties.getProcessorCache() != 0) {
processorCache = new SynchronizedStack<>(SynchronizedStack.DEFAULT_SIZE,
socketProperties.getProcessorCache());
}
if (socketProperties.getEventCache() != 0) {
eventCache = new SynchronizedStack<>(SynchronizedStack.DEFAULT_SIZE,
socketProperties.getEventCache());
}
if (socketProperties.getBufferPool() != 0) {
nioChannels = new SynchronizedStack<>(SynchronizedStack.DEFAULT_SIZE,
socketProperties.getBufferPool());
}
//创建worker线程组(干活的人) Create worker collection
if (getExecutor() == null) {
createExecutor(); //默认worker线程池10个线程等待处理
}
initializeConnectionLatch(); //连接限流的,最大处理8192条连接
// 单线程启动poller
//启动一个poller;拉取者?????? Start poller thread
poller = new Poller();
Thread pollerThread = new Thread(poller, getName() + "-ClientPoller");
pollerThread.setPriority(threadPriority);
pollerThread.setDaemon(true);
pollerThread.start();
//启动接受者线程
// 单线程启动Accepter 8080
startAcceptorThread();
}
}
- 启动worker线程池, 默认为10个
- 单线程启动Poller
- 单线程准备一个Acceptor: 通过ServerSocket.accept 一直接受数据
3.Cataliona.await()方法等待数据
StandardServer.await()
与底层的jdk
的serverSocket
建立了关系, 通过accpet
接收数据