Spring Boot:使用Actuator监控端点

1、Actuator依赖

<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的运行状况。

2、Actuator内置的端点

iddescSensitive
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执行一个线程dumpYes
httptrace显示HTTP跟踪信息(默认显示最后100个HTTP请求 - 响应交换)Yes

Spring Boot中对这些端点提供了多种监控方式,包括HTTP和JMX等。下面,我们先来看看使用HTTP方式监控。

3、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”后,服务就会关闭了。

    

4、JMX监控

对于Spring Boot,还可以通过Java管理扩展(Java Management Extensions,JMX)来让开发人员监控JVM的状况。

进入JAVA_HOME目录下的bin目录,找到jconsole.exe文件,在运行Spring Boot的项目时在运行它。可以看到如下所示的对话框:

选中Spring Boot项目,点击“Connect”就能够连接到Spring Boot运行的环境,从而监控JVM的运行状态。

5、自定义端点

除了使用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

6、健康指标项

                                                                              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

这里是问题级别从重到轻的排序,它们使用逗号分割,其配置项含义为:

  • 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

我这里使用的是公司电脑,需要代理,所以无法访问。

 

 

 

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值