Recently, both school and social recruitment have been in full bloom. I also undertook a lot of interviews. During an interview, I talked with candidates about Dubbo.
Dubbo is a well-known RPC framework, many people have a certain understanding of some of its network communication, communication protocol, dynamic proxy and so on, so does this candidate.
However, I then asked him a question: how do you guarantee that a request won’t be interrupted if the application restarts while using Dubbo?
He didn’t say much, and I thought he didn’t understand my question, so I asked him: I just want to ask Dubbo how to do graceful up-and-down, do you know?
Then he asked me, “What is graceful up-and-down?”
All right.
In this article, LET me introduce this knowledge point.
Graceful up and down line
I can’t find an official explanation for the term “graceful up-and-down,” but I’ll try to explain what it is.
First of all, we must be very clear about the online and offline, for example, in the process of an application release, we need to stop the application service first, and then start the service. This achievement consists of one offline and one online.
So, what does “elegant” mean?
Let’s start with what we think is not elegant:
1. When the service stops, the corresponding monitoring is not closed, resulting in a large number of alarms after the application stops.
2. When the application stops, external callers are not notified, and many requests will still come, resulting in many failed calls.
3. When the application stops, a thread is in progress, and the JVM process is killed in the middle of execution.
4. When the application starts, the service is not ready and starts to provide services externally, resulting in many failed calls.
5. When the application is started, it starts to provide services without checking the health status of the application, resulting in many failed calls.
The above, are we think of the inelegant situation, then, in turn, elegant up and down line is a means to avoid the above situation.
In fact, there are a lot of content involved in the elegant up and down of an application, from the underlying operating system, container level, to the level of programming language, framework, and then to the level of application architecture, involving a wide range of knowledge.
Actually, in elegant fluctuation line, the most important or elegant get off line. If the offline process is not elegant, many calls fail, services cannot be found, and so on. So a lot of times, people talk about elegant downtime.
Graceful up-and-down, described later in this article, also focuses on the process of graceful downtime.
Operating system & container graceful up and down line
In an earlier article on operating systems, I wrote on the topic of why you can’t execute kill -9 on your machine online.
In fact, the thinking behind this is graceful up and down the line.
We know that kill-9 is not recommended because it is so tough that the system sends a SIGKILL signal, which requires that any program receiving this signal terminate immediately and not be blocked or ignored.
This process is obviously inelegant, because if the application stops immediately, there is no way to finish. A more elegant way is to kill -15.
When using kill -15, the system sends a SIGTERM signal to the corresponding program. Once the program receives the signal, what it does with it is up to it.
Kill-15 notifies the application, which is the most basic operating system support for gracefully logging on and off.
In the past, on the operating system is the application, but since the introduction of containerization technology, between the operating system and the application, there is a container layer, and Docker, K8S and other containers are also support elegant online.
For example, Docker also provides two commands, Docker stop and Docker kill
Docker Stop, like kill -15, sends SIGTERM to the process inside the container, and then sends SIGKILL 10 seconds later (as specified by the parameter).
Docker kill, like kill-9, sends SIGKILL signals directly.
Graceful up-and-down of the JVM
After the operating system, container and other basic support for graceful online and offline, after receiving docker stop, kill -15 and other commands, the application process will be notified to shut down the process.
At runtime, a Java application is a standalone process. How is this process shut down?
The termination of Java program is realized based on the shutdown of JVM, which can be divided into normal shutdown, forced shutdown and abnormal shutdown.
Among them, the normal off is to support elegant online. During a normal shutdown, the JVM can perform some cleanup actions, such as deleting temporary files.
Of course, developers can also customize to do additional things, such as notifying the application framework of graceful online and offline operations.
This mechanism is implemented through the Shutdown hook provided in the JDK. Provides the Java JDK. Runtime. AddShutdownHook (Thread hook) method, you can register a JVM closed hook.
Examples are as follows:
package com.hollis; public class ShutdownHookTest { public static void main(String[] args) { boolean flag = true; Runtime.getRuntime().addShutdownHook(new Thread(() -> { System.out.println("hook execute..." ); })); while (flag) { // app is runing } System.out.println("main thread execute end..." ); }}Copy the code
Execute command:
➜ jps
6520 ShutdownHookTest
6521 Jps
➜ kill 6520
Copy the code
Console output:
hook execute...
Process finished with exit code 143 (interrupted by signal 15: SIGTERM)
Copy the code
As you can see, when shutting down the process using kill (default kill -15), the program will execute the shutdownHook I registered and then exit with a warning: Interrupted by Signal 15: SIGTERM
Spring’s elegant up-and-down
With the SHUTDOWN hook provided by the JVM, many frameworks can use this mechanism to support graceful logoff.
Spring, for example, registers a shutdown hook with the JVM to execute bean destruction, container destruction, and so on upon receiving a shutdown notification.
At the same time, Spring, as a mature framework, also provides an event mechanism that allows for more elegant online and offline functionality.
ApplicationListener is part of Spring’s event mechanism and works with the abstract ApplicationEvent class to implement the event mechanism of ApplicationContext.
Developers can implement the ApplicationListener interface to listen for ContextClosedEvent to do special processing:
@Component public class MyListener implements ApplicationListener<ContextClosedEvent> { @Override public void OnApplicationEvent (ContextClosedEvent event) {// Do the cleanup before closing the container}}Copy the code
Dubbo’s elegant up and down line
Because Spring provides the ApplicationListener interface to help us listen for container closure events, many Web containers, frameworks, and so on can use this mechanism to do their own elegant inline and offline operations.
Such as Tomcat, Dubbo and so on do this.
Here’s a brief description of Dubbo. On Dubbo’s website, there is an introduction about elegant downtime:
When an application receives a shutdown notification, it marks itself as not accepting (initiating) new requests, and then waits 10 seconds (the default is 10 seconds) for the executing thread to finish executing.
Well, he can do this because everything from the operating system to the JVM to Spring supports elegant downtime.
One of my colleagues wrote an article about how Dubbo’s JVM shutdown hook, or Spring’s event mechanism, was used to shutdown gracefully last night.
www.cnkirito.moe/dubbo-grace…
Dubbo 2.5 to Dubbo 2.7 introduces the history of Dubbo to solve the elegant offline problems and solutions.
Dubbo is currently implemented as follows, using the same Spring event mechanism:
public class SpringExtensionFactory implements ExtensionFactory { public static void addApplicationContext(ApplicationContext context) { CONTEXTS.add(context); if (context instanceof ConfigurableApplicationContext) { ((ConfigurableApplicationContext) context).registerShutdownHook(); DubboShutdownHook.getDubboShutdownHook().unregister(); } BeanFactoryUtils.addApplicationListener(context, SHUTDOWN_HOOK_LISTENER); }}Copy the code
conclusion
Starting with operating systems, this article introduces Linux, Docker, JVM, Spring, Dubbo, and more for elegant downtime support.
As you can see, a simple and elegant shutdown function requires so much infrastructure and application support upstream and downstream.
I believe that through learning this article, you must have more understanding of the elegant up and down line.
In addition, I hope that when you encounter some practical problems after reading this article, you can think of shutdown Hook mechanism and Spring event mechanism mentioned in the article. In many cases, these mechanisms help us solve a lot of problems.
I’ve used this mechanism many times in my work, and I’ll give you a few examples later.
Reference:
zhuanlan.zhihu.com/p/29093407
www.cnkirito.moe/dubbo-grace…
About the author: Hollis, a person with a unique pursuit of Coding, is a technical expert of Alibaba, co-author of “Three Courses for Programmers”, and author of a series of articles “Java Engineers becoming Gods”.
Follow the public account [Hollis], the background reply “into god map” can be downloaded to receive the Java engineer advanced mind map.