赞
踩
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-actuator</artifactId>
- </dependency>
- <dependency>
- <groupId>org.springframework.hateoas</groupId>
- <artifactId>spring-hateoas</artifactId>
- <version>0.24.0.RELEASE</version>
- </dependency>
代码中引入了spring-boot-starter-actuator,它是Spring Boot实施监控所必须的包。此外还引入了spring-hateoas。HATEOAS(The Hypermedia As The Engine Of Application Statue)是REST架构的主要约束。“hepermedia”表示任何包含指向图片、电影、文字等资源的链接,Web是超媒体的经典例子。HATEOAS背后的思想其实非常简单,就是响应中包含指向其它资源的链接。客户端可以利用这些链接和服务器交互。
有关HATEOAS的文章: Spring REST实践之HATEOAS
下面我们先来了解下Actuator提供了哪些端点来监控Spring Boot的运行状况。
id | desc | Sensitive |
---|---|---|
auditevents | 显示当前应用程序的审计事件信息 | Yes |
beans | 显示应用Spring Beans的完整列表 | Yes |
caches | 显示可用缓存信息 | Yes |
conditions | 显示自动装配类的状态及及应用信息 | Yes |
configprops | 显示所有 @ConfigurationProperties 列表 | Yes |
env | 显示 ConfigurableEnvironment 中的属性 | Yes |
flyway | 显示 Flyway 数据库迁移信息 | Yes |
health | 显示应用的健康信息(未认证只显示status ,认证显示全部信息详情) | No |
info | 显示任意的应用信息(在资源文件写info.xxx即可) | No |
liquibase | 展示Liquibase 数据库迁移 | Yes |
metrics | 展示当前应用的 metrics 信息 | Yes |
mappings | 显示所有 @RequestMapping 路径集列表 | Yes |
scheduledtasks | 显示应用程序中的计划任务 | Yes |
sessions | 允许从Spring会话支持的会话存储中检索和删除用户会话。 | Yes |
shutdown | 允许应用以优雅的方式关闭(默认情况下不启用) | Yes |
threaddump | 执行一个线程dump | Yes |
httptrace | 显示HTTP跟踪信息(默认显示最后100个HTTP请求 - 响应交换) | Yes |
Spring Boot中对这些端点提供了多种监控方式,包括HTTP和JMX等。下面,我们先来看看使用HTTP方式监控。
注意:使用HTTP方式监控需要先导入spring-boot-starter-web包。
在导入好所需的依赖后,启动项目,访问http://localhost:8080/actuator/health,就可以看到当前应用的健康状态。
在默认情况下,Spring Boot的端点前缀是"/actuator"。我们也可以通过更改配置项来修改它为“/manage”:
management.endpoints.web.base-path=/manage
值得注意的是Spring Boot2.x
中,默认只开放了info、health
两个端点(因为端点往往会显示一些项目的敏感信息),剩余的需要自己通过配置management.endpoints.web.exposure.include
属性来加载所需端点(反之用exclude来排除不需要的端点
)。如果想单独操作某个端点可以使用management.endpoint.端点.enabled
属性进行启用或禁用。
比如说,访问除了env端点以外的所有端点,那么可以在application.properties文件中做如下配置:
- # 暴露所有端点
- management.endpoints.web.exposure.include=*
- # 不暴露env端点
- management.endpoints.web.exposure.exclude=env
但是通过这种方式访问端点是相当危险的,毕竟这些信息的权限应该属于系统的开发者和管理员,而不是每一个人。因此,我们应该通过Spring Security配置用户和角色,来解决这些敏感信息的访问权限问题。(需加入spring-boot-starter-security依赖)
- package com.scb.actuatordemo.config;
-
- import org.springframework.boot.actuate.autoconfigure.security.servlet.EndpointRequest;
- import org.springframework.context.annotation.Configuration;
- import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
- import org.springframework.security.config.annotation.web.builders.HttpSecurity;
- import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
- import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
- import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
- import org.springframework.security.crypto.password.PasswordEncoder;
-
- @Configuration
- @EnableWebSecurity
- public class SecurityConfig extends WebSecurityConfigurerAdapter {
-
- // 注册两个用户
- @Override
- protected void configure(AuthenticationManagerBuilder auth) throws Exception {
- // 密码加密器
- PasswordEncoder passwordEncoder=new BCryptPasswordEncoder();
- auth.inMemoryAuthentication().passwordEncoder(passwordEncoder)
- .withUser("admin").password(passwordEncoder.encode("admin")).roles("USER","ADMIN").and()
- .withUser("user").password(passwordEncoder.encode("user")).roles("USER");
- }
-
- @Override
- protected void configure(HttpSecurity http) throws Exception {
- String[] endPoints={"auditevents","beans","conditions","configprops","env","flyway","httptrace",
- "loggers","liquibase","metrics","mappings","scheduledtasks","sessions","shutdown","threaddump"};
- http.requestMatcher(EndpointRequest.to(endPoints))
- .authorizeRequests().anyRequest().hasRole("ADMIN")
- .and()
- // 后续shutdown端点的权限配置
- .antMatcher("/close").authorizeRequests().anyRequest().hasRole("ADMIN")
- .and()
- .httpBasic();
- }
- }

configure(HttpSecurity http)方法,首先定义了一个端点的数组,用来保存敏感信息的端点,而这些端点需要验证通过后才能访问。这里使用requestMatcher方法进行匹配请求,而EndpointRequest.to(...)方法是指定对应的端点,后续的hasRole是限定角色访问权限。这样对应的敏感信息除health和info之外,都只有拥有角色为“ROLE_ADMIN”的用户才能访问。 仍需将所有端点暴露出来:management.endpoints.web.exposure.include=*
shutdown端点
在所有端点中,shutdown端点是最特殊的一个。在默认情况下,Actuator并不会给开发者启动这个端点,因为请求它就会关闭服务器。如果想启用该端点需要在application.properties文件中做如下配置:
management.endpoint.shutdown.enabled=true
配置好了之后,shutdown端点就变为可用了。但它是一个POST请求,也就是无法通过浏览器地址栏进行访问。下面,我们通过jsp页面进行模拟:
/webapp/WEB-INF/jsp/close.jsp
- <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
- <!DOCTYPE html>
- <html>
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
- <script src="./../js/jquery-3.3.1.min.js"></script>
- <script type="text/javascript">
- $(document).ready(function () {
- $("#submit").click(function () {
- $.post({
- url: "./actuator/shutdown",
- success:function (result) {
- if (result!=null || result.message!=null){
- alert(result.message);
- return;
- }
- alert("close failure")
- }
- })
- })
- })
- </script>
- <title>Test shutdown endpoint</title>
- </head>
- <body>
- <input id="submit" type="button" value="shutdown">
- </body>
- </html>

ActuatorController.class
- package com.scb.actuatordemo.controller;
-
- import org.springframework.web.bind.annotation.GetMapping;
- import org.springframework.web.bind.annotation.RestController;
- import org.springframework.web.servlet.ModelAndView;
-
- @RestController
- public class ActuatorController {
- @GetMapping("/close")
- public ModelAndView close(ModelAndView mv){
- mv.setViewName("close");
- return mv;
- }
- }
接下来访问http://localhost:8080/close,点击按钮“shutdown”后,服务就会关闭了。
对于Spring Boot,还可以通过Java管理扩展(Java Management Extensions,JMX)来让开发人员监控JVM的状况。
进入JAVA_HOME目录下的bin目录,找到jconsole.exe文件,在运行Spring Boot的项目时在运行它。可以看到如下所示的对话框:
选中Spring Boot项目,点击“Connect”就能够连接到Spring Boot运行的环境,从而监控JVM的运行状态。
除了使用Actuator默认给予的端点外,我们还可以自定义端点来满足自定义监控的要求。在Actuator中加入端点只需要加入注解@Endpoint即可,这个注解会同时提供JMX监控和Web监控。如果只想提供JMX监控,可以使用@JmxEndpoint;如果只想提供Web监控,可以使用注解@WebEndpoint。
- package com.scb.actuatordemo.endpoint;
-
- import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
- import org.springframework.boot.actuate.endpoint.annotation.ReadOperation;
- import org.springframework.stereotype.Component;
-
- import java.util.HashMap;
- import java.util.Map;
-
- @Component
- @Endpoint(id = "endpointTest",enableByDefault = true)
- public class MyEndPoint {
- @ReadOperation
- public Map<String,String> test(){
- Map<String,String> result=new HashMap<>();
- result.put("author","Ni");
- result.put("time","2019/02/25");
- return result;
- }
- }

@ReadOperation:
GET请求,响应状态为 200 如果没有返回值响应 404(资源未找到)@WriteOperation:
POST请求,响应状态为 200 如果没有返回值响应 204(无响应内容)@DeleteOperation:
DELETE请求,响应状态为 200 如果没有返回值响应 204(无响应内容)运行项目,访问http://localhost:8080/actuator/endpointTest
Actuator默认提供的监控指标项
名称 | 描述 |
---|---|
CassandraHealthIndicator | 检查Cassandra 数据库是否启动。 |
DiskSpaceHealthIndicator | 检查磁盘空间不足。 |
DataSourceHealthIndicator | 检查是否可以获得连接DataSource 。 |
ElasticsearchHealthIndicator | 检查Elasticsearch 集群是否启动。 |
InfluxDbHealthIndicator | 检查InfluxDB 服务器是否启动。 |
JmsHealthIndicator | 检查JMS 代理是否启动。 |
MailHealthIndicator | 检查邮件服务器是否启动。 |
MongoHealthIndicator | 检查Mongo 数据库是否启动。 |
Neo4jHealthIndicator | 检查Neo4j 服务器是否启动。 |
RabbitHealthIndicator | 检查Rabbit 服务器是否启动。 |
RedisHealthIndicator | 检查Redis 服务器是否启动。 |
SolrHealthIndicator | 检查Solr 服务器是否已启动。 |
上表所示的健康指标是Actuator根据开发者配置的项目进行自动创建的,但是他们在默认情况下,是不会进行展示的。要展示这些健康项的时候,需要进行如下配置:
- # never:从不展示健康项
- # when-authorized:签名认证之后展示
- # always:每次都展示
- management.endpoint.health.show-details=when_authorized
此时,在访问http://localhost:8080/actuator/health
上图展示了所有开发者配置内容的健康指标。但是如果不想开启所有指标,可以根据情况关闭对应的健康指标项监控。例如,关闭数据库的健康指标可以进行如下配置:
management.health.db.enabled=false
对于健康指标,除了关注如何查看外,还需要关注它们的严重级别,如默认的配置项所示:
management.health.status.order=DOWN, OUT_OF_SERVICE, UP, UNKNOWN
这里是问题级别从重到轻的排序,它们使用逗号分割,其配置项含义为:
下面我们看看如何开发自定义的健康指标:
- package com.scb.actuatordemo.endpoint;
-
- import org.springframework.boot.actuate.health.AbstractHealthIndicator;
- import org.springframework.boot.actuate.health.Health;
- import org.springframework.stereotype.Component;
-
- import java.net.InetAddress;
-
- /**
- * 监测服务器是否可以访问万维网
- */
- @Component
- public class WwwHealthIndicator extends AbstractHealthIndicator {
- private final static String BAIDU_HOST="www.baidu.com";
- private final static int TIME_OUT=3000;
- @Override
- protected void doHealthCheck(Health.Builder builder) throws Exception {
- boolean status=ping();
- if(status){
- builder.withDetail("message","当前服务器可以访问万维网。").up();
- }else {
- builder.withDetail("message","当前服务器无法访问万维网。").outOfService();
- }
- }
- // 监测是否能够访问百度,用以判断能否访问万维网
- private boolean ping() throws Exception{
- try{
- return InetAddress.getByName(BAIDU_HOST).isReachable(TIME_OUT);
- }catch (Exception ex){
- return false;
- }
- }
- }

再次访问http://localhost:8080/actuator/health
我这里使用的是公司电脑,需要代理,所以无法访问。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。