文章目录

  • 集成
  • 引入依赖
  • 配置文件
  • 访问验证
  • 端点 Endpoints
  • Health
  • Info
  • 安全
  • 高级
  • 自定义健康检查
  • 自定义metrics指标
  • PID PORT过程监控
  • 自定义管理端点路径
  • 自定义管理服务器端口
  • 暴露数据给Prometheus


集成

引入依赖

在项目的pom.xml中增加以下依赖

<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

配置文件

application.yml

management:
   # 禁用执行器端点的安全检查
   security:
      enabled: false

访问验证

例如,输入http://localhost:8080/actuator/health,我们可以查看应用程序当前状态

{
    "status": "UP"
}

这个接口经常用于服务探活或者健康检查接口。

到这里就集成完成了哈。

端点 Endpoints

Actuator默认把所有访问点暴露给JMX,但处于安全原因,只有healthinfo会暴露给Web。

Actuator提供的所有访问点均在官方文档列出,要暴露更多的访问点给Web,需要在application.yml中加上配置:

management:
  endpoints:
    web:
      exposure:
        # 包含所有端点使用 "*",注意有引号
        include: info, health, beans, env, metrics

Actuator 提供了以下接口,具体如下表所示。

HTTP 方法

路径

描述

GET

/auditevents

显示应用暴露的审计事件 (比如认证进入、订单失败)

GET

/beans

描述应用程序上下文里全部的 Bean,以及它们的关系

GET

/conditions

就是 1.0 的 /autoconfig ,提供一份自动配置生效的条件情况,记录哪些自动配置条件通过了,哪些没通过

GET

/configprops

描述配置属性(包含默认值)如何注入Bean

GET

/env

获取全部环境属性

GET

/env/{name}

根据名称获取特定的环境属性值

GET

/flyway

提供一份 Flyway 数据库迁移信息

GET

/liquidbase

显示Liquibase 数据库迁移的纤细信息

GET

/health

报告应用程序的健康指标,这些值由 HealthIndicator 的实现类提供

GET

/heapdump

dump 一份应用的 JVM 堆信息

GET

/httptrace

显示HTTP足迹,最近100个HTTP request/repsponse

GET

/info

获取应用程序的定制信息,这些信息由info打头的属性提供

GET

/logfile

返回log file中的内容(如果 logging.file 或者 logging.path 被设置)

GET

/loggers

显示和修改配置的loggers

GET

/metrics

报告各种应用程序度量信息,比如内存用量和HTTP请求计数

GET

/metrics/{name}

报告指定名称的应用程序度量值

GET

/scheduledtasks

展示应用中的定时任务信息

GET

/sessions

如果我们使用了 Spring Session 展示应用中的 HTTP sessions 信息

POST

/shutdown

关闭应用程序,要求endpoints.shutdown.enabled设置为true

GET

/mappings

描述全部的 URI路径,以及它们和控制器(包含Actuator端点)的映射关系

GET

/threaddump

获取线程活动的快照

GET

/prometheus

以 Prometheus 服务器可以抓取的格式公开指标。需要依赖micrometer-registry-prometheus.

下面着重讲下实际项目用到的。

Health

health 主要用来检查应用的运行状态,这是我们使用最高频的一个监控点。监控实例的运行状态,以及应用不”健康“的原因,比如数据库连接、磁盘空间不够等。

健康信息详情是否公开可以配置,例如:

management.endpoint.health.show-details=always
  • never 从不显示细节,默认
  • when-authorized 详细信息仅向授权用户显示。可以使用 配置授权角色management.endpoint.health.roles
  • always 向所有用户显示详细信息。

Spring Boot 会自动配置HealthIndicators下表中列出的内容。您也可以通过配置启用或禁用选定的指标management.health.key.enabledkey如下表所示:

钥匙

姓名

描述

cassandra

CassandraDriverHealthIndicator

检查 Cassandra 数据库是否已启动。

couchbase

CouchbaseHealthIndicator

检查 Couchbase 集群是否已启动。

db

DataSourceHealthIndicator

检查是否可以获得连接DataSource

diskspace

DiskSpaceHealthIndicator

检查磁盘空间不足。

elasticsearch

ElasticsearchRestHealthIndicator

检查 Elasticsearch 集群是否已启动。

hazelcast

HazelcastHealthIndicator

检查 Hazelcast 服务器是否已启动。

influxdb

InfluxDbHealthIndicator

检查 InfluxDB 服务器是否已启动。

jms

JmsHealthIndicator

检查 JMS 代理是否已启动。

ldap

LdapHealthIndicator

检查 LDAP 服务器是否已启动。

mail

MailHealthIndicator

检查邮件服务器是否已启动。

mongo

MongoHealthIndicator

检查 Mongo 数据库是否已启动。

neo4j

Neo4jHealthIndicator

检查 Neo4j 数据库是否已启动。

ping

PingHealthIndicator

始终以 响应UP

rabbit

RabbitHealthIndicator

检查 Rabbit 服务器是否已启动。

redis

RedisHealthIndicator

检查 Redis 服务器是否已启动。

solr

SolrHealthIndicator

检查 Solr 服务器是否已启动。

可以在配置文件中关闭特定的健康检查指标,比如关闭 redis 的健康检查:

management.health.redis.enabled=false

Info

info 就是我们自己配置在配置文件中以 info 开头的配置信息,您可以通过设置Spring 属性来自定义info端点公开的数据。info.*键下的所有Environment属性都会自动公开。例如,您可以将以下设置添加到application.yaml文件中:

info:
  app:
    name: spring-boot-actuator
    version: 1.0.0
    test: test
    encoding: @project.build.sourceEncoding@
    source: @java.version@
    target: @java.version@

启动项目,访问:http://localhost:8080/actuator/info返回部分信息如下:

{
	"app": {
		"name": "spring-boot-actuator",
		"version": "1.0.0",
		"test": "test",
		"encoding": "UTF-8",
		"source": "1.8.0_102",
		"target": "1.8.0_102"
	}
}

安全

要特别注意暴露的URL的安全性,例如,/actuator/env可以获取当前机器的所有环境变量,不可暴露给公网。

为了保证 actuator 暴露的监控接口的安全性,需要添加安全控制的依赖spring-boot-start-security依赖,访问应用监控端点时,都需要输入验证信息。

则默认情况下使用基于表单的HTTP身份验证来保护端点。

Security 依赖,可以选择不加,不进行安全管理,但不建议这么做。

<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-security</artifactId>
</dependency>

代码如下:

@Configuration
public class ActuatorSecurityConfig extends WebSecurityConfigurerAdapter {

    /*
     * version1:
     * 1. 限制 '/shutdown'端点的访问,只允许ACTUATOR_ADMIN访问
     * 2. 允许外部访问其他的端点
     * 3. 允许外部访问静态资源
     * 4. 允许外部访问 '/'
     * 5. 其他的访问需要被校验
     * version2:
     * 1. 限制所有端点的访问,只允许ACTUATOR_ADMIN访问
     * 2. 允许外部访问静态资源
     * 3. 允许外部访问 '/'
     * 4. 其他的访问需要被校验
     */

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // version1
//        http
//                .authorizeRequests()
//                    .requestMatchers(EndpointRequest.to(ShutdownEndpoint.class))
//                        .hasRole("ACTUATOR_ADMIN")
//                .requestMatchers(EndpointRequest.toAnyEndpoint())
//                    .permitAll()
//                .requestMatchers(PathRequest.toStaticResources().atCommonLocations())
//                    .permitAll()
//                .antMatchers("/")
//                    .permitAll()
//                .antMatchers("/**")
//                    .authenticated()
//                .and()
//                .httpBasic();

        // version2
        http
                .authorizeRequests()
                .requestMatchers(EndpointRequest.toAnyEndpoint())
                    .hasRole("ACTUATOR_ADMIN")
                .requestMatchers(PathRequest.toStaticResources().atCommonLocations())
                    .permitAll()
                .antMatchers("/")
                    .permitAll()
                .antMatchers("/**")
                    .authenticated()
                .and()
                .httpBasic();
    }
}

application.properties的相关配置如下:

# Spring Security Default user name and password
spring.security.user.name=actuator
spring.security.user.password=actuator
spring.security.user.roles=ACTUATOR_ADMIN

高级

自定义健康检查

要提供自定义健康信息,您可以注册实现该HealthIndicator接口的 Spring bean。您需要提供该health()方法的实现并返回Health响应。Health响应应包含状态,并且可以选择包含要显示的其他详细信息。以下代码显示了一个示例HealthIndicator实现:

@Component
public class EasyAdminHealthIndicator extends AbstractHealthIndicator {

    @Override
    public void doHealthCheck(Health.Builder builder) throws Exception {
        boolean checkHealth = check();
        if (checkHealth) {
            builder.up();
        } else {
            builder.down();
        }
        builder.withDetail("code", "200")
                .withDetail("msg", "i am ok");
    }

    private boolean check() {
        return true;
    }

}

启动项目,访问:http://localhost:8080/actuator/health返回信息如下:

{
	"status": "UP",
	"components": {
		"db": {
			"status": "UP",
			"details": {
				"database": "MySQL",
				"validationQuery": "isValid()"
			}
		},
		"diskSpace": {
			"status": "UP",
			"details": {
				"total": 332861009920,
				"free": 312464228352,
				"threshold": 10485760,
				"exists": true
			}
		},
		"easyAdmin": {         // do do do
			"status": "UP",
			"details": {
				"code": "200",
				"msg": "i am ok"
			}
		},
		"mail": {
			"status": "UP",
			"details": {
				"location": "smtp.qq.com:-1"
			}
		},
		"ping": {
			"status": "UP"
		}
	}
}

