1 使用Actuator检查与监控的步骤
1.1 在 pom 文件中添加 Actuator 的坐标
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
<version>2.1.6.RELEASE</version>
</dependency>
1.2 在全局配置文件中设置关闭安全限制
# 在1.5.x版本中通过management.security.enabled=false来暴露所有端点
management.security.enabled=false
# 在2.x 的springboot中的properties文件格式
management.endpoints.web.exposure.include=*
# 在2.x的springboot版本中的yml格式
# 2.0 yml格式
management:
endpoints:
web:
exposure:
include: refresh
但是spring boot2.0
以后actuator
中security
的报错A global security auto-configuration is now provided
,过时问题,主要是:
- 报错原因: 在
spring boot2.0
以后的版本中,actuator
的security
某些方法已经过期了,已有所改动.不过要是不介意继续用也没事(eclispe
不会提示,但是idea
会提示)
springboot
启动成功后,直接127.0.0.1:8080/+以下请求URI
即可
ID | 描述 | 是否需要鉴权 |
---|---|---|
actuator | 为其他端点提供“发现页面”。 要求 Spring HATEOAS 在 classpath 路径上 | 需要 |
auditevents | 陈列当前应用程序的审计事件信息 | 需要 |
autoconfig | 展示自动配置信息并且显示所有自动配置候选人以及他们“被不被”应用的原因 | 需要 |
beans | 显示应用程序中所有 Spring bean 的完整列表 | 需要 |
configprops | 显示所有配置信息 | 需要 |
dump | dump 所有线程 | 需要 |
env | 陈列所有的环境变量 | 需要 |
flyway | Shows any Flyway database migrations that have been applied | 需要 |
health | 显示应用程序运行状况信息 | 不需要 |
info | 显示应用信息 | 不需要 |
loggers | 显示和修改应用程序中的 loggers 配置 | 需要 |
liquibase | 显示已经应用的任何 Liquibase 数据库迁移 | 需要 |
metrics | 显示当前应用程序的“指标”信息 | 需要 |
mappings | 显示所有@RequestMapping 的 url 整理列表。 | 需要 |
shutdown | 关闭应用(默认情况下不启用) | 需要 |
trace | 显示跟踪信息(默认最后 100 个 HTTP 请求) | 需要 |
1.3 Spring Boot停止服务的方法
在使用 Springboot
的时候,都要涉及到服务的停止和启动,当我们停止服务的时候,很多时候大家都是 kill -9
直接把程序进程杀掉,这样程序不会执行优雅的关闭。而且一些没有执行完的程序就会直接退出。
我们很多时候都需要安全的将服务停止,也就是把没有处理完的工作继续处理完成。比如停止一些依赖的服务,输出一些日志,发一些信号给其他的应用系统,这个在保证系统的高可用是非常有必要的
1.3.1 Springboot提供的actuator
Springboot
提供的actuator
的功能,它可以执行shutdown, health, info
等,默认情况下,actuator
的shutdown
是disable
的,我们需要打开它。首先引入acturator的maven依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
然后将 shutdown
节点打开,也将 /actuator/shutdown
暴露 web
访问也设置上,除了shutdown
之外还有health, info
的web访问都打开的话将management.endpoints.web.exposure.include=*
就可以。将如下配置设置到application.properties
里边
server.port=3333
management.endpoint.shutdown.enabled=true
management.endpoints.web.exposure.include=shutdown
接下来,咱们创建一个springboot
工程,然后设置一个bean
对象,配置上PreDestroy
方法。这样在停止的时候会打印语句。bean
的整个生命周期分为创建、初始化、销毁,当最后关闭的时候会执行销毁操作。在销毁的方法中执行一条输出日志。
package com.hqs.springboot.shutdowndemo.bean;
import javax.annotation.PreDestroy;
publicclass TerminateBean {
@PreDestroy
public void preDestroy() {
System.out.println("TerminalBean is destroyed");
}
}
做一个configuration
,然后提供一个获取bean
的方法,这样该bean
对象会被初始化。
package com.hqs.springboot.shutdowndemo.config;
import com.hqs.springboot.shutdowndemo.bean.TerminateBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
publicclass ShutDownConfig {
@Bean
public TerminateBean getTerminateBean() {
return new TerminateBean();
}
}
在启动类里边输出一个启动日志,当工程启动的时候,会看到启动的输出,接下来咱们执行停止命令。curl -X POST http://localhost:3333/actuator/shutdown
以下日志可以输出启动时的日志打印和停止时的日志打印,同时程序已经停止。是不是比较神奇。
1.3.2 获取程序启动时的context并关闭
获取程序启动时候的 context
,然后关闭主程序启动时的 context
。这样程序在关闭的时候也会调用 PreDestroy
注解。如下方法在程序启动十秒后进行关闭。
ConfigurableApplicationContext ctx = SpringApplication.run(ShutdowndemoApplication.class, args);
try {
TimeUnit.SECONDS.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
ctx.close();
1.3.3 用Linux命令
在springboot
启动的时候将进程号写入一个app.pid
文件,生成的路径是可以指定的,可以通过命令 cat /Users/huangqingshi/app.id | xargs kill
命令直接停止服务,这个时候 bean
对象的 PreDestroy
方法也会调用的。这种方法大家使用的比较普遍。写一个start.sh
用于启动springboot
程序,然后写一个停止程序将服务停止。
/* method 3 : generate a pid in a specified path, while use command to shutdown pid :
'cat /Users/huangqingshi/app.pid | xargs kill' */
SpringApplication application = new SpringApplication(ShutdowndemoApplication.class);
application.addListeners(new ApplicationPidFileWriter("/Users/huangqingshi/app.pid"));
application.run();
1.3.4 SpringApplication.exit()方法
通过调用一个 SpringApplication.exit()
方法也可以退出程序,同时将生成一个退出码,这个退出码可以传递给所有的 context
。这个就是一个 JVM
的钩子,通过调用这个方法的话会把所有 PreDestroy
的方法执行并停止,并且传递给具体的退出码给所有 Context
。通过调用 System.exit(exitCode)
可以将这个错误码也传给 JVM
。程序执行完后最后会输出:Process finished with exit code 0
,给JVM一个SIGNAL。
/* method 4: exit this application using static method */
ConfigurableApplicationContext ctx = SpringApplication.run(ShutdowndemoApplication.class, args);
exitApplication(ctx);
System.exit(exitCode);
}
public static void exitApplication(ConfigurableApplicationContext context) {
int exitCode
= SpringApplication.exit(context, (ExitCodeGenerator) () -> 0);
}
1.3.5 通过Controller调用
写一个 Controller
,然后将写好的Controller
获取到程序的 context
,然后调用自己配置的 Controller
方法退出程序。通过调用自己写的 /shutDownContext
方法关闭程序:curl -X POST http://localhost:3333/shutDownContext
package com.hqs.springboot.shutdowndemo.controller;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
publicclass ShutDownController implements ApplicationContextAware {
private ApplicationContext context;
@PostMapping("/shutDownContext")
public String shutDownContext() {
ConfigurableApplicationContext ctx = (ConfigurableApplicationContext) context;
ctx.close();
return"context is shutdown";
}
@GetMapping("/")
public String getIndex() {
return"OK";
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
context = applicationContext;
}
}
2 使用可视化的监控报表 Spring Boot Admin
2.1 搭建服务端
2.1.1 引入admin坐标
服务端其实也是一个 SpringBoot
项目,引入admin的坐标
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-starter-server</artifactId>
<version>1.5.7</version>
</dependency>
2.1.2 修改启动类,添加@EnableAdminServer
@SpringBootApplication
@EnableAdminServer
public class SpringbootServerApplication {
public static void main(String[] args) {
SpringApplication.run(SpringbootServerApplication.class,args);
}
}
2.2 搭建客户端
其实客户端
就是我们需要监控的工程。
2.2.1 修改客户端的pom文件添加依赖
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-starter-client</artifactId>
<!-- 此处的版本号和springboot版本号一致,或者比springboot版本更低也可以 -->
<version>RELEASE</version>
</dependency>
2.2.2 修改客户端的 application.properteis 配置文件
2.2.2.1 关闭安全限制
# 当springboot是1.5.x时使用这个关闭安全限制如下
management.security.enabled=false
# 当springboot是2.X时,就使用如下
management.endpoints.web.exposure.include=*
# 当springboot是2.X时,使用的yml格式:
management:
endpoints:
web:
exposure:
# 此处的星号是特殊字符,必须用引号引起来
include: “*”
2.2.2.2 注册到springbootadmin的服务
# http://localhost:9090 表示是 Spring Boot Admin 服务单的 IP 地址以及端口号
spring.boot.admin.client.url=http://localhost:9090
2.2.2.3 不让springboot admin通过主机名字 获取ip
# 必须在客户端配置 boot.admin.client.instance.service-url属性,
# 让Spring Boot Admin服务端可以通过网络获取客户端的数据(否则默认会通过主机名去获取)
spring.boot.admin.client.instance.service-url=127.0.0.1:9090
# prefer-ip是否使用注册的ip地址来取代上述各个url中hostname的值,默认值是false
spring.boot.admin.client.instance.prefer-ip=true
2.3 监控信息讲解
报错信息:
Calling [asyncError()] is not valid for a request with Async state [MUST_DISPATCH]
这个是没有什么影响的,说是内置tomcat
的问题,把spring-boot-admin-starter
版本降低下,2.1.2和2.1.3
可能不会让application
页面刷新出来,这时候降低到2.1.0
就可以了