Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

Tomcat elegantly shuts down the road

2025-01-16 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Servers >

Share

Shulou(Shulou.com)06/02 Report--

This article was first posted on the official account of Wechat, vivo Internet technology.

Link: https://mp.weixin.qq.com/s/ZqkmoAR4JEYr0x0Suoq7QQ

Author: Ma Yunjie

By reading the source code of the Tomcat startup and shutdown process, this article deeply analyzes the principles behind different Tomcat shutdown methods, so that developers can understand what they need to pay attention to when using different shutdown methods, and avoid a variety of unpredictable errors caused by the abnormal exit of the JVM process.

I. the startup process of Tomcat

To understand how Tomcat shuts down, you first need to look at how Tomcat is started. Let's give a brief introduction here.

The entry for Tomcat startup is the main method in the Bootstrap class, and then initialize Server, Service, Enigin, Connector, Host, Context, and other components according to the configuration in server.xml, and then start these components. Let's focus on what Tomcat has done since startup.

After the components of Tomcat are started, the main main thread enters the await () method of Catalina.out, which in turn mainly calls the await () method of the Server component, which, as you can see from the name, is intended to block the current thread (the main main thread).

Analyze the source code of await (the source code is relatively long, some of which are intercepted here, and all of them can be read by pulling the Tomcat source code on their own).

(StandardServer.await ())

We find that the await () method mainly does the following work based on the setting of the port attribute of the Server node in server.xml:

When port is-2, the function exits directly, and the main thread does not block.

When port is-1, set the waiting thread as the current thread and enter the while loop until the position of the stopAwait flag is true

When port is other, a new socket server is created, which binds the ip of the current server and the port port, then sets the waiting thread as the current thread, and the socket enters the blocking listening state until the socket listens to the closed string preset in the server.xml (default is "SHUTDOWN").

After the main thread exits and waits, it enters the Tomcat shutdown process and performs stop and destroy operations on each component. As can be seen from the above analysis, to stop Tomcat is to interrupt the wait state of the main main thread.

The following figure shows the entire life cycle of Tomcat.

(Tomcat Lifecycle)

Second, common ways to shut down Tomcat

1. Under the bin directory of the Tomcat package we downloaded, there is an official script (shutdown.sh) that can be used to end the Tomcat process.

2. On the server, we can also use the kill-x command to end the Tomcat process.

3. In addition, the occurrence of exceptions such as System.exit () and OOM in the code will also lead to the shutdown of the Tomcat process, but neither of them is a normal means of operation and maintenance, so we will not analyze them here.

Third, shutdown script 1, the principle of shutdown.sh

Looking at and analyzing the official shutdown.sh script and the catalina.sh script, it is found that the two scripts end up calling the main method of the Bootstrap class, and the same method is called when the Tomcat is started, the difference is that "stop" is passed in as the parameter of the main method, while the main method passed in this parameter will call the stopServer () method of the Catalina class. Here we erase the code that doesn't need attention, and we can simplify the entire stopServer () method to the following four steps:

It mainly does two things:

Initialize the Server component, which is similar to when Tomcat starts. This step is mainly to parse the server.xml file, and then initialize the member variables of the Tomcat component according to the attributes in server.xml. Here, we mainly focus on several member variables of the Server component: port, address, shutdown, with default values of 8005, 127.0.0.1, SHUTDOWN, etc., which need to be consistent with the server.xml read at startup.

The "SHUTDOWN" string occurs to the Socket port on which address port is listening.

At this point, it is obvious that this corresponds to the third blocking situation in the first section, where the "SHUTDOWN" string ends the wait state of the main main thread and then releases the resources by calling the stop () and destroy () methods of each component.

2. Disadvantages of shutdown script

Although the shutdown script is officially produced by Tomcat, it is not widely used in practice, mainly due to the following two shortcomings:

From the above principle, it can be analyzed that the shutdown script is based on listening to the corresponding port at startup, which allows anyone to shut down the Tomcat process as long as they can send the "SHUTDOWN" string to the corresponding port, which is quite dangerous to the production environment. Therefore, a typical production environment will set the port property of Server to-1

