Understanding Tomcat Startup and Shutdown Mechanisms
Tomcat starts by Bootstrap.main reading server.xml, initializing components, then blocking in Server.await based on the shutdown port, while shutdown can be performed via the shutdown.sh script (sending a SHUTDOWN command), kill signals (preferably SIGTERM for graceful hooks), or custom JVM shutdown hooks, with the script posing security risks and often being replaced by kill‑15 combined with proper hooks in production.
This article analyzes the source code of Tomcat's startup and shutdown processes, explaining the principles behind different shutdown methods so developers can avoid unexpected errors caused by abnormal JVM termination.
1. Tomcat Startup Process
Tomcat starts via the Bootstrap.main method, which reads server.xml to initialize Server, Service, Engine, Connector, Host, Context, etc. After component initialization, the main thread calls Server.await() , which blocks the thread. The await method behaves differently based on the port attribute in server.xml :
port = -2: method returns immediately, no blocking.
port = -1: the current thread becomes the await thread and loops until a stop flag is set.
other values: a socket is opened on the specified port; the thread blocks until the socket receives the shutdown command (default "SHUTDOWN").
When the await loop ends, Tomcat proceeds to stop and destroy all components.
2. Common Tomcat Shutdown Methods
1) The official shutdown.sh script in the bin directory.
2) Using Linux kill commands (e.g., kill -9 , kill -15 ).
3) Programmatic termination via System.exit() or OOM, which are not recommended operationally.
3. shutdown.sh Script
The script ultimately invokes Bootstrap.main with the argument "stop", which calls Catalina.stopServer() . The simplified steps are:
It reinitializes the Server component (parsing server.xml to obtain port , address , shutdown ) and then sends the "SHUTDOWN" string to the listening socket.
Drawbacks:
Anyone who can reach the shutdown port can stop Tomcat, posing a security risk; production often sets port=-1 .
The script only ends the main thread's await state. User threads (e.g., thread pools) may keep the JVM alive, preventing graceful exit.
4. kill Signals
kill -9 forcefully terminates the process, risking data loss. kill -15 (SIGTERM) allows the JVM to run shutdown hooks, enabling a more graceful shutdown.
5. JVM Shutdown Hooks
Tomcat defines a CatalinaShutdownHook (extends Thread ) that calls Catalina.stop() , which stops components, interrupts the main thread, and destroys resources.
Developers can register custom hooks via Runtime.getRuntime().addShutdownHook(...) . In Spring, AbstractApplicationContext.registerShutdownHook() registers a hook that invokes destroyBeans() for beans implementing DisposableBean .
Guidelines for using shutdown hooks:
Invocation order is not guaranteed.
Hooks should be short and avoid deadlocks.
Do not call System.exit() inside a hook.
6. Summary
The article explains two common Tomcat shutdown mechanisms. The shutdown.sh script poses security and thread‑lifecycle issues, so it is less used in production. Using kill -15 together with JVM shutdown hooks provides a safer and more controllable way to stop Tomcat.
vivo Internet Technology
Sharing practical vivo Internet technology insights and salon events, plus the latest industry news and hot conferences.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.