springboot应用关闭方式
引
言
在这篇文章中,我们将讨论使用不同的方式关闭Spring启动应用程序。
介绍
在生产环境中管理应用程序与开发环境不同。我们可能希望控制我们部署在生产环境的应用程序的生命周期。SpringBoot提供了一些开箱即用的特性来控制Spring容器的生命周期,包括优雅地关闭SpringBoot应用程序。让我们讨论一些最常见的方法来控制生产环境中的Springboot企业应用程序。
springboot actuator具有许多生产就绪特征,包括 关闭端点。默认情况下,actuator中没有启用所有 关闭端点。要在我们的应用程序中使用此端点,我们应该引用spring-boot-starter-actuator,并在应用程序中启用此端点。
为了引入和启用它,我们需要在应用程序pom.xml中添加spring-boot-starter-actuator启动器,并且需要使用application.properties或application.yml文件启用关闭端点。下面是我们的Maven依赖项设置。
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency>
如果要配置端点的启用,需要使用management.endpoint..enabled属性。下面就是我们的应用程序属性在添加更改后的样子:
management.endpoint.shutdown.enabled=true management.endpoint.info.enabled=true management.endpoints.web.exposure.include=*
1.1:安全端点
在这个例子中,我们在没有任何安全防护的情况下开放 端点。不建议在生产应用程序上执行此操作。这会给应用程序带来很大的安全风险。为了保护应用的的关闭端点,需要使用spring-boot-starter-security。
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency>
1.2:测试端点
要测试关闭端点,需要先启动应用,当应用启动运行后,只需要调用使用POST方式调用端点即可。
curl -i -X POST http://localhost:8080/actuator/shutdown
产生如下类似的响应:
HTTP/1.1 200 Content-Type: application/vnd.spring- boot.actuator.v2+json;charset=UTF-8 Transfer-Encoding: chunked Date: Sun, 05 Aug 2018 18:11:27 GMT { "message":"Shutting down, bye..." }
查看服务器控制台/日志,会看到类似的输出:
2018-08-05 11:11:28.151 INFO 9626 --- [ Thread-28] ConfigServletWebServerApplicationContext : Closing org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@42f0c846: startup date [Sun Aug 05 11:10:58 PDT 2018]; root of context hierarchy 2018-08-05 11:11:28.155 INFO 9626 --- [ Thread-28] o.s.j.e.a.AnnotationMBeanExporter : Unregistering JMX-exposed beans on shutdown Copy
关闭Spring启动应用程序的另外一种方式是使用SpringApplication关闭ApplicationContext上下文。SpringApplication#run(String...)方法返回ApplicationContext作为ConfigurableApplicationContext上下文。我们可以调用close()方法以编程方式关闭ApplicationContext上下文。
@SpringBootApplication public class SpringBootShutdownApplication { public static void main(String[] args) { ConfigurableApplicationContext ctx = SpringApplication.run(SpringBootShutdownApplication.class, args); ctx.close(); } }
运行应用程序时,我们在服务器控制台或日志文件上有类似的输出:
2018-08-05 11:32:19.898 INFO 9899 --- [ restartedMain] ConfigServletWebServerApplicationContext : Closing org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@72d1ddb3: startup date [Sun Aug 05 11:32:16 PDT 2018]; root of context hierarchy 2018-08-05 11:32:19.901 INFO 9899 --- [ restartedMain] o.s.j.e.a.AnnotationMBeanExporter : Unregistering JMX-exposed beans on shutdown
要处理ApplicationContext上下文关闭事件,让我们使用@PreDestroy注解创建关闭处理方法:
@Configuration public class ApplicationConfig { @PreDestroy public void onShutDown() { System.out.println("closing application context..let's do the final resource cleanup"); } }
在运行应用程序时,我们看到类似的输出:
2018-08-05 22:24:48.487 INFO 10550 --- [ restartedMain] ConfigServletWebServerApplicationContext : Closing org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@451a9713: startup date [Sun Aug 05 22:24:45 EDT 2018]; root of context hierarchy 2018-08-05 22:24:48.490 INFO 10550 --- [ restartedMain] o.s.j.e.a.AnnotationMBeanExporter : Unregistering JMX-exposed beans on shutdown closing application context..let's do the final resource cleanup
我们还可以选择使用SpringApplication类可用的静态退出帮助方法:
@SpringBootApplication public class SpringBootShutdownApplication { public static void main(String[] args) { ConfigurableApplicationContext ctx = SpringApplication.run(SpringBootShutdownApplication.class, args); exitApplication(ctx); //ctx.close(); } public static void exitApplication(ConfigurableApplicationContext ctx) { int exitCode = SpringApplication.exit(ctx, new ExitCodeGenerator() { @Override public int getExitCode() { // no errors return 0; } }); System.exit(exitCode); } }
用Java8的lambda表达式,上面的代码可以重写为:
SpringApplication.exit(ctx, () -> returnCode);
使用springboot应用将进程id写入到文件中,我们可以通过一个bash脚本使用进程文件来停止和重启应用以及获取运行状态:
SpringApplication application = new SpringApplication(Application.class); application.addListeners(new ApplicationPidFileWriter("./bin/app.pid")); application.run();
总结
在这篇文章中,我们讨论了关闭springboot应用程序的不同方式,我们了解了在Springboot actuator下使用HTTP方式关闭应用程序的shutdown端点。我们也分析了使用SpringAppication#close方法关闭应用程序上下文,在最后,我们了解了如何将进程id写入文件,以及如何使用bash脚本来控制应用程序的生命周期。
本文分享自 PersistentCoder 微信公众号,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文参与 腾讯云自媒体同步曝光计划 ,欢迎热爱写作的你一起参与!