tomcat
架构
-
Server
server是tomcat的顶级容器 tomcat的生命周期由server控制
一个tomcat可以有1个server
一个server可以有多个service
-
Service
service是server的子容器 由Connector和Container组成
一个server可以有多个service
一个service包含多个Connector和1个Container
- Connector
- Container(Engine)
-
Host
-
Context
- Wrapper
-
-
-
springboot嵌入式tomcat启动原理
接口
public interface WebServer {
/**
* Starts the web server. Calling this method on an already started server has no
* effect.
* @throws WebServerException if the server cannot be started
*/
void start() throws WebServerException;
/**
* Stops the web server. Calling this method on an already stopped server has no
* effect.
* @throws WebServerException if the server cannot be stopped
*/
void stop() throws WebServerException;
/**
* Return the port this server is listening on.
* @return the port (or -1 if none)
*/
int getPort();
/**
* Initiates a graceful shutdown of the web server. Handling of new requests is
* prevented and the given {@code callback} is invoked at the end of the attempt. The
* attempt can be explicitly ended by invoking {@link #stop}. The default
* implementation invokes the callback immediately with
* {@link GracefulShutdownResult#IMMEDIATE}, i.e. no attempt is made at a graceful
* shutdown.
* @param callback the callback to invoke when the graceful shutdown completes
* @since 2.3.0
*/
default void shutDownGracefully(GracefulShutdownCallback callback) {
callback.shutdownComplete(GracefulShutdownResult.IMMEDIATE);
}
}
public interface Server extends Lifecycle {
}
public interface Service extends Lifecycle {
}
public interface Container extends Lifecycle {
}
public interface Lifecycle {
public void init() throws LifecycleException;
public void start() throws LifecycleException;
public void stop() throws LifecycleException;
}
实现
ServletWebServerApplicationContext
- factory.getWebServer
public class ServletWebServerApplicationContext extends GenericWebApplicationContext implements ConfigurableWebServerApplicationContext {
//创建一个webServer
private void createWebServer() {
WebServer webServer = this.webServer;
ServletContext servletContext = this.getServletContext();
if (webServer == null && servletContext == null) {
StartupStep createWebServer = this.getApplicationStartup().start("spring.boot.webserver.create");
ServletWebServerFactory factory = this.getWebServerFactory();
createWebServer.tag("factory", factory.getClass().toString());
this.webServer = factory.getWebServer(new ServletContextInitializer[]{this.getSelfInitializer()});
createWebServer.end();
this.getBeanFactory().registerSingleton("webServerGracefulShutdown", new WebServerGracefulShutdownLifecycle(this.webServer));
this.getBeanFactory().registerSingleton("webServerStartStop", new WebServerStartStopLifecycle(this, this.webServer));
} else if (servletContext != null) {
try {
//初始化servlet
this.getSelfInitializer().onStartup(servletContext);
} catch (ServletException var5) {
throw new ApplicationContextException("Cannot initialize servlet context", var5);
}
}
this.initPropertySources();
}
}
TomcatServletWebServerFactory
- new Tomcat()
- new Connector(this.protocol)
- new TomcatWebServer(tomcat, this.getPort() >= 0, this.getShutdown())
//TocmatServer工厂
public class TomcatServletWebServerFactory extends AbstractServletWebServerFactory implements ConfigurableTomcatWebServerFactory, ResourceLoaderAware {
//返回一个tomcat webServer
public WebServer getWebServer(ServletContextInitializer... initializers) {
if (this.disableMBeanRegistry) {
Registry.disableRegistry();
}
Tomcat tomcat = new Tomcat();
File baseDir = this.baseDirectory != null ? this.baseDirectory : this.createTempDir("tomcat");
tomcat.setBaseDir(baseDir.getAbsolutePath());
Connector connector = new Connector(this.protocol);
connector.setThrowOnFailure(true);
tomcat.getService().addConnector(connector);
//配置connector
this.customizeConnector(connector);
tomcat.setConnector(connector);
tomcat.getHost().setAutoDeploy(false);
//配置engine
this.configureEngine(tomcat.getEngine());
Iterator var5 = this.additionalTomcatConnectors.iterator();
while(var5.hasNext()) {
Connector additionalConnector = (Connector)var5.next();
tomcat.getService().addConnector(additionalConnector);
}
this.prepareContext(tomcat.getHost(), initializers);
return this.getTomcatWebServer(tomcat);
}
protected TomcatWebServer getTomcatWebServer(Tomcat tomcat) {
return new TomcatWebServer(tomcat, this.getPort() >= 0, this.getShutdown());
}
}
TomcatWebServer
- tomcat.start()
//主要是启动tomcat
public class TomcatWebServer implements WebServer {
//tomcat
private final Tomcat tomcat;
//自动启动
private final boolean autoStart;
//优雅停机
private final GracefulShutdown gracefulShutdown;
public TomcatWebServer(Tomcat tomcat, boolean autoStart, Shutdown shutdown) {
Assert.notNull(tomcat, "Tomcat Server must not be null");
this.tomcat = tomcat;
this.autoStart = autoStart;
this.gracefulShutdown = (shutdown == Shutdown.GRACEFUL) ? new GracefulShutdown(tomcat) : null;
//初始化
initialize();
}
//初始化
private void initialize() throws WebServerException {
logger.info("Tomcat initialized with port(s): " + getPortsDescription(false));
synchronized (this.monitor) {
try {
addInstanceIdToEngineName();
Context context = findContext();
//添加生命周期侦听器
context.addLifecycleListener((event) -> {
if (context.equals(event.getSource()) && Lifecycle.START_EVENT.equals(event.getType())) {
// Remove service connectors so that protocol binding doesn't
// happen when the service is started.
removeServiceConnectors();
}
});
//启动tomcat
// Start the server to trigger initialization listeners
this.tomcat.start();
// We can re-throw failure exception directly in the main thread
rethrowDeferredStartupExceptions();
try {
ContextBindings.bindClassLoader(context, context.getNamingToken(), getClass().getClassLoader());
}
catch (NamingException ex) {
// Naming is not enabled. Continue
}
// Unlike Jetty, all Tomcat threads are daemon threads. We create a
// blocking non-daemon to stop immediate shutdown
startDaemonAwaitThread();
}
catch (Exception ex) {
stopSilently();
destroySilently();
throw new WebServerException("Unable to start embedded Tomcat", ex);
}
}
}
}
Tomcat
- server.start()
public class Tomcat {
//顶级的Server容器
protected Server server;
//端口 主机 目录
protected int port = 8080;
protected String hostname = "localhost";
protected String basedir;
//server.xml 配置文件中
//用户和密码
private final Map<String, String> userPass = new HashMap<>();
//用户和角色
private final Map<String, List<String>> userRoles = new HashMap<>();
//用户主体信息
private final Map<String, Principal> userPrincipals = new HashMap<>();
//tomcat启动
//先设置server
//server启动
public void start() throws LifecycleException {
getServer();
server.start();
}
}
standandserver没有重写start方法,实现了startInternal 方法和initInternal方法
直接使用父类 LifecycleBase 的 start 方法
在start方法中调用子类 standserver.initInternal 和 standserver.startInternal
public abstract class LifecycleBase implements Lifecycle {
//server生命周期启动
//这里考虑standandserver的
public final synchronized void start() throws LifecycleException {
//如果状态已经启动 直接返回
if (LifecycleState.STARTING_PREP.equals(state) || LifecycleState.STARTING.equals(state) ||
LifecycleState.STARTED.equals(state)) {
if (log.isDebugEnabled()) {
Exception e = new LifecycleException();
log.debug(sm.getString("lifecycleBase.alreadyStarted", toString()), e);
} else if (log.isInfoEnabled()) {
log.info(sm.getString("lifecycleBase.alreadyStarted", toString()));
}
return;
}
//如果是new状态 先初始化
//如果是失败状态 直接stop
//如果是已经初始化 或者 已停止 那就验证一下 ? 验证什么
if (state.equals(LifecycleState.NEW)) {
init();
} else if (state.equals(LifecycleState.FAILED)) {
stop();
} else if (!state.equals(LifecycleState.INITIALIZED) &&
!state.equals(LifecycleState.STOPPED)) {
invalidTransition(Lifecycle.BEFORE_START_EVENT);
}
try {
//设置状态为 准备启动
setStateInternal(LifecycleState.STARTING_PREP, null, false);
//启动
startInternal();
//判断状态是否成功
if (state.equals(LifecycleState.FAILED)) {
// This is a 'controlled' failure. The component put itself into the
// FAILED state so call stop() to complete the clean-up.
stop();
} else if (!state.equals(LifecycleState.STARTING)) {
// Shouldn't be necessary but acts as a check that sub-classes are
// doing what they are supposed to.
invalidTransition(Lifecycle.AFTER_START_EVENT);
} else {
setStateInternal(LifecycleState.STARTED, null, false);
}
} catch (Throwable t) {
// This is an 'uncontrolled' failure so put the component into the
// FAILED state and throw an exception.
handleSubClassException(t, "lifecycleBase.startFail", toString());
}
}
//执行初始化
public final synchronized void init() throws LifecycleException {
if (!state.equals(LifecycleState.NEW)) {
invalidTransition(Lifecycle.BEFORE_INIT_EVENT);
}
try {
setStateInternal(LifecycleState.INITIALIZING, null, false);
initInternal();
setStateInternal(LifecycleState.INITIALIZED, null, false);
} catch (Throwable t) {
handleSubClassException(t, "lifecycleBase.initFail", toString());
}
}
}
StandandServer
- initInternal
- service.init()
- startInternal
- service.start()
public final class StandardServer extends LifecycleMBeanBase implements Server {
private int port = 8005;
private String address = "localhost";
private Service services[] = new Service[0];
//两个线程池
private ScheduledThreadPoolExecutor utilityExecutor = null;
private ScheduledExecutorService utilityExecutorWrapper = null;
//初始化server容器
//循环调用service.init()的方法 初始化service容器
protected void initInternal() throws LifecycleException {
super.initInternal();
// Initialize utility executor
reconfigureUtilityExecutor(getUtilityThreadsInternal(utilityThreads));
register(utilityExecutor, "type=UtilityExecutor");
// Register global String cache
// Note although the cache is global, if there are multiple Servers
// present in the JVM (may happen when embedding) then the same cache
// will be registered under multiple names
onameStringCache = register(new StringCache(), "type=StringCache");
// Register the MBeanFactory
MBeanFactory factory = new MBeanFactory();
factory.setContainer(this);
onameMBeanFactory = register(factory, "type=MBeanFactory");
// Register the naming resources
globalNamingResources.init();
// Populate the extension validator with JARs from common and shared
// class loaders
if (getCatalina() != null) {
ClassLoader cl = getCatalina().getParentClassLoader();
// Walk the class loader hierarchy. Stop at the system class loader.
// This will add the shared (if present) and common class loaders
while (cl != null && cl != ClassLoader.getSystemClassLoader()) {
if (cl instanceof URLClassLoader) {
URL[] urls = ((URLClassLoader) cl).getURLs();
for (URL url : urls) {
if (url.getProtocol().equals("file")) {
try {
File f = new File (url.toURI());
if (f.isFile() &&
f.getName().endsWith(".jar")) {
ExtensionValidator.addSystemResource(f);
}
} catch (URISyntaxException | IOException e) {
// Ignore
}
}
}
}
cl = cl.getParent();
}
}
// Initialize our defined Services
for (Service service : services) {
service.init();
}
}
//启动server容器
//调用service的start方法
//启动service的生命周期
//注意server中有多个service
protected void startInternal() throws LifecycleException {
fireLifecycleEvent(CONFIGURE_START_EVENT, null);
setState(LifecycleState.STARTING);
globalNamingResources.start();
// Start our defined Services
synchronized (servicesLock) {
for (Service service : services) {
service.start();
}
}
if (periodicEventDelay > 0) {
monitorFuture = getUtilityExecutor().scheduleWithFixedDelay(
() -> startPeriodicLifecycleEvent(), 0, 60, TimeUnit.SECONDS);
}
}
}
StandardService
- initInternal
- startInternal
- engine.start()
- executor.start()
- connector.start()
public class StandardService extends LifecycleMBeanBase implements Service {
private String name = null;
private Server server = null;
protected Connector connectors[] = new Connector[0];
protected final ArrayList<Executor> executors = new ArrayList<>();
private Engine engine = null;
//初始化service容器
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) {
connector.init();
}
}
}
//启动service容器
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) {
// If it has already failed, don't try and start it
if (connector.getState() != LifecycleState.FAILED) {
connector.start();
}
}
}
}
}
Engine:
-
initInternal
-
startInternal
调用父类 ContainerBase 来启动
public class StandardEngine extends ContainerBase implements Engine {
private String defaultHost = null;
private Service service = null;
protected void initInternal() throws LifecycleException {
// Ensure that a Realm is present before any attempt is made to start
// one. This will create the default NullRealm if necessary.
getRealm();
super.initInternal();
}
protected synchronized void startInternal() throws LifecycleException {
// Log our server identification information
if (log.isInfoEnabled()) {
log.info(sm.getString("standardEngine.start", ServerInfo.getServerInfo()));
}
// Standard container startup
super.startInternal();
}
}
ContainerBase:
-
initInternal
配置线程池
-
startInternal
通过线程池逐个启动子容器
public abstract class ContainerBase extends LifecycleMBeanBase
implements Container {
//子容器
protected final HashMap<String, Container> children = new HashMap<>();
//容器名
protected String name = null;
//流水线
protected final Pipeline pipeline = new StandardPipeline(this);
//权限
private volatile Realm realm = null;
//线程池
protected ExecutorService startStopExecutor;
protected void initInternal() throws LifecycleException {
reconfigureStartStopExecutor(getStartStopThreads());
super.initInternal();
}
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);
}
}
if (multiThrowable != null) {
throw new LifecycleException(sm.getString("containerBase.threadedStartFailed"),
multiThrowable.getThrowable());
}
// 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);
}
}
//添加子容器
private void addChildInternal(Container child) {
if (log.isDebugEnabled()) {
log.debug("Add child " + child + " " + this);
}
synchronized(children) {
if (children.get(child.getName()) != null)
throw new IllegalArgumentException(
sm.getString("containerBase.child.notUnique", child.getName()));
child.setParent(this); // May throw IAE
children.put(child.getName(), child);
}
fireContainerEvent(ADD_CHILD_EVENT, child);
// Start child
// Don't do this inside sync block - start can be a slow process and
// locking the children object can cause problems elsewhere
try {
if ((getState().isAvailable() ||
LifecycleState.STARTING_PREP.equals(getState())) &&
startChildren) {
child.start();
}
} catch (LifecycleException e) {
throw new IllegalStateException(sm.getString("containerBase.child.start"), e);
}
}
//子容器启动线程
private static class StartChild implements Callable<Void> {
private Container child;
public StartChild(Container child) {
this.child = child;
}
@Override
public Void call() throws LifecycleException {
child.start();
return null;
}
}
}
流程
- ApplicationContext.refreshContext()
- AbstractApplicationContext.refresh()
- ServletWebServerApplicationContext.onRefresh()
- ServletWebServerApplicationContext.createWebServer()
- TomcatServletWebServerFactory.getWebServer()
- new TomcatWebServer()
- TomcatWebServer.initialize()
- Tomcat.start()
- StandandServer.start()
- StandandService.start()
- StandandEngine.start()
- StandandHost.start()
- StandandContext.start()
- StandandWrapper.start()
- StandandPipeline.start()
- StandandPipeline.start()
- StandandContext.start()
- StandandPipeline.start()
- StandandHost.start()
- Connector.start()
- Executor.start()
- StandandPipeline.start()
- StandandEngine.start()