跳转到内容
123xiao | 无名键客

《Spring Boot 中基于 Actuator 与 Micrometer 的应用监控实战:从指标采集到告警落地》

字数: 0 阅读时长: 1 分钟

Spring Boot 中基于 Actuator 与 Micrometer 的应用监控实战:从指标采集到告警落地

很多团队一开始做监控,都是“先把 /actuator/prometheus 暴露出来再说”。结果过几周就会发现几个现实问题:

  • 指标很多,但不知道哪些值得看
  • 业务接口明明变慢了,Grafana 面板却没法直接定位
  • 告警规则写了一堆,不是误报就是漏报
  • 线上出了问题,才发现健康检查、线程池、JVM、数据库连接池数据根本没接全

这篇文章我想换一个更“落地”的视角来讲:不是只教你把指标采出来,而是从 Spring Boot + Actuator + Micrometer 出发,串起“采集、暴露、展示、告警”这一整条链路。你可以把它当成一篇可直接照着做的教程。


背景与问题

在 Spring Boot 应用里,监控常见痛点主要有三类:

  1. 系统层问题看不到
    • CPU 飙升、内存抖动、GC 频繁、线程池堆积
  2. 应用层问题看不清
    • 某个接口慢、某类异常暴涨、某个下游依赖超时
  3. 告警层问题不可靠
    • 只看“服务是否存活”远远不够
    • 没有基于趋势和阈值的组合告警

Actuator 解决的是“暴露运行信息”,Micrometer 解决的是“统一指标采集与输出模型”。两者配合后,Spring Boot 应用就能比较顺畅地接入 Prometheus,再由 Grafana 展示、Alertmanager 告警。

一句话概括:

Actuator 负责把门打开,Micrometer 负责把数据组织好。


前置知识与环境准备

本文默认你已经具备这些基础:

  • 会写基本的 Spring Boot Web 应用
  • 知道 Maven/Gradle 的依赖管理
  • 对 Prometheus、Grafana 有基础认知
  • 使用 JDK 17+、Spring Boot 3.x

本文示例环境:

  • Spring Boot 3.3.x
  • Micrometer + Prometheus Registry
  • Prometheus
  • Grafana

核心原理

先别急着上代码,我们先把链路理顺。实际运行时,大致是这样:

flowchart LR
    A[Spring Boot App] --> B[Actuator Endpoints]
    A --> C[Micrometer MeterRegistry]
    C --> B
    B --> D[/actuator/prometheus]
    D --> E[Prometheus 拉取]
    E --> F[Grafana 展示]
    E --> G[Alertmanager 告警]

这条链路里有几个关键角色:

1. Actuator:暴露运行时能力

Actuator 提供很多端点,比如:

  • /actuator/health
  • /actuator/info
  • /actuator/metrics
  • /actuator/prometheus

其中:

  • /actuator/metrics 更适合人肉查看某个指标
  • /actuator/prometheus 更适合 Prometheus 定时抓取

2. Micrometer:统一指标模型

Micrometer 是 Spring Boot 监控体系里的核心抽象,它定义了常见指标类型:

  • Counter:只增不减,适合请求次数、异常次数
  • Gauge:瞬时值,适合队列长度、缓存大小
  • Timer:耗时与调用次数,适合接口 RT
  • DistributionSummary:分布统计,适合请求大小、订单金额这类数值

它还有一个很重要的概念:tag(标签)

例如一个 HTTP 请求指标可能长这样:

  • 指标名:http_server_requests_seconds_count
  • 标签:
    • method=GET
    • uri=/api/orders/{id}
    • status=200
    • outcome=SUCCESS

标签能让你按维度分析,但也很容易失控。后面讲“常见坑”时我会重点说这个问题。

3. Prometheus:拉模型采集

Prometheus 默认是pull 模式,它会定时去拉你的 /actuator/prometheus

这意味着:

  • 应用自身不用主动推送
  • 每个实例都要能被 Prometheus 访问到
  • 指标端点不能随便暴露给公网

