SpringBoot最大特点便是简化配置,提升开发效率,实现简单部署就是通过内嵌一个Web容器,如果Tomcat、Jettty等。
对于SpringBoot应用,只需打包成一个简单的Jar包,然后执行java -jar就可以启动,是一种非常优雅的方式,但同时也隐藏着一些问题,如:应用如何停止?对于传统的部署在容器中的Java应用(非Spring Boot应用)可以使用容器提供的脚本优雅重启,但是SpringBoot应用容器是内嵌的,也就不会存在容器的脚本,最直接的想法就是kill进程,但这样很不优雅,进程强行终止会带来数据丢失或者终端无法恢复到正常的状态,在分布式环境下还可能导致数据不一致的情况。
SpringBoot提供了几种停止的方法,本文重点介绍actuator endpoint的方法,SpringBoot官方文档的Endpoints章节中介绍了应用发布生产准备的各种特性,其中通过Actuator的HTTP Endpoint,开发人员可以方便地对应用进行监控和管理。
简易优雅停服
pom引入Maven依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
SpringBoot配置文件application.yml
server:
port: 8077
management:
endpoint:
health:
show-details: always
shutdown:
enabled: true
endpoints:
web:
exposure:
include: '*'
- management.endpoint.shutdown.enabled 这是说是否启动/shutdown端点,默认是false,
- management.endpoints.web.exposure.include='*' 这是公开所有端点
测试Endpoint
按照上面进行配置后,SpringBoot项目就可以优雅关闭了,只要模拟一个POST请求,在Postman或者其他工具,访问如下路径
http://localhost:8077/actuator/shutdown
注:替换成自己项目的host及port,必须是post
返回
{
"message": "Shutting down, bye..."
}
说明SpringBoot应用已优雅关闭
安全设置
虽然SpringBoot应用已可以优雅关闭了,但是还存在很大的安全隐患,如果有搞破坏的知道了ip、端口号后就可以模拟该请求停止服务了,因此需要增加一些安全限制
- management.endpoints.web.base-path 自定义shutdown的请求路径
- management.server.address 设置为本地ip,就可以防止远程访问该连接进行关闭服务了
- management.server.port 自定义shutdown请求路径的端口号
进行这些配置后就可以做到最基本的安全且优雅的关闭SpringBoot应用了,调整后的配置文件如下
Endpoint配置文件
management:
endpoint:
health:
show-details: always
shutdown:
# 启用shutdown配置
enabled: true
endpoints:
web:
exposure:
include: '*'
# 自定义管理断点的前缀,安全性考虑
base-path: /restartactuator
server:
# 自定义端口
port: 12581
# 不允许远程管理连接,安全性考虑
address: 127.0.0.1
验证
登录到SpringBoot应用部署的服务器,本地通过curl执行POST请求
curl -X POST http://127.0.0.1:12581/restartactuator/shutdown
然后可以可到如下输出
{"message":"Shutting down, bye..."}
说明SpringBoot应用已经优雅且安全的进行了停止
相关知识
kill指令
kill -9 pid 是不进行任何等待判断,可以理解为操作系统从内核级别强行杀死某个进程,可模拟为系统宕机、系统断点等特殊情况
kill -15 pid 是等待应用关闭,执行阻塞操作,有时候也会出现无法关闭应用的情况(线上理想情况,是bug就该追根溯源)
网友评论