前言
记得tomcat有热部署功能吗?只要往webapp文件夹下新增war包,那么该war包就会被解析并生成一个应用,ContainerBackgroundProcessor线程就是负责扫描的工作的,backgroundProcessorDelay参数作用是控制如何拉起ContainerBackgroundProcessor线程的!
1. 什么是backgroundProcessorDelay参数,有什么用
Tomcat的Engine
会启动一个线程(就是ContainerBackgroundProcessor),该线程每10s
会发送一个发送一个事件,监听到该事件的部署配置类会自动去扫描webapp文件夹下的war包,将其加载成一个Context,即启动一个web服务。同时,该线程还会调用子容器Engine、Host、Context、Wrapper各容器组件及与它们相关的其它组件的backgroundProcess方法。
容器类的基类ContainerBase
拥有一个重要属性backgroundProcessorDelay
,默认为-1
,在StandardEngine
里面设置成了10
,其余的容器如StandardContext、StandardHost都仍然为-1
,只有该值属性为正数才能启动ContainerBackgroundProcessor线程。
org.apache.catalina.core.ContainerBase {
//默认值为-1
protected int backgroundProcessorDelay = -1
}
org.apache.catalina.core.StandardEngine {
public StandardEngine() {
super();
....
//定制值为10
backgroundProcessorDelay = 10;
}
}
所以只有StandardEngine
会启动ContainerBackgroundProcessor
线程:
2. ContainerBackgroundProcessor
2.1 该线程的启动过程
如图所示,在启动的步骤中,由context>service>engine顺序执行,再往下就是host>context,每个容器类都会执行到容器类的基类ContainerBase
的threadStart():
protected void threadStart() {
if (thread != null)
return;
//只有engine符合条件
if (backgroundProcessorDelay <= 0)
return;
threadDone = false;
String threadName = "ContainerBackgroundProcessor[" + toString() + "]";
thread = new Thread(new ContainerBackgroundProcessor(), threadName);
thread.setDaemon(true);
thread.start();
}
但是只有engine符合条件,因此这个线程只会由engine创建,一个engine下就这一个线程。
2.2 这个线程干了什么
ContainerBackgroudProcessor线程每隔backgroundProcessorDelay秒去执行递归指定自己及子容器的backgroundProcessor方法。由于backgroundProcessorDelay大于0的容器会有一个自己的ContainerBackgroudProcessor线程,所以只会执行backgroundProcessorDelay不大于0的子容器的backgroundProcessor方法。
参考:《记一次tomcat程序CPU占用高排backgroundProcessorDelay参数》
《Tomcat处理过期Session》