The shutdown script simply ends the wait state of the main main thread and allows it to go on normally. We know that threads in JVM can be divided into two types: daemon thread and user thread. Daemon threads will be automatically reclaimed after all user threads finish, resulting in the exit of the JVM process. The main main thread is a user thread, but as the program becomes more complex, there may be many other user threads. For example, in our usual development process, the common operation of creating a thread pool, Executors.newFixedThreadPool (n), will create n user threads, which will not be automatically recycled after the main thread of main exits, thus preventing the normal exit of JVM. So there are often scenarios where the shutdown script is called but the Tomcat process cannot exit. 4. Kill-x1, kill-9 or kill-15

The kill-x operation in Linux sends the corresponding semaphore to the target process. You can use the kill-l command to see the value of the semaphore that each numeric value represents.

(kill semaphore)

Here, we often use the command kill-9, kill-9 will immediately force the end of the current process, which is convenient but also very destructive. In the real environment, we may have tasks in running. If the program is forcibly closed at this time, it will lead to the loss of the data of the current task, especially for a very long time, which is very likely to cause the previous work to be wasted. At the same time, if the program is not designed properly and there is no corresponding idempotent operation, it may also cause the lack of data or dirty data in the actual environment, which will cause fatal problems to the production environment.

Compared to kill-9, kill-15 (15 is just an example, and there are other interrupt signals in Linux) is much more elegant. Kill-15 sends an interrupt semaphore of TERM to the process, and when the JVM receives the semaphore, it responds to the interrupt and ends the current process. The reason why this operation can gracefully shut down Tomcat is that before ending the current process, JVM will start a series of threads called shutdownhook (turn off hooks), and these threads will become our risk control tools. Let's first look at the close hook in Tomcat.

2. Shutdownhook close the hook

Tomcat's close hook is defined in the Catalina class, where there is an inner class called CatalinaShutdownHook, which inherits the Thread class. Following the run () method in this thread class, it calls the stop () method of Catalina, where the stop method, in addition to normally stopping the components, interrupts and quickly ends the main main thread (if the main thread still exists), and finally calls the destroy () method of each component to release resources.

(shutdownhook in Tomcat)

In addition to the fact that Tomcat uses close hooks, many middleware also use this very important feature.

We can also use closed hooks in the normal development process, and we can add hooks by calling the Runtime.getRuntime (). AddShutdownHook (shutdownHook) method at the start or run stage of the program, but it is important to note that the code to remove the hook needs to be added to the closed process.

Of course, there are applications for closing hooks in Spring, and it also provides a more friendly programming experience for us to use closed hooks.

In Spring, the close hook is added to the AbstractApplicationContext.registerShutdownHook () method (the code in the following figure), while its run method that closes the hook calls the destroyBeans () method, which calls its destroy () method on all classes that inherit the DisposableBean interface.

Read here we understand that in peacetime development, if there is a need to use closed hooks, we can inherit DisposableBean and achieve its destroy (), which is very convenient to achieve our goal of recycling resources and cleaning the battlefield.

3. Pay attention to the use of shutdownhook

Shutdownhook can not be misused at will, so you need to pay attention to the following points:

The order of shutdownhook calls is not guaranteed.

Shutdownhook is the thread called before the end of the JVM, so the methods in this thread should be as short as possible and ensure that deadlocks do not occur, otherwise the normal exit of JVM will be prevented.

System.exit () cannot be executed in shutdownhook, otherwise it will cause the virtual machine to get stuck and have to kill the process forcibly. 5. Summary

This paper interprets the principles of two commonly used shutdown methods of Tomcat. From the above analysis, we can see that there is a risk of permissions in using shutdown.sh scripts to control Tomcat shutdown, and Tomcat can not be closed because of thread operations in development, so this method is rarely used in practical applications.

On the other hand, kill-15 can safely kill the Tomcat process, and because of the existence of JVM shutdownhook, we can have stronger control over the whole program when it is closed, and the exit process is more elegant, so it is widely used.

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Servers

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report