本文章介绍了正常关闭Spring Boot 应用程序的过程。许多开发人员和架构师总是讨论SpringBoot的应用设计、流量负载、框架和应用模式,但很少有人讨论关闭阶段。生命周期意识可以说一个真正资深程序员应该具有的素质,对于重资源对象,包括线程池 连接池等都要有始有终,不能只顾创建。
对于 SpringBoot 来说,打包成一个简单的 Jar 包直接使用 java -jar即可启动,这是一种非常优雅的方式,但同时也带来了一定的问题,如:应用如何停止?在过去,应用程序是部署在特定的容器中的,使用容器提供的脚本可以优雅停服,但现在容器被内嵌了,脚本没有了,怎么办?直接 kill 是一种方式,但未免显得太过粗鲁,而且可能带来许多意想不到的问题。
下面记录一种方案。
使用 Endpoints
在 SpringBoot 官方文档的第5部分中介绍了为应用发布生产准备的各种特性,其中,通过 Actuator 的 HTTP Endpoint,开发人员可以方便地对应用的监控与管理。此方法配合winsw使用,适用于window服务器,有需要请参考:在windows服务器上使用winsw部署spring boot项目
引入指定的SpringBoot starter包
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
在 application.properties 中打开如下两个配置,即可实现通过 Http 请求停止应用
management.endpoints.web.exposure.include=*
management.endpoint.shutdown.enabled=true
操作命令如下:
curl -X POST http://host:port/actuator/shutdown
但这种方式有一个非常严重的问题,那就是任意人都可以控制应用的停止,为了保证系统的安全,需要给其加上一层 HTTP Basic Auth
增加 Security 依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
在 application.properties 中增加如下两个配置:
spring.security.user.name=actuator
spring.security.user.password=password
spring.security.user.roles=ACTUATOR
增加security过滤规则
@Configuration
public class ActuatorWebSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable().authorizeRequests().antMatchers("/").permitAll()
.requestMatchers(EndpointRequest.toAnyEndpoint()).hasRole("ACTUATOR")
.anyRequest().authenticated().and()
//开启basic认证,若不添加此项,将不能通过curl的basic方式传递用户信息
.httpBasic();
}
}
配置完成后,最终的停服命令为:
curl -X POST -u actuator:password http://host:port/actuator/shutdown
执行返回:{"message":"Shutting down, bye..."},说明服务停止成功。