优雅的关闭springboot程序
使用jar形式部署springboot程序后,通过kill进程关闭程序,总是不踏实。好在,官方提供了优雅关闭应用程序的方式。
引入依赖
首先,在POM中引入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
配置application
以2.1.8.RELEASE为例,application.yml配置如下:
management:
endpoint:
shutdown:
enabled: true
endpoints:
web:
exposure:
include: "*"
base-path: /actuator
发送POST请求
curl -d "" --header "Content-Type:application/json" http://127.0.0.1:8080/actuator/shutdown
{"message":"Shutting down, bye..."}
Spring Boot Actuator
actuator可以帮助你监控和管理Spring Boot应用,比如健康检查、审计、统计和HTTP追踪等。所有的这些特性可以通过JMX或者HTTP endpoints来获得。
Actuator通过创建Endpoint来暴露HTTP或者JMX来监控和管理应用。
Endpoint
| Endpoint | 说明 |
|---|---|
| auditevents | 显示应用暴露的审计事件 (比如认证进入、订单失败) |
| info | 显示应用的基本信息 |
| health | 显示应用的健康状态 |
| metrics | 显示应用多样的度量信息 |
| loggers | 显示和修改配置的loggers |
| logfile | 返回log file中的内容(如果logging.file或者logging.path被设置) |
| httptrace | 显示HTTP足迹,最近100个HTTP request/repsponse |
| env | 显示当前的环境特性 |
| flyway | 显示数据库迁移路径的详细信息 |
| liquidbase | 显示Liquibase 数据库迁移的纤细信息 |
| shutdown | 让你逐步关闭应用 |
| mappings | 显示所有的@RequestMapping路径 |
| scheduledtasks | 显示应用中的调度任务 |
| threaddump | 执行一个线程dump |
| heapdump | 返回一个GZip压缩的JVM堆dump |
默认,除了shutdown所有的endpints都是打开的。
打开关闭Endpoint
你可以通过设置management.endpoint.<id>.enabled to true or false来决定打开还是关闭一个actuator endpoint。启用shutdown如下:
management.endpoint.shutdown.enabled=true
暴露Endpoint
通过HTTP暴露Actuator endpoints
management.endpoints.web.exposure.include=*
management.endpoints.web.exposure.exclude=health,info
通过JMX暴露Actuator endpoints
management.endpoints.jmx.exposure.include=*
management.endpoints.jmx.exposure.exclude=
打开全部Endpoint后,访问http://127.0.0.1:8080/actuator如下:
{
_links: {
self: {
href: "http://127.0.0.1:8080/actuator",
templated: false
},
auditevents: {
href: "http://127.0.0.1:8080/actuator/auditevents",
templated: false
},
beans: {
href: "http://127.0.0.1:8080/actuator/beans",
templated: false
},
caches-cache: {
href: "http://127.0.0.1:8080/actuator/caches/{cache}",
templated: true
},
caches: {
href: "http://127.0.0.1:8080/actuator/caches",
templated: false
},
health: {
href: "http://127.0.0.1:8080/actuator/health",
templated: false
},
health-component: {
href: "http://127.0.0.1:8080/actuator/health/{component}",
templated: true
},
health-component-instance: {
href: "http://127.0.0.1:8080/actuator/health/{component}/{instance}",
templated: true
},
conditions: {
href: "http://127.0.0.1:8080/actuator/conditions",
templated: false
},
shutdown: {
href: "http://127.0.0.1:8080/actuator/shutdown",
templated: false
},
configprops: {
href: "http://127.0.0.1:8080/actuator/configprops",
templated: false
},
env: {
href: "http://127.0.0.1:8080/actuator/env",
templated: false
},
env-toMatch: {
href: "http://127.0.0.1:8080/actuator/env/{toMatch}",
templated: true
},
info: {
href: "http://127.0.0.1:8080/actuator/info",
templated: false
},
loggers: {
href: "http://127.0.0.1:8080/actuator/loggers",
templated: false
},
loggers-name: {
href: "http://127.0.0.1:8080/actuator/loggers/{name}",
templated: true
},
heapdump: {
href: "http://127.0.0.1:8080/actuator/heapdump",
templated: false
},
threaddump: {
href: "http://127.0.0.1:8080/actuator/threaddump",
templated: false
},
metrics: {
href: "http://127.0.0.1:8080/actuator/metrics",
templated: false
},
metrics-requiredMetricName: {
href: "http://127.0.0.1:8080/actuator/metrics/{requiredMetricName}",
templated: true
},
scheduledtasks: {
href: "http://127.0.0.1:8080/actuator/scheduledtasks",
templated: false
},
httptrace: {
href: "http://127.0.0.1:8080/actuator/httptrace",
templated: false
},
mappings: {
href: "http://127.0.0.1:8080/actuator/mappings",
templated: false
}
}
}
安全
考虑到可能造成信息泄露等严重的安全隐患,可以使用security机制。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
引入这个依赖之后,所有的接口都访问不了了,需要填写用户名和密码。
spring:
security:
user:
name: admin
password: admin
roles: ADMIN
management:
server:
port: 8081
通过下面自定义Security配置类,可以对/actuator开始的url访问要求有ADMIN权限,其他的随意访问。
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/actuator/**").access("hasRole('ADMIN')")
.antMatchers("/**").permitAll();
super.configure(http);
}
}