Skip to content

可观测性

actuator 的导入

  • 导入依赖
xml
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
  • 暴露端点,可在 application 配置文件配置
yaml
# 暴露所有监控端点
management:
  endpoints:
    web:
      exposure:
        include: '*'
  • 访问 http://localhost:8080/actuator

暴露端点.png

定制 Health 端点

java
/**
 * 1、实现 HealthIndicator 接口来定制组件的健康状态返回
 */
@Component
public class MyHealthIndicator implements HealthIndicator {
    
    @Override
    public Health health() {
        return null;
    }
    
}

/**
 * 1、实现 HealthIndicator 接口来定制组件的健康状态返回
 * 2、或继承它的抽象方法
 */
@Component
public class MyHealthIndicator extends AbstractHealthIndicator {

    @Autowired
    MyComponent myComponent;

    @Override
    protected void doHealthCheck(Health.Builder builder) throws Exception {
        //自定义检查方法
        int check = myComponent.check();
        if (check == 1) {
            builder.up()
                    .withDetail("code",1000)
                    .withDetail("msg","活得很健康")
                    .withDetail("data","我是组件哈哈哈哈")
                    .build();
        }else {
            builder.down().build();
        }
    }

}

@Component
public class MyComponent {

    public int check() {
        //业务代码判断这个组件是否该是存活状态
        return 1;
    }

}
  • 修改 applicaton 配置文件展示详细信息
yaml
management:
  endpoint:
    health:
      enabled: true
      show-details: always
  • 查看健康状态端点

自定义health端点.png

定制 Metrics 端点

  • 调用 MyComponentcheck() 方法,并记录访问次数
java
@Component
public class MyComponent {

    Counter counter = null;

    public MyComponent(MeterRegistry meterRegistry) {
        //得到一个名为 myComponent.check 的计数器
        counter = meterRegistry.counter("myComponent.check");
    }

    public int check() {
        //每被调用一次,计数器+1
        counter.increment();
        //业务代码判断这个组件是否该是存活状态
        return 1;
    }

}

@RequestMapping("/my")
@RestController
public class MyController {

    @Autowired
    MyComponent myComponent;

    @GetMapping("/hello")
    public String hello() {
        myComponent.check();
        return "哈哈哈";
    }
}
  • 访问若干次后(对用户无感),查看 /actuator/metrics/myComponent.check

自定义metrics.png

整合 Prometheus +

导入 prometheus 依赖

xml
<dependency>
    <groupId>io.micrometer</groupId>
    <artifactId>micrometer-registry-prometheus</artifactId>
</dependency>

准备 jdk 21 环境, java -jar 启动打包好的 jar 包

shell
# 下载 jdk 21
wget https://download.oracle.com/java/21/latest/jdk-21_linux-x64_bin.tar.gz 

mkdir -p /opt/java

# 解压
tar -xzf jdk-21_linux-x64_bin.tar.gz -C /opt/java/

#配置环境变量
vi /etc/profile 

#添加
export JAVA_HOME=/opt/java/jdk-21.0.5
export PATH=$PATH:$JAVA_HOME/bin

# 让环境变量更改生效
source /etc/profile

# 后台启动 java 应用
nohup java -jar app.jar > output.log 2>&1 &

安装 Prometheus + Grafana

  • 修改 prometheus.yml 文件
shell
global:
  # 设置默认的数据抓取间隔为 15 s
  scrape_interval: 15s
  # 设置默认的告警规则评估间隔为 15 s
  evaluation_interval: 15s

scrape_configs:
  - job_name: 'prometheus'
    static_configs:
      - targets: ['localhost:9090']

  - job_name: 'spring-boot-demo'
    # spring-boot 的 Prometheus 指标路径
    metrics_path: '/actuator/prometheus'
    static_configs:
      - targets: ['8.140.207.120:8080']
        labels:
          nodename: 'app-demo'
  • 启动 prometheus 和 grafana
shell
# 安装 prometheus 时序数据库
docker run \
  --name=prometheus \
  -d \
  -p 9090:9090 \
  -v ~/prometheus/conf:/etc/prometheus \
  prom/prometheus \
  --config.file=/etc/prometheus/prometheus.yml \
  --storage.tsdb.path=/prometheus \
  --web.console.libraries=/usr/share/prometheus/console_libraries \
  --web.console.templates=/usr/share/prometheus/consoles \
  --web.enable-lifecycle

# 安装 grafana , 默认账号密码 admin:admin
docker run -d --name=grafana -p 3000:3000 grafana/grafana
  • 添加 prometheus 数据源

Grafana添加 prometheus 数据源.png

  • 添加一个 grafana dashboard

grafana dashboard.png