Spring boot 2.0 обеспечивает плавное завершение работы
Яма, на которую наступили на ранней стадии (spring boot 1.x)
1. Добавьте зависимости mavne
1<!-- springboot监控 -->
2<dependency>
3 <groupId>org.springframework.boot</groupId>
4 <artifactId>spring-boot-starter-actuator</artifactId>
5</dependency>
2. Включить выключение
Добавьте следующую конфигурацию в файл конфигурации
1#启用shutdown endpoint的HTTP访问
2endpoints.shutdown.enabled=true
3#不需要验证
4endpoints.shutdown.sensitive=false
При запуске вы можете увидеть следующий журнал, указывающий на успех
3. Изящное завершение работы
отправить POST-запросhttp://localhost:8080/shutdown
Если код ответа 404, вы можете попробовать POSThttp://localhost:8080/actuator/shutdown
spring boot 2.0
Если вы используете загрузочную версию Spring 2.x, вы обнаружите, что эти запросы POST приведут к ошибке 404.
Ниже приведена реализация изящного завершения работы Spring Boot 2.0.
1. Измените класс запуска приложения.
контейнер кота
1@SpringBootApplication
2public class ShutdownApplication {
3
4 public static void main(String[] args) {
5 SpringApplication.run(ShutdownApplication.class, args);
6 }
7
8 /**
9 * 用于接受 shutdown 事件
10 */
11 @Bean
12 public GracefulShutdown gracefulShutdown() {
13 return new GracefulShutdown();
14 }
15
16 /**
17 * 配置tomcat
18 *
19 * @return
20 */
21 @Bean
22 public ServletWebServerFactory servletContainer() {
23 TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory();
24 tomcat.addConnectorCustomizers(gracefulShutdown());
25 return tomcat;
26 }
27
28 /**
29 * 优雅关闭 Spring Boot。容器必须是 tomcat
30 */
31 private class GracefulShutdown implements TomcatConnectorCustomizer, ApplicationListener<ContextClosedEvent> {
32 private final Logger log = LoggerFactory.getLogger(GracefulShutdown.class);
33 private volatile Connector connector;
34 private final int waitTime = 10;
35
36 @Override
37 public void customize(Connector connector) {
38 this.connector = connector;
39 }
40
41 @Override
42 public void onApplicationEvent(ContextClosedEvent contextClosedEvent) {
43 this.connector.pause();
44 Executor executor = this.connector.getProtocolHandler().getExecutor();
45 if (executor instanceof ThreadPoolExecutor) {
46 try {
47 ThreadPoolExecutor threadPoolExecutor = (ThreadPoolExecutor) executor;
48 threadPoolExecutor.shutdown();
49 if (!threadPoolExecutor.awaitTermination(waitTime, TimeUnit.SECONDS)) {
50 log.warn("Tomcat 进程在" + waitTime + " 秒内无法结束,尝试强制结束");
51 }
52 } catch (InterruptedException ex) {
53 Thread.currentThread().interrupt();
54 }
55 }
56 }
57 }
58}
59
Подводный контейнер (не используется, не гарантируется)
1@SpringBootApplication
2public class Application {
3
4 public static void main(String[] args) {
5 SpringApplication.run(Application.class, args);
6 }
7
8 /**
9 * 优雅关闭 Spring Boot
10 */
11 @Component
12 public class GracefulShutdown implements ApplicationListener<ContextClosedEvent> {
13
14 @Autowired
15 private GracefulShutdownWrapper gracefulShutdownWrapper;
16
17 @Autowired
18 private ServletWebServerApplicationContext context;
19
20 @Override
21 public void onApplicationEvent(ContextClosedEvent contextClosedEvent){
22 gracefulShutdownWrapper.getGracefulShutdownHandler().shutdown();
23 try {
24 UndertowServletWebServer webServer = (UndertowServletWebServer)context.getWebServer();
25 Field field = webServer.getClass().getDeclaredField("undertow");
26 field.setAccessible(true);
27 Undertow undertow = (Undertow) field.get(webServer);
28 List<Undertow.ListenerInfo> listenerInfo = undertow.getListenerInfo();
29 Undertow.ListenerInfo listener = listenerInfo.get(0);
30 ConnectorStatistics connectorStatistics = listener.getConnectorStatistics();
31 while (connectorStatistics.getActiveConnections() > 0){}
32 }catch (Exception e){
33 // Application Shutdown
34 }
35 }
36 }
37 @Component
38 public class GracefulShutdownWrapper implements HandlerWrapper{
39
40 private GracefulShutdownHandler gracefulShutdownHandler;
41
42 @Override
43 public HttpHandler wrap(HttpHandler handler) {
44 if(gracefulShutdownHandler == null) {
45 this.gracefulShutdownHandler = new GracefulShutdownHandler(handler);
46 }
47 return gracefulShutdownHandler;
48 }
49
50 public GracefulShutdownHandler getGracefulShutdownHandler() {
51 return gracefulShutdownHandler;
52 }
53
54 }
55 @Component
56 @AllArgsConstructor
57 public class UndertowExtraConfiguration {
58
59 private final GracefulShutdownWrapper gracefulShutdownWrapper;
60
61 @Bean
62 public UndertowServletWebServerFactory servletWebServerFactory() {
63 UndertowServletWebServerFactory factory = new UndertowServletWebServerFactory();
64 factory.addDeploymentInfoCustomizers(deploymentInfo -> deploymentInfo.addOuterHandlerChainWrapper(gracefulShutdownWrapper));
65 factory.addBuilderCustomizers(builder -> builder.setServerOption(UndertowOptions.ENABLE_STATISTICS, true));
66 return factory;
67 }
68
69 }
70}
2. Убейте процесс с помощью команды kill
Убейте процесс, используя команду ниже. Команда состоит в том, чтобы послать процессу сигнал завершения.
1kill -15 [PID]
Пожалуйста, укажите источник
Ссылка на эту статью:Этот курс.com/20180504.Контракт…