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()
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值