First, when the start Tomcat, the various components of what has been done
When the execution startup.sh script to start Tomcat,
1, the Tomcat is essentially a Java program, so startup.sh script will start a startup class Bootstrap JVM to run the Tomcat
2, Bootstrap is initialized Tomcat class loader, and create Catalina
3, Catalina is a startup class that can parse server.xml, create the corresponding component and start method is called Server.
4, Server components used to manage Service components, it can call the start method of the Service
5, Service component of responsibility is the management of top-level container connector and Engine, it can call connector and Engine start method
二,Catalina
Catalina task is to create Server, it parses through server.xml, created out of the individual components configured in server.xml, then call the init method and the start method Server components, so that Tomcat started.
public void Start () { // 1. Server instance if the holder is empty, it parses out server.xml create IF (the getServer () == null ) { Load (); } // 2. If the creation fails, an error exit IF (getServer () == null ) { log.fatal (sm.getString ( " catalina.noServer " )); return ; } // 3. start Server the try { getServer () start ();. } the catch (LifecycleException E) { return ; } // create and register a shutdown hook if (useShutdownHook) { if (shutdownHook == null) { shutdownHook = new CatalinaShutdownHook(); } Runtime.getRuntime().addShutdownHook(shutdownHook); } // 用 await 方法监听停止请求 if (await) { await(); stop(); } }
So, Tomcat is how to stop and clean up the resources it?
First, Catalina in the JVM to register a "closed hook", the hook can do some cleanup when closed, such as the brush cached data to disk. This hook is actually a thread, JVM will try to run before stopping method to perform this thread.
CatalinaShutdownHook:
protected class CatalinaShutdownHook extends Thread { @Override public void run() { try { if (getServer() != null) { Catalina.this.stop(); } } catch (Throwable ex) { ... } } }
Tomcat "off the hook" is actually a stop on the implementation of the method Server, stop method Server will release and clean up all the resources.
Three, Server Components
Specific implementation class: StandardServer.
Subassemblies Server is Service, so it is to manage the lifecycle of Service. When Server starts, you need to call start method Service component, call their methods to stop when you stop. Server internally maintains a Service component, to save through the array. Server How to Add a Service to the array?
@Override public void addService (-Service-Service) { service.setServer ( the this ); the synchronized (servicesLock) { // create a new array length + -Service Results [] = new new -Service [services.length + . 1 ]; // will old data replication past System.arraycopy (Services, 0 , Results, 0 , services.length); Results [services.length] = Service; Services = Results; // start the Service component IF (getState () isAvailable ().) { the try { service.start (); } the catch (LifecycleException E) { // the Ignore } } // trigger event listener support.firePropertyChange ( " -Service " , null ,-Service); } }
Four, Service Component
Service implementation class components: StandardService.
public class StandardService the extends LifecycleBase the implements-Service { // Name Private String name = null ; // Server instance Private Server Server = null ; // connector array protected Connector Connectors [] = new new Connector [ 0 ]; Private Final Object connectorsLock = new new Object (); // a corresponding container Engine Private Engine Engine = null ; // mapper and listener protected Final mapper mapper = new new Mapper(); protected final MapperListener mapperListener = new MapperListener(this);
The components can be seen StandardService there: Connector, Engine, Mapper, MapperListener (which is a listener, when the Web application deployment changes to update the information in Mapper, use hot deployment).
StandardService in startup method:
protected void startInternal () throws LifecycleException { // 1. a trigger to start the listener the setState (LifecycleState.STARTING); // 2. First Start Engine, Engine starts its subcontainers IF (Engine =! null ) { the synchronized (Engine) { engine.start (); } } // 3. Mapper restart listener mapperListener.start (); // 4. Finally start connector, the connector sub-assembly will start it, such Endpoint the synchronized (connectorsLock) { for (connector Connector: Connectors) { IF (connector.getState () =! LifecycleState.FAILED) { connector.start (); } } } }
Note the boot sequence: first start Engine components, and then start Mapper listener, and finally start the connector. (In line with the first inner layer, the outer layer)
Five, Engine Components
Implementation class: StandardEngine, Engine is essentially a container, which inherits the base class ContainerBase, and implements the interface Engine
public class StandardEngine extends ContainerBase implements Engine { }
Engine sub-container is Host, which holds an array Host container,
CatalinaShutdownHook
Geek Time Copyright: https://time.geekbang.org/column/article/97603: