Kill -9 pid??

Kill sends the specified information to the program. The default message is SIGTERM(15), which terminates the specified program. If you still cannot terminate the program, you can use the SIGKILL(9) message to try to forcibly remove the program. The number of a program or job can be viewed using the PS or JOBS command.

This is a complex, simple way to kill processes in Linux. What? You ask me what is a process? Please search by yourself.

I believe that many people have used the command kill -9 pid, kill the process completely, normally we use it without the above problems, but in our project there may be fatal problems.

Kill -9 Problems caused by PID

Because kill -9 is a violent delete, so it will bring serious consequences to the program, then what will bring consequences?

Take, for example, the power failure of the transfer function while adding and deducting money to two accounts? What happens at this point? For InnoDB storage engine, there is no loss because it supports transactions, but for MyISAM engine it is a disaster, why? If you have deducted money from account A and need to add money to account B, then the power failure will cause that A’s money is deducted, but B does not get the money, which is absolutely not allowed in the production environment. Kill -9 is equivalent to the effect of A sudden power failure.

Of course, if you use kill -9 to stop the service, then it is not your transaction that can guarantee the accuracy of data. At this time, you may think of distributed transaction. There is no absolute security system or architecture in the world, and distributed transactions are the same. They may also have problems. The probability is very small, and if they happen, the loss may be irreparable.

In the MyISAM engine performance of the more obvious, such as user information from two tables maintenance, administrators to modify the user information needs to be modified when two tables, but because of you kill 9 violent end project, lead to a list only change a success, it can also lead to data inconsistencies, this is the little things, because big changes again, But money, contract these important information if because of your violent deletion lead to disorder, I think it may be worse than delete library run away, at least delete library can recover, you do not know where is wrong.

So how do we end the project?

In fact, Java provides us with the ability to end a project. For example, Tomcat can use shutdown.bat/shutdown.sh to gracefully end a project.

What does it mean to end gracefully?

Step 1: Stop receiving requests and internal threads. Step 2: Determine if any threads are executing. Step 3: Wait for the executing thread to complete. Step 4: Stop the container.

The above four steps are the normal end process, so how does SpringBoot end the service normally? Please take notes in your notebook as I introduce several ways to end a service normally.

Graceful end of service

kill -15 pid

This is also a more elegant way to end a process (project), use it carefully, why? Let’s look at an example

I wrote a normal Controller method for testing

@GetMapping(value = "/test")
    public String test(){
        log.info("test --- start");
        try {
            Thread.sleep(100000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        log.info("test --- end");
        return "test";
    }
1234567891011
Copy the code

The code is very simple, print: test — start to put the program to sleep for 100 seconds, then print: test — end, in the thread sleep we use kill -15 PID to end the process, do you guess test — end will print?

application.yml

server:
  port: 9988
12
Copy the code

Start the project

sudo mvn spring-boot:run
1
Copy the code

This is how Maven launches the SpringBoot projectWhen you see this, it means the project is in motion

Find the process ID for the project

sudo ps -ef |grep shutdown
1
Copy the code

This is the process number of the project. We will test the test interface to put the thread to sleep, and then stop the project using kill -15 14086

sudo curl 127.0. 01.:9988/test
1
Copy the code

Back to project logWe find that the request has reached the service and the thread has successfully gone to sleep. Now we kill -15 14086 to terminate the process

sudo kill - 15 14086
1
Copy the code

Return to the log

2020- 04- 24 10:53:14.939  INFO 14086 --- [nio- 9988.-exec- 1] com.ymy.controller.TestController        : test --- start
2020- 04- 24 10:54:02.450  INFO 14086 --- [extShutdownHook] o.s.s.concurrent.ThreadPoolTaskExecutor  : Shutting down ExecutorService 'applicationTaskExecutor'
java.lang.InterruptedException: sleep interrupted
 at java.lang.Thread.sleep(Native Method)
 at com.ymy.controller.TestController.test(TestController.java:26)
 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
 at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
 at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
 at java.lang.reflect.Method.invoke(Method.java:498)
 at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:190)
 at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138) at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHand lerMethod.java:105) at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHan dlerAdapter.java:879) at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerA dapter.java:793)
 at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
 at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1040)
 at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:943)
 at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)
 at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898)
 at javax.servlet.http.HttpServlet.service(HttpServlet.java:634)
 at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)
 at javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
 at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
 at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
 at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
 at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
 at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
 at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
 at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
 at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
 at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
 at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
 at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
 at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
 at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
 at org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.doFilterInternal(WebMvcMetricsFilter.java:109)
 at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
 at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
 at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
 at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
 at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
 at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
 at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
 at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202)
 at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
 at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541)
 at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139)
 at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
 at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
 at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
 at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:373)
 at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
 at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868)
 at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1594)
 at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
 at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
 at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
 at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
 at java.lang.Thread.run(Thread.java:748)
2020- 04- 24 10:54:04.574  INFO 14086 --- [nio- 9988.-exec- 1] com.ymy.controller.TestController        : test --- end
2020- 04- 24 10:54:04.610 ERROR 14086 --- [nio- 9988.-exec- 1] o.s.web.servlet.HandlerExecutionChain : HandlerInterceptor.afterCompletion threw exception java.lang.NullPointerException: null at org.springframework.boot.actuate.metrics.web.servlet.LongTaskTimingHandlerInterceptor.stopLongTaskTimers(LongTaskTimingH andlerInterceptor.java:123) ~[spring-boot-actuator2.26..RELEASE.jar:2.26..RELEASE] at org.springframework.boot.actuate.metrics.web.servlet.LongTaskTimingHandlerInterceptor.afterCompletion(LongTaskTimingHand lerInterceptor.java:79) ~[spring-boot-actuator2.26..RELEASE.jar:2.26..RELEASE]
 at org.springframework.web.servlet.HandlerExecutionChain.triggerAfterCompletion(HandlerExecutionChain.java:179) ~[spring-webmvc5.2. 5.RELEASE.jar:5.2. 5.RELEASE]
 at org.springframework.web.servlet.DispatcherServlet.triggerAfterCompletion(DispatcherServlet.java:1427) [spring-webmvc5.2. 5.RELEASE.jar:5.2. 5.RELEASE]
 at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1060) [spring-webmvc5.2. 5.RELEASE.jar:5.2. 5.RELEASE]
 at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:943) [spring-webmvc5.2. 5.RELEASE.jar:5.2. 5.RELEASE]
 at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) [spring-webmvc5.2. 5.RELEASE.jar:5.2. 5.RELEASE]
 at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898) [spring-webmvc5.2. 5.RELEASE.jar:5.2. 5.RELEASE]
 at javax.servlet.http.HttpServlet.service(HttpServlet.java:634) [tomcat-embed-core9.033..jar:9.033.]
 at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) [spring-webmvc5.2. 5.RELEASE.jar:5.2. 5.RELEASE]
 at javax.servlet.http.HttpServlet.service(HttpServlet.java:741) [tomcat-embed-core9.033..jar:9.033.]
 at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) [tomcat-embed-core9.033..jar:9.033.]
 at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core9.033..jar:9.033.]
 at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) [tomcat-embed-websocket9.033..jar:9.033.]
 at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core9.033..jar:9.033.]
 at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core9.033..jar:9.033.]
 at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) [spring-web5.2. 5.RELEASE.jar:5.2. 5.RELEASE]
 at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) [spring-web5.2. 5.RELEASE.jar:5.2. 5.RELEASE]
 at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core9.033..jar:9.033.]
 at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core9.033..jar:9.033.]
 at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) [spring-web5.2. 5.RELEASE.jar:5.2. 5.RELEASE]
 at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) [spring-web5.2. 5.RELEASE.jar:5.2. 5.RELEASE]
 at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core9.033..jar:9.033.]
 at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core9.033..jar:9.033.]
 at org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.doFilterInternal(WebMvcMetricsFilter.java:109) [spring-boot-actuator2.26..RELEASE.jar:2.26..RELEASE]
 at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) [spring-web5.2. 5.RELEASE.jar:5.2. 5.RELEASE]
 at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core9.033..jar:9.033.]
 at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core9.033..jar:9.033.]
 at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) [spring-web5.2. 5.RELEASE.jar:5.2. 5.RELEASE]
 at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) [spring-web5.2. 5.RELEASE.jar:5.2. 5.RELEASE]
 at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core9.033..jar:9.033.]
 at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core9.033..jar:9.033.]
 at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202) [tomcat-embed-core9.033..jar:9.033.]
 at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) [tomcat-embed-core9.033..jar:9.033.]
 at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541) [tomcat-embed-core9.033..jar:9.033.]
 at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139) [tomcat-embed-core9.033..jar:9.033.]
 at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) [tomcat-embed-core9.033..jar:9.033.]
 at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) [tomcat-embed-core9.033..jar:9.033.]
 at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343) [tomcat-embed-core9.033..jar:9.033.]
 at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:373) [tomcat-embed-core9.033..jar:9.033.]
 at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) [tomcat-embed-core9.033..jar:9.033.]
 at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868) [tomcat-embed-core9.033..jar:9.033.]
 at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1594) [tomcat-embed-core9.033..jar:9.033.]
 at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-embed-core9.033..jar:9.033.]
 at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [na:1.8. 0_242]
 at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [na:1.8. 0_242]
 at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core9.033..jar:9.033.]
 at java.lang.Thread.run(Thread.java:748) [na:1.8. 0_242]

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646 566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
Copy the code

Test — end = test — end = test — end This has to do with the method sleep, where during the thread sleep,A call to the threadinterrupt method causes sleep to throw an exceptionThe kill -15 command causes the interrupt method to be invoked immediately in order to stop the thread. It is up to the thread to decide when to stop, which is why we still see test-end. More Spring Boot video tutorials can be obtained by following wechat subscription number.

ConfigurableApplicationContext colse

So let’s see how do we do that

package com.ymy.controller;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@Slf4j
public class TestController  implements ApplicationContextAware {

    private  ApplicationContext  context;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.context = applicationContext;
    }


    @GetMapping(value = "/test")
    public String test(){
        log.info("test --- start");
        try {
            Thread.sleep(100000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        log.info("test --- end");
        return "test";
    }

    /** * stop */
    @PostMapping(value = "shutdown")
    public void shutdown(){
        ConfigurableApplicationContext cyx = (ConfigurableApplicationContext) context;
        cyx.close();
    }
}
1234567891011121314151617181920212223242526272829303132333435363738394041424344
Copy the code

Cyx.close (); Why could he shut down springboot? Please look at the source code

public void close() {
        synchronized(this.startupShutdownMonitor) {
            this.doClose();
            if(this.shutdownHook ! = null) { try { Runtime.getRuntime().removeShutdownHook(this.shutdownHook); } catch (IllegalStateException var4) { } } } }123456789101112
Copy the code

The application registers a close hook with the JVM at startup. When we execute the colse method, we remove the close hook and the JVM knows that we need to stop the service.

Let’s look at the test resultsApparently, he also uses interrupt methods to cause threads to report errors, much like kill-15.

actuator

In this way, services are stopped by introducing dependencies. The actuator provides many interfaces, such as health checks, basic information and so on, and we can also use them to gracefully shut down.

Introduction of depend on

<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>

12345
Copy the code

application.yml

server:
  port: 9988

management:
  endpoints:
    web:
      exposure:
        include: shutdown
  endpoint:
    shutdown:
      enabled: true
  server:
    port: 8888
12345678910111213
Copy the code

Here, I assign a new interface for the interface of the actuator, which can improve the security. Let’s test it

@RequestMapping(value = "/test",method = RequestMethod.GET)
    public String test(){
        System.out.println("test --- start");
        try {
            Thread.sleep(10000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("test --- end");
        return "hello";
    }
1234567891011
Copy the code

Stopped service on request for testWe noticed that after sending the stop service request we were given a message back, which was very humane, so let’s look at the consoleTest — end is executed, but interrupt is invoked to stop the thread pool, causing sleep to fail. All three methods can gracefully stop the SpringBoot service. If I have thread sleep in my project, can I wait 10 seconds before stopping the springboot service? It’s definitely ok. We just need to make a few modifications.

1. The new stop springboot service class: ElegantShutdownConfig. Java

package com.ymy.config;

import org.apache.catalina.connector.Connector;
import org.springframework.boot.web.embedded.tomcat.TomcatConnectorCustomizer;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextClosedEvent;

import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class ElegantShutdownConfig implements TomcatConnectorCustomizer, ApplicationListener<ContextClosedEvent> {

    private volatile Connector connector;
    private final int waitTime = 10;

    @Override
    public void customize(Connector connector) {
        this.connector = connector;
    }

    @Override
    public void onApplicationEvent(ContextClosedEvent event) {
        connector.pause();
        Executor executor = connector.getProtocolHandler().getExecutor();
        if (executor instanceof ThreadPoolExecutor) {
            try {
                ThreadPoolExecutor threadPoolExecutor = (ThreadPoolExecutor) executor;
                threadPoolExecutor.shutdown();
                if(! threadPoolExecutor.awaitTermination(waitTime, TimeUnit.SECONDS)) { System.out.println("Please try a violent shutdown.");
                }
            } catch (InterruptedException ex) {
                System.out.println("Abnormal"); Thread.currentThread().interrupt(); }}}}1234567891011121314151617181920212223242526272829303132333435363738394041
Copy the code

2. Add beans to the startup class

package com.ymy;

import com.ymy.config.ElegantShutdownConfig;
import lombok.extern.slf4j.Slf4j;
import org.apache.catalina.connector.Connector;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.embedded.tomcat.TomcatConnectorCustomizer;
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.boot.web.servlet.server.ServletWebServerFactory;
import org.springframework.context.ApplicationListener;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.event.ContextClosedEvent;

import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

@SpringBootApplication
public class ShutdownServerApplication {

    public static void main(String[] args) {
        ConfigurableApplicationContext run = SpringApplication.run(ShutdownServerApplication.class, args);
        run.registerShutdownHook();
    }


    @Bean
    public ElegantShutdownConfig elegantShutdownConfig() {
        return new ElegantShutdownConfig();
    }

    @Bean
    public ServletWebServerFactory servletContainer() {
        TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory();
        tomcat.addConnectorCustomizers(elegantShutdownConfig());
        returntomcat; }}1234567891011121314151617181920212223242526272829303132333435363738394041
Copy the code

Now that we are configured, let’s test again. The test interface still sleeps for 10 secondsWe find that there is no error this time, it is the thread pool that waits for a period of time to terminate, which is the waitTime we configured in the ElegantShutdownConfig class.

Then you might wonder, what happens when the JVM doesn’t stop immediately when there are requests? If a new request is received while closing, the service will not receive the request.

Data Backup Operation

What should I do if I want to do a backup operation when the service stops? It’s as simple as adding an annotation to the method you want to execute: @predestroy

Destroy: pre – prefix abbreviation

So that all adds up to executing the container once before it stops, you can do backups in it, you can do downtime, etc.

Added service stop backup utility class: databackupconfig.java

package com.ymy.config;

import org.springframework.context.annotation.Configuration;

import javax.annotation.PreDestroy;

@Configuration
public class DataBackupConfig {

    @PreDestroy
    public  void backData(){

        System.out.println("Backing up data..."); }}123456789101112131415
Copy the code

Let’s test again and print the console log:

From: blog.csdn.net/qq_33220089/article/details/105708331