4. 告警不是“有指标就行”,而是“指标要可解释”

监控成熟度提升的关键,不在于你采了多少指标,而在于:

  • 指标是否能和业务动作对应
  • 告警是否能指导排查
  • 阈值是否符合系统真实负载特征

监控链路分层设计

我比较推荐把应用监控分成三层看:

flowchart TD
    A[基础设施层] --> A1[CPU/内存/磁盘/网络]
    B[运行时层] --> B1[JVM GC 线程 类加载]
    C[应用层] --> C1[HTTP接口 数据库 线程池 缓存 业务指标]
    D[告警层] --> D1[可用性 延迟 错误率 饱和度]

对应到 Spring Boot 项目里,通常至少要覆盖:

  • JVM 指标
  • HTTP 请求指标
  • 数据库连接池指标
  • 线程池指标
  • 关键业务指标

实战代码(可运行)

下面我们从零开始搭一个可运行示例。

第一步:创建项目并添加依赖

Maven 依赖

<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.example</groupId>
    <artifactId>boot-monitor-demo</artifactId>
    <version>1.0.0</version>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.3.2</version>
    </parent>

    <properties>
        <java.version>17</java.version>
    </properties>

    <dependencies>
        <!-- Web -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

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

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

        <!-- 可选:校验 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-validation</artifactId>
        </dependency>

        <!-- 测试 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
</project>

第二步:开启 Actuator 与 Prometheus 端点

application.yml

server:
  port: 8080

spring:
  application:
    name: boot-monitor-demo

management:
  endpoints:
    web:
      exposure:
        include: health,info,metrics,prometheus
  endpoint:
    health:
      show-details: when_authorized
  prometheus:
    metrics:
      export:
        enabled: true

  metrics:
    tags:
      application: ${spring.application.name}
    distribution:
      percentiles-histogram:
        http.server.requests: true
      slo:
        http.server.requests: 100ms,200ms,500ms,1s,2s

这里有两个特别关键的配置:

  • percentiles-histogram.http.server.requests=true
    • 让 HTTP 请求指标生成 Prometheus 可聚合直方图
  • slo.http.server.requests=...
    • 设定分桶边界,后续算 P95/P99、慢请求占比会更靠谱

如果你少了这部分,后面做延迟告警会很难受。我早期就踩过这个坑:图能画出来,但算分位数时精度和可解释性都很一般。


第三步:启动类

package com.example.monitor;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class BootMonitorDemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(BootMonitorDemoApplication.class, args);
    }
}

第四步:写一个业务接口,并模拟慢请求与异常

package com.example.monitor.web;

import jakarta.validation.constraints.Min;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.Map;
import java.util.concurrent.ThreadLocalRandom;

@RestController
@RequestMapping("/api/orders")
@Validated
public class OrderController {

    @GetMapping("/{id}")
    public Map<String, Object> getOrder(@PathVariable @Min(1) Long id,
                                        @RequestParam(defaultValue = "false") boolean slow,
                                        @RequestParam(defaultValue = "false") boolean fail) throws InterruptedException {
        if (slow) {
            Thread.sleep(ThreadLocalRandom.current().nextLong(300, 1200));
        }

        if (fail) {
            throw new IllegalStateException("simulate order query failure");
        }

        return Map.of(
                "id", id,
                "status", "PAID",
                "amount", 199.00
        );
    }
}

这个接口的意义很简单:

  • slow=true:制造慢请求
  • fail=true:制造错误请求

后面我们就靠它验证监控面板和告警规则。


第五步:自定义业务指标

系统指标只能告诉你“程序不太对劲”,但真正帮你判断业务状态的,通常还是业务指标

例如我们统计订单创建次数和金额分布。

package com.example.monitor.service;

import io.micrometer.core.instrument.Counter;
import io.micrometer.core.instrument.DistributionSummary;
import io.micrometer.core.instrument.MeterRegistry;
import org.springframework.stereotype.Service;

@Service
public class OrderMetricsService {

    private final Counter orderCreatedCounter;
    private final DistributionSummary orderAmountSummary;

    public OrderMetricsService(MeterRegistry meterRegistry) {
        this.orderCreatedCounter = Counter.builder("biz_order_created_total")
                .description("Total created orders")
                .register(meterRegistry);

        this.orderAmountSummary = DistributionSummary.builder("biz_order_amount")
                .description("Order amount distribution")
                .baseUnit("yuan")
                .register(meterRegistry);
    }

    public void recordCreatedOrder(double amount, String channel) {
        orderCreatedCounter.increment();
        orderAmountSummary.record(amount);
    }
}

这里我先保留了 channel 参数,但没有直接打成 tag,不是漏写,而是故意这样设计。原因是:

  • 如果 channel 值域稳定,比如 app/web/mini-program,可以作为 tag
  • 如果值域不稳定,贸然加 tag 很容易造成指标基数爆炸

这一点后面会展开。

补一个创建订单接口

package com.example.monitor.web;

import com.example.monitor.service.OrderMetricsService;
import jakarta.validation.constraints.DecimalMin;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.Map;

@RestController
@RequestMapping("/api/order-create")
@Validated
public class OrderCreateController {

    private final OrderMetricsService orderMetricsService;

    public OrderCreateController(OrderMetricsService orderMetricsService) {
        this.orderMetricsService = orderMetricsService;
    }

    @PostMapping
    public Map<String, Object> create(@RequestParam @DecimalMin("0.01") double amount,
                                      @RequestParam(defaultValue = "web") String channel) {
        orderMetricsService.recordCreatedOrder(amount, channel);
        return Map.of(
                "success", true,
                "amount", amount,
                "channel", channel
        );
    }
}

第六步:给线程池加监控

线上问题里,线程池堆积是特别常见的一类。只盯 HTTP RT,很容易漏掉根因。

package com.example.monitor.config;

import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.core.instrument.binder.jvm.ExecutorServiceMetrics;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.concurrent.*;

@Configuration
public class ExecutorConfig {

    @Bean(destroyMethod = "shutdown")
    public ExecutorService businessExecutor(MeterRegistry meterRegistry) {
        ThreadPoolExecutor executor = new ThreadPoolExecutor(
                4,
                8,
                60,
                TimeUnit.SECONDS,
                new LinkedBlockingQueue<>(100),
                new ThreadPoolExecutor.CallerRunsPolicy()
        );

        return ExecutorServiceMetrics.monitor(
                meterRegistry,
                executor,
                "biz_executor",
                "pool", "order"
        );
    }
}

有了这个之后,你就能在 Prometheus 中看到类似指标:

  • executor_active_threads
  • executor_pool_size_threads
  • executor_queued_tasks

这比“感觉线程池可能有问题”靠谱得多。


第七步:查看指标是否真的出来了

启动应用后,先手工验证。

查看健康检查

curl http://localhost:8080/actuator/health

查看指标列表

curl http://localhost:8080/actuator/metrics

查看 Prometheus 格式指标

curl http://localhost:8080/actuator/prometheus

压测制造一些数据

正常请求:

curl "http://localhost:8080/api/orders/1"

慢请求:

curl "http://localhost:8080/api/orders/1?slow=true"

失败请求:

curl "http://localhost:8080/api/orders/1?fail=true"

创建订单:

curl -X POST "http://localhost:8080/api/order-create?amount=299.9&channel=web"

如果一切正常,你应该能在 /actuator/prometheus 里看到这些指标中的一部分:

http_server_requests_seconds_count
http_server_requests_seconds_bucket
http_server_requests_seconds_sum
jvm_memory_used_bytes
jvm_gc_pause_seconds_count
system_cpu_usage
process_uptime_seconds
biz_order_created_total
biz_order_amount_count
biz_order_amount_sum
executor_active_threads

第八步:接入 Prometheus

prometheus.yml

global:
  scrape_interval: 15s

scrape_configs:
  - job_name: 'boot-monitor-demo'
    metrics_path: '/actuator/prometheus'
    static_configs:
      - targets: ['host.docker.internal:8080']

如果你不是 Docker 环境,直接写宿主机 IP 或域名即可。

启动 Prometheus 后,打开:

http://localhost:9090

试几个查询:

http_server_requests_seconds_count
rate(http_server_requests_seconds_count[1m])
sum(rate(http_server_requests_seconds_count{status=~"5.."}[5m]))
histogram_quantile(0.95, sum(rate(http_server_requests_seconds_bucket[5m])) by (le, uri, method))

最后这个 P95 查询是最常用的一个。


第九步:Grafana 看板最小可用方案

如果你不想一上来就做特别复杂的大盘,我建议先把这几类图补齐:

  1. 应用可用性
    • 每分钟请求量
    • 5xx 错误率
  2. 应用延迟
    • P50/P95/P99
    • 慢请求占比
  3. JVM
    • 堆内存使用
    • GC 次数与暂停时间
    • 线程数
  4. 线程池
    • active
    • queue size
  5. 业务指标
    • 订单创建次数
    • 订单金额总和或均值

下面是一个典型的指标流转时序:

sequenceDiagram
    participant U as User
    participant A as Spring Boot App
    participant M as Micrometer
    participant P as Prometheus
    participant G as Grafana
    participant Al as Alertmanager

    U->>A: 发起HTTP请求
    A->>M: 记录Timer/Counter/Gauge
    P->>A: 定时拉取 /actuator/prometheus
    A-->>P: 返回指标文本
    G->>P: 查询 PromQL
    P-->>G: 返回时序数据
    P->>Al: 触发告警规则
    Al-->>U: 发送告警通知

第十步:从指标到告警落地

监控最终要落到告警,否则只是“会看图”。

下面给一组比较实用的 Prometheus 告警规则。

alert-rules.yml

groups:
  - name: spring-boot-demo-alerts
    rules:
      - alert: ApplicationDown
        expr: up{job="boot-monitor-demo"} == 0
        for: 1m
        labels:
          severity: critical
        annotations:
          summary: "应用实例不可达"
          description: "Prometheus 连续 1 分钟无法抓取应用指标"

      - alert: HighHttp5xxRate
        expr: |
          sum(rate(http_server_requests_seconds_count{job="boot-monitor-demo",status=~"5.."}[5m]))
          /
          sum(rate(http_server_requests_seconds_count{job="boot-monitor-demo"}[5m]))
          > 0.05
        for: 5m
        labels:
          severity: warning
        annotations:
          summary: "HTTP 5xx 错误率过高"
          description: "过去 5 分钟 5xx 占比超过 5%"

      - alert: HighP95Latency
        expr: |
          histogram_quantile(
            0.95,
            sum(rate(http_server_requests_seconds_bucket{job="boot-monitor-demo"}[5m])) by (le)
          ) > 0.8
        for: 5m
        labels:
          severity: warning
        annotations:
          summary: "应用 P95 延迟过高"
          description: "过去 5 分钟整体 P95 超过 800ms"

      - alert: HighJvmHeapUsage
        expr: |
          (
            sum(jvm_memory_used_bytes{job="boot-monitor-demo",area="heap"})
            /
            sum(jvm_memory_max_bytes{job="boot-monitor-demo",area="heap"})
          ) > 0.85
        for: 10m
        labels:
          severity: warning
        annotations:
          summary: "JVM 堆使用率过高"
          description: "堆内存持续 10 分钟超过 85%"

      - alert: ThreadPoolQueueBacklog
        expr: executor_queued_tasks{job="boot-monitor-demo"} > 50
        for: 3m
        labels:
          severity: warning
        annotations:
          summary: "业务线程池队列积压"
          description: "线程池排队任务数超过 50,持续 3 分钟"

为什么这些规则比较实用?

因为它们覆盖了“四个最小生存指标”:

  • 可用性:应用是否还活着
  • 错误率:请求是否失败变多
  • 延迟:请求是否明显变慢
  • 饱和度:资源是否快耗尽

这其实就是业界常说的几个核心观测维度,只不过我们在 Spring Boot 落地时,把它们映射成了具体 PromQL。


逐步验证清单

建议你按下面顺序验证,不要一口气全上。

验证 1:应用端点是否可访问

curl http://localhost:8080/actuator/prometheus

如果这个都不通,后面就不用看了。

验证 2:Prometheus 是否抓取成功

在 Prometheus 页面检查:

up{job="boot-monitor-demo"}

结果应该是 1

验证 3:HTTP 指标是否增长

连续访问几次接口后检查:

sum(rate(http_server_requests_seconds_count[1m]))

验证 4:错误率告警是否可触发

多次访问失败接口:

for i in {1..30}; do curl "http://localhost:8080/api/orders/1?fail=true"; done

然后看:

sum(rate(http_server_requests_seconds_count{status=~"5.."}[5m]))

验证 5:延迟告警是否可触发

多次访问慢接口:

for i in {1..50}; do curl "http://localhost:8080/api/orders/1?slow=true"; done

检查:

histogram_quantile(0.95, sum(rate(http_server_requests_seconds_bucket[5m])) by (le))

验证 6:业务指标是否正常记录

for i in {1..10}; do curl -X POST "http://localhost:8080/api/order-create?amount=88.8&channel=web"; done

查询:

biz_order_created_total

常见坑与排查

这一节非常重要。很多“监控没效果”并不是技术不会,而是踩了几个典型坑。

1. /actuator/prometheus 没暴露出来

现象

  • Prometheus 抓取失败
  • 浏览器访问 /actuator/prometheus 返回 404

排查

确认配置中是否包含:

management:
  endpoints:
    web:
      exposure:
        include: health,info,metrics,prometheus

如果你只配了 health,Prometheus 当然拉不到。


2. 指标有了,但 PromQL 查询不到想要的结果

常见原因

  • 时间窗口太短
  • 没有先制造流量
  • 指标名记错
  • Spring Boot / Micrometer 版本不同导致指标标签略有差异

排查建议

先从最原始查询开始:

http_server_requests_seconds_count

再逐步加条件,而不是一上来就写一个很复杂的 histogram_quantile + sum by + rate


3. 自定义 tag 导致指标基数爆炸

这个坑我真的见过太多次了。

错误示例

Counter.builder("biz_order_created_total")
    .tag("userId", userId.toString())
    .register(meterRegistry);

如果 userId 是高基数数据,每个用户都会生成新的时序。用户一多,Prometheus 内存会迅速上涨。

正确思路

tag 只用于低基数、稳定枚举值,例如:

  • channel=web/app
  • region=cn-east/cn-north
  • result=success/fail

不要把下面这些字段直接打成 tag:

  • 用户 ID
  • 订单号
  • 请求参数原值
  • URL 中动态 ID
  • 异常 message 原文

4. P95 看起来不准

原因

  • 没开 histogram
  • 没配置合理分桶
  • 请求量太小,分位数不稳定

建议

management:
  metrics:
    distribution:
      percentiles-histogram:
        http.server.requests: true
      slo:
        http.server.requests: 100ms,200ms,500ms,1s,2s

另外,低流量服务不要过度解读 P99。样本太少时,P99 很容易“看起来很吓人,但没有统计意义”。


5. 健康检查通过,但服务其实已经不可用

原因

默认 health 只代表部分组件状态,不等于你的业务功能完整可用。

建议

把健康检查分层:

  • liveness:进程是否存活
  • readiness:是否可对外接流量
  • 业务健康检查:关键依赖是否正常

不要把所有下游依赖都塞进一个重型健康检查里,否则健康检查本身也会拖垮系统。


6. 告警太多,最后没人看

典型原因

  • 阈值拍脑袋
  • 没有 for 持续时间
  • 把单次抖动当故障
  • 告警没有分级

我的建议

先从少而稳开始:

  • critical:实例不可达、错误率暴涨
  • warning:延迟高、堆使用率高、队列堆积

先保证告警可信,再逐步扩展覆盖面。


安全/性能最佳实践

监控是基础设施,但它本身也会带来安全和性能成本。

1. 不要把 Actuator 全量暴露到公网

建议只暴露必要端点:

management:
  endpoints:
    web:
      exposure:
        include: health,info,metrics,prometheus

不要图省事直接:

include: "*"

这在测试环境可能无所谓,在线上风险很大。


2. 为 Actuator 端点加访问控制

如果项目接了 Spring Security,建议对 Actuator 端点做单独鉴权,或者仅允许 Prometheus 所在网段访问。

最简单的思路:

  • 内网暴露
  • 网关层限制
  • mTLS 或基础认证
  • Kubernetes 中结合 NetworkPolicy

3. 控制标签数量与指标数量

监控不是越多越好。每新增一个高频指标、每多一个标签维度,都会增加:

  • 应用内存开销
  • /actuator/prometheus 输出体积
  • Prometheus 抓取与存储压力

经验建议:

  • 先做“少量高价值指标”
  • tag 控制在业务可解释范围
  • 避免高基数维度

4. 对热点接口开启直方图,对全部接口谨慎评估

直方图很有用,但会增加时序数量。

如果你的服务接口很多、实例很多,可以优先:

  • 对关键接口保留细粒度分桶
  • 对普通接口降低标签维度
  • 通过公共 uri 模板归类,而不是原始 URL

5. 告警要和排障动作绑定

一个好的告警,至少应该回答三个问题:

  • 哪个服务出问题了?
  • 出的是哪类问题?
  • 值班同学第一步该查什么?

比如:

  • 高延迟告警 → 先看线程池、GC、数据库连接池
  • 高错误率告警 → 先看异常日志、下游依赖状态
  • 堆内存高告警 → 先看对象增长、GC、缓存是否失控

如果告警只写“系统异常,请及时处理”,那和没写差不多。


6. 给业务指标定义边界与口径

例如“订单创建量”要说清楚:

  • 是下单请求到达数?
  • 还是创建成功数?
  • 是否包含重试?
  • 是否按最终一致结果计数?

如果口径不清,监控面板再漂亮也会误导决策。


一个更实用的监控落地思路

如果你现在就要在项目里落地,不妨按这个顺序推进:

flowchart TD
    A[先接 Actuator + Prometheus] --> B[确认 JVM/HTTP 基础指标]
    B --> C[补线程池/数据库连接池指标]
    C --> D[增加 2~3 个关键业务指标]
    D --> E[建立最小告警集]
    E --> F[按告警噪音持续调优]

这条路线的好处是:

  • 起步快
  • 反馈快
  • 不容易一上来就过度设计

总结

Spring Boot 里的监控落地,真正有价值的不是“把 Actuator 开起来”,而是把下面这套能力打通:

  • Actuator 暴露运行信息
  • Micrometer 统一采集系统、应用、业务指标
  • Prometheus 抓取与存储时序数据
  • Grafana 可视化趋势
  • Alertmanager 把关键异常及时通知出去

如果你让我给一个中级开发者最实用的建议,我会说三点:

  1. 先抓核心指标,不要贪多
    • 可用性、错误率、延迟、饱和度,先覆盖这四类
  2. 业务指标必须补上
    • 只看 JVM 和 HTTP,很多业务故障是看不出来的
  3. 控制标签基数
    • 这是 Micrometer/Prometheus 体系里最容易被忽略、但代价最大的坑

最后给一个可执行的落地边界:

  • 如果你的应用还是单体、流量不高:先把基础指标 + 关键告警做稳
  • 如果你的应用已经多实例、微服务化:尽快统一指标规范、标签规范和告警分级
  • 如果你已经有 tracing/logging:监控指标最好和日志、链路追踪互相跳转,排障效率会提升一个量级

监控从来不是装个依赖就结束,它更像是给系统建立“体检、诊断和报警”的能力。Actuator 和 Micrometer 只是起点,但这个起点非常值得认真搭好。


分享到:

下一篇
《Web逆向实战:中级开发者如何定位并复现前端签名算法实现接口自动化调用》