preface

As online applications are built using SpringBoot, there are more and more SpringBoot application instances. When an online application needs to be upgraded and deployed, you often run the kill command to stop the application. In this way, the application dismisses all requests in process and fails to respond. Such response failures are particularly important to avoid when dealing with important business logic, so what better way to smoothly shut down a SpringBoot application? Then through this article to explore it. (This article focuses on applications based on Spring Boot embedded Tomcat containers as Web services)

The sample code for this article can be obtained from the following repository address:

  • Springboot-shutdown:github.com/wrcj12138aa…

Environment support:

  • JDK 8
  • SpringBoot 2.1.4
  • Maven 3.6.0

Customize Tomcat Connector behavior

The prerequisite for a smooth closing of a Spring Boot application is to first close its built-in Web container and stop processing incoming requests from outside. In order to make application to accept close the event notification, guarantee the Tomcat handle all have entered the request, we need to implement TomcatConnectorCustomizer interface, the interface of the source code is very simple, As you can see from the comment, this is a callback interface to implement custom Tomcat Connector behavior:

If you are not familiar with Connector, I will describe it briefly: Connector is an abstract component of Tomcat. The function of Connector is to accept external requests and internal transmission, and return the response content. It is an important component of Tomcat request processing and response, including HTTP Connector and AJP Connector.

By customizing the behavior of the Connector, we can allow the Tomcat thread pool to be closed once the request has been processed as follows:

This code defines the TIMEOUT variable as the maximum time for the Tomcat thread pool to be delayed to close. Once this time is exceeded, the Tomcat thread pool will be forced to close and not be able to process all requests. We can gracefully close the Web application by controlling the timing of the Tomcat thread pool’s closing. Another thing to note is that our CustomShutdown class implements the ApplicationListener interface, meaning that we are listening for the Spring container to close. This means that the current ApplicationContext executes the close method.

## Add Connector callback to Tomcat

With the custom Connector callback, we need to add it to the embedded Tomcat container during startup and wait for execution. How to achieve this step, you can refer to the following code:

The TomcatServletWebServerFactory here is Spring Boot to realize embedded Tomcat factory class, similar to other Web container, also have the corresponding factory like JettyServletWebServerFactory, UndertowServletWebServerFactory. Their common characteristic is inherited with an abstract class AbstractServletWebServerFactory, provides a Web container public implementation of default, such as application context setting, session management, etc.

If we need to define the Spring Boot embedded Tomcat container, you can use the TomcatServletWebServerFactory for personalized definition, for example, below is the official document provides customised sample:

Ok, so we’re going to use addConnectorCustomizers to add custom Connector behavior to the embedded Tomcat. To see how it works, We can in the Spring after the Boot to Boot from the container to obtain the webServerFactory object, then observe, in its tomcatConnectorCustomizers attributes can see have CustomeShutdown object.

Open the Shutdown the Endpoint

In addition to the regular Linux Kill command, we can use Spring Boot to close the container remotely. In addition to the usual Linux Kill command, we can use Spring Boot to close the container remotely. How do we do that

Spring Boot Actuator is a feature that provides rich functionality to help you monitor and manage Spring Boot applications running in production environments. In addition to managing our applications via HTTP or JMX, it provides audit, health status, and measurement information collection for our applications to help us get a more complete picture of the running application.

In Chinese, the word Actuator is a manufacturing term for the mechanical device that controls something.

Spring Boot Actuator also provides the function of controlling app shutdown. Therefore, we need to introduce Spring Boot Actuator for applications by adding the corresponding starter dependency to the current project. Take Maven project as an example:

Spring Boot enables users to monitor and manage applications by exposing endpoints. After the introduction of spring-boot-starter- Actuator, We need to enable the Shutdown Endpoint that we need in the configuration file application.properties

The first line indicates that Shutdown Endpoint is enabled, and the second line indicates that all endpoints are exposed to the external system in HTTP mode. By default, all endpoints except Shutdown Endpoint are enabled.

In addition to the Shutdown Endpoint, there are more than ten types of Actuator endpoints. Some are specific operations, such as heapdump, which dumps memory logs. Some are informational displays, such as Health, which shows the health status of the application. For details about all Endpoints, see -53. Endpoints in the official document.

At this point our pre-configuration work is complete. When start the application, you can request by POST corresponding to the path of http://host:port/actuator/shutdown to realize Spring application remote Boot closed, isn’t it simple?

Simulation test

Here, in order to simulate the test, we first simulate the implementation of the request controller BusinessController, which takes up to 10s to process business. The specific implementation is as follows:

At the same time, use the Shutdown Endpoint in HTTP mode to try to Shutdown the application. You can observe the console log to see whether the application will complete the processing of the request before you really close the application.

Use the curl command to simulate sending a service request:

Then, during service processing, directly send the actuator/shutdown request and try to close the application. Also, use curl:

The response result is returned immediately after the ACTUATOR /shutdown request is sent, but the application does not stop:

Finally, take a look at the console log output order:

Can see immediately after sending business requests sent off applications request, will not be applied immediately to stop, but after the request processing is completed, is blocked after 10 s application to exit, so that returning to normal response has received the request, and close the request and then enter the request will not be processed, At this point we are able to gracefully close the Spring Boot program.

Automate

Because Spring Boot provides the convenience of having an embedded Web container, we often package and distribute programs as JARS. Generally, the startup and shutdown process of an application is fixed and repeated. In accordance with the Don’t Repeat Yourself principle, it is necessary to automate the operation process and write shell scripts for the closing and enabling SpringBoot application to avoid human error and make it easy to use. Improve operating efficiency. Here is the program startup script I wrote for the sample program :(the detailed script can be viewed in the sample project)

With the script, we can smoothly update and deploy the Spring Boot program directly from the command line, as follows:

conclusion

This article mainly explores how to use the Spring Boot embedded Tomcat Web application for smooth closure of the implementation, if the use of other Web container is similar, I hope this article is helpful, if there are mistakes or improper place, also please criticize and correct, together to learn communication.

reference

  • Graceful Shutdown Spring Boot Applications:blog.marcosbarbero.com/graceful-sh…
  • Shutdown a Spring Boot Application: www.baeldung.com/spring-boot…
  • Official document -53.endpoints: docs.spring. IO /spring-boot…
  • The HTTP Connector: tomcat.apache.org/tomcat-8.5-…
  • Customizing ConfigurableServletWebServerFactory Directly: docs. Spring. IO/spring – the boot…