自定义metrics指标

两种常用指标类型(Metric Type)

gauge, counter, summary, timer

gauge: 可增可减计数器,反应某值当前一刻状态。比如称重传感器的当前重量,温度传感器的当前温度。

方式一:

Gauge.builder("gn.temperature.gauge", new AtomicInteger(37), AtomicInteger::get)

方式二:

registry.gauge("gn.temperature.gauge", Tags.of("site", "SiteA", "cab", "cab01"), new AtomicInteger(37));

counter:只增不减计数器,是Gauge的一个特例。适用于只有服务器重启时候才会重置的计数场景。比如"用户访问次数",某接口失败次数"等等。API 使用方式类似。

Counter counter = Counter.builder("gn.beat.counter")
  .tags("site", "SiteA", "function", "foo")
  .description("for request errors")
  .register(registry);

counter.increment();

融入到系统的方式

方式一: 业务系统埋点

@Component
public class SampleBean {
    private final Counter counter;
    private final List<String> list = new CopyOnWriteArrayList<>();;
    public SampleBean(MeterRegistry registry) {
        this.counter = registry.counter("laker.counter");
         registry.gauge("laker.size", Tags.empty(), this.list.size());
    }
    public void handleMessage(String message) {
        this.counter.increment();
        list.add(message);
    }
    public void handleRemoveMessage(String message) {
        list.remove(message);
    }
}

方式二:MeterBinder

SpringBoot中提供了MeterBinder接口用于申明与注册meterRegistry。自定义Metrics只需要实现MeterBinder接口,Spring会自动发现并完成后续的杂活。

@Bean
public class MyMetrics implements MeterBinder {
   @Override
   public void bindTo(MeterRegistry meterRegistry) {
    //此处添加相关指标
    meterRegistry.gauge("laker.gauge", Tags.of("site", "SiteA"), new AtomicInteger(37));
   }
}

在浏览器访问http://localhost:8080/actuator/metrics/laker.counter

结果如下

{
	"name": "laker.counter",
	"description": null,
	"baseUnit": null,
	"measurements": [
		{
			"statistic": "COUNT",
			"value": 9.0
		}
	],
	"availableTags": []
}

其他使用情况可参考:MetricsAutoConfiguration.java

PID PORT过程监控

  • ApplicationPidFileWriter创建一个包含应用程序 PID 的文件(默认情况下,在应用程序目录中,文件名为application.pid)。
  • WebServerPortFileWriter创建一个文件(或多个文件),其中包含正在运行的 Web 服务器的端口(默认情况下,在应用程序目录中,文件名为application.port)。

默认情况下,这些编写器未激活:

@SpringBootApplication
public class LakerMapApplication {
    public static void main(String[] args) {
        SpringApplication springApplication = new SpringApplication(LakerMapApplication.class);
        springApplication.addListeners(new ApplicationPidFileWriter(), new WebServerPortFileWriter("./laker.port"));
        springApplication.run(args);
    }
}

配置文件:

spring: 
  pid:
    # 写入pid的文件
    file: ./laker.pid
    # 当无法写入pid文件的时候,是否抛出异常
    fail-on-write-error: false

自定义管理端点路径

management.endpoints.web.base-path=/manage

将端点从/actuator/{id}更改为/manage/{id}(例如,/manage/info)。

如果要将端点映射到不同的路径,可以使用该management.endpoints.web.path-mapping属性。

以下示例重新映射/actuator/health/healthcheck

management.endpoints.web.base-path=/
management.endpoints.web.path-mapping.health=healthcheck

自定义管理服务器端口

management.server.port=8081
management.server.address=127.0.0.1

暴露数据给Prometheus

因为暴露内部信息的特性,Actuator 也可以和一些外部的应用监控系统整合(Prometheus, Graphite, DataDog, Influx, Wavefront, New Relic等)。这些监控系统提供了出色的仪表板,图形,分析和警报,可帮助你通过一个统一友好的界面,监视和管理你的应用程序。

添加依赖

为了让Spring Boot 应用和Prometheus 集成,你需要增加micrometer-registry-prometheus依赖。

<!-- Micrometer Prometheus registry  -->
<dependency>
    <groupId>io.micrometer</groupId>
    <artifactId>micrometer-registry-prometheus</artifactId>
</dependency>

添加上述依赖项之后,Spring Boot 将会自动配置 PrometheusMeterRegistryCollectorRegistry来以Prometheus 可以抓取的格式收集和导出指标数据。

所有的相关数据,都会在Actuator 的 /prometheus端点暴露出来。Prometheus 可以抓取该端点以定期获取度量标准数据。

添加micrometer-registry-prometheus依赖后,我们访问http://localhost:8080/actuator/prometheus地址。

参考: