Tomcat 启动流程

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;
        }
    }
    
}

流程

  1. ApplicationContext.refreshContext()
  2. AbstractApplicationContext.refresh()
  3. ServletWebServerApplicationContext.onRefresh()
  4. ServletWebServerApplicationContext.createWebServer()
  5. TomcatServletWebServerFactory.getWebServer()
  6. new TomcatWebServer()
  7. TomcatWebServer.initialize()
  8. Tomcat.start()
  9. StandandServer.start()
  10. StandandService.start()
    1. StandandEngine.start()
      1. StandandHost.start()
        1. StandandContext.start()
          1. StandandWrapper.start()
          2. StandandPipeline.start()
        2. StandandPipeline.start()
      2. StandandPipeline.start()
    2. Connector.start()
    3. Executor.start()
    4. StandandPipeline.start()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值