跳到主要内容
版本:Next

framework-starter-monitor - 监控功能自动配置模块

1. 模块概述

framework-starter-monitor 是 epoch-framework 中的监控功能自动配置模块,集成了 SkyWalking 分布式追踪和 Spring Boot Actuator,提供了应用监控、分布式追踪、健康检查和指标收集等功能。该模块通过自动配置的方式,简化了监控功能的集成和使用,帮助开发者更好地了解应用运行状态。

2. 模块结构

framework-starter-monitor/
├── src/
│ ├── main/
│ │ ├── java/
│ │ │ └── com/epoch/framework/starter/monitor/
│ │ │ ├── config/ # 自动配置类
│ │ │ ├── tracing/ # 分布式追踪配置
│ │ │ ├── health/ # 健康检查配置
│ │ │ ├── metrics/ # 指标收集配置
│ │ │ └── support/ # 支持工具类
│ │ └── resources/
│ │ └── META-INF/
│ │ └── spring.factories # Spring Boot 自动配置入口
│ └── test/ # 测试代码
└── pom.xml # Maven 依赖配置

3. 核心功能

3.1 SkyWalking 分布式追踪

  • 自动配置 SkyWalking Agent 集成
  • 支持分布式追踪和链路分析
  • 提供服务拓扑图和性能监控
  • 支持日志关联和异常追踪

3.2 Spring Boot Actuator 集成

  • 自动配置 Actuator 端点
  • 提供应用健康状态检查
  • 支持应用信息和指标收集
  • 提供环境变量和配置信息访问

3.3 健康检查自动配置

  • 集成数据库、Redis、MQ 等健康检查
  • 支持自定义健康检查指示器
  • 提供健康状态聚合和分组
  • 支持健康检查状态的监控和报警

3.4 应用指标监控

  • 收集 JVM 运行指标
  • 提供 HTTP 请求指标
  • 支持数据源连接池指标
  • 提供缓存使用情况指标

3.5 日志集成

  • 与日志框架集成,支持日志链路追踪
  • 提供日志级别动态调整
  • 支持日志文件监控和管理
  • 提供日志收集和分析支持

4. 配置说明

4.1 SkyWalking 配置

# SkyWalking Agent 配置(通常在启动脚本中设置)
# -javaagent:/path/to/skywalking-agent.jar
# -Dskywalking.agent.service_name=epoch-application
# -Dskywalking.collector.backend_service=localhost:11800
# -Dskywalking.trace.ignore_path=/actuator/**

# SkyWalking 采样率配置
skywalking:
trace:
sample:
rate: 1.0
ignore:
path: /actuator/**,/health/**

4.2 Actuator 端点配置

management:
endpoints:
web:
exposure:
include: '*' # 在生产环境中建议只暴露必要的端点
base-path: /actuator
cors:
allowed-origins: '*'
allowed-methods: GET,POST
endpoint:
health:
show-details: always # 在生产环境中建议设置为 when_authorized
probes:
enabled: true
metrics:
enabled: true
info:
enabled: true
loggers:
enabled: true
env:
enabled: true

4.3 健康检查配置

management:
endpoint:
health:
group:
liveness:
include: livenessState,customLivenessCheck
readiness:
include: readinessState,customReadinessCheck,db,redis

4.4 指标收集配置

management:
metrics:
export:
prometheus:
enabled: true
step: 1m
distribution:
percentiles-histogram:
http.server.requests: true
percentiles:
http.server.requests: 0.5,0.9,0.95,0.99
tags:
application: ${spring.application.name}

5. 使用指南

5.1 引入依赖

<dependency>
<groupId>com.epoch</groupId>
<artifactId>framework-starter-monitor</artifactId>
<version>${epoch.version}</version>
</dependency>

<!-- 如果需要使用 Prometheus 导出指标 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
</dependency>

5.2 启动配置

在应用启动脚本中添加 SkyWalking Agent 配置:

java -javaagent:/path/to/skywalking-agent.jar \
-Dskywalking.agent.service_name=epoch-application \
-Dskywalking.collector.backend_service=localhost:11800 \
-jar epoch-application.jar

5.3 分布式追踪使用

@Service
public class OrderService {

@Autowired
private ProductService productService;

@Autowired
private PaymentService paymentService;

public Order createOrder(OrderRequest request) {
// 自动创建追踪链路
Product product = productService.getProduct(request.getProductId());
Order order = new Order();
order.setProductId(product.getId());
order.setAmount(request.getAmount());
order.setTotalPrice(product.getPrice() * request.getAmount());

// 调用其他服务,自动延续追踪链路
paymentService.processPayment(order);

return order;
}
}

5.4 健康检查使用

5.4.1 访问健康检查端点

# 获取完整健康状态
curl http://localhost:8080/actuator/health

# 获取特定健康检查组件状态
curl http://localhost:8080/actuator/health/db
curl http://localhost:8080/actuator/health/redis

# 获取分组健康状态
curl http://localhost:8080/actuator/health/liveness
curl http://localhost:8080/actuator/health/readiness

5.4.2 自定义健康检查

@Component
public class CustomHealthIndicator implements HealthIndicator {

@Autowired
private SomeService someService;

@Override
public Health health() {
try {
boolean isHealthy = someService.checkHealth();
if (isHealthy) {
return Health.up()
.withDetail("status", "UP")
.withDetail("timestamp", System.currentTimeMillis())
.build();
} else {
return Health.down()
.withDetail("status", "DOWN")
.withDetail("reason", "Service unavailable")
.build();
}
} catch (Exception e) {
return Health.down(e)
.withDetail("status", "DOWN")
.withDetail("error", e.getMessage())
.build();
}
}
}

5.5 指标监控使用

5.5.1 访问指标端点

# 获取所有指标
curl http://localhost:8080/actuator/metrics

# 获取特定指标
curl http://localhost:8080/actuator/metrics/jvm.memory.used
curl http://localhost:8080/actuator/metrics/http.server.requests

# 获取 Prometheus 格式的指标
curl http://localhost:8080/actuator/prometheus

5.5.2 自定义指标收集

@Service
public class OrderService {

private final Counter orderCreatedCounter;
private final Timer orderProcessingTimer;

public OrderService(MeterRegistry meterRegistry) {
// 创建订单创建计数器
this.orderCreatedCounter = Counter.builder("order.created")
.description("Number of orders created")
.tag("application", "order-service")
.register(meterRegistry);

// 创建订单处理计时器
this.orderProcessingTimer = Timer.builder("order.processing.time")
.description("Time taken to process orders")
.tag("application", "order-service")
.register(meterRegistry);
}

public Order createOrder(OrderRequest request) {
// 记录订单创建数量
orderCreatedCounter.increment();

// 记录订单处理时间
return orderProcessingTimer.record(() -> {
// 订单处理逻辑
Order order = new Order();
// ...
return order;
});
}
}

5.6 日志集成使用

@Service
public class UserService {

private static final Logger logger = LoggerFactory.getLogger(UserService.class);

public User getUserById(Long id) {
logger.info("Getting user with id: {}", id);
try {
User user = userRepository.findById(id);
logger.debug("Found user: {}", user);
return user;
} catch (Exception e) {
logger.error("Error getting user with id: {}", id, e);
throw new ServiceException("Failed to get user");
}
}
}

6. 自定义配置

6.1 自定义健康检查指示器

@Configuration
public class HealthCheckConfig {

@Bean
public HealthIndicator databaseHealthIndicator(DataSource dataSource) {
return new AbstractHealthIndicator() {
@Override
protected void doHealthCheck(Health.Builder builder) throws Exception {
try (Connection connection = dataSource.getConnection()) {
DatabaseMetaData metaData = connection.getMetaData();
builder.up()
.withDetail("database", metaData.getDatabaseProductName())
.withDetail("version", metaData.getDatabaseProductVersion())
.withDetail("url", metaData.getURL())
.withDetail("user", metaData.getUserName());
}
}
};
}

@Bean
public HealthIndicator customHealthIndicator() {
return () -> Health.up()
.withDetail("custom-metric", "custom-value")
.build();
}
}

6.2 自定义指标收集

@Configuration
public class MetricsConfig {

@Bean
public Gauge customGauge(MeterRegistry registry) {
return Gauge.builder("custom.gauge", () -> {
// 自定义指标计算逻辑
return someService.getCustomMetricValue();
})
.description("Custom gauge metric")
.tag("application", "my-app")
.register(registry);
}

@Bean
public MeterBinder customMetricsBinder() {
return registry -> {
Counter.builder("custom.counter")
.description("Custom counter metric")
.register(registry);
};
}
}

6.3 自定义追踪配置

@Configuration
public class TracingConfig {

@Bean
public Sampler customSampler() {
// 自定义采样策略
return Sampler.create(0.5); // 采样率 50%
}

@Bean
public SpanReporter customSpanReporter() {
return span -> {
// 自定义 Span 报告逻辑
if (span.isError()) {
// 处理错误 Span
log.error("Error span: {}", span);
}
};
}
}

6.4 自定义 Actuator 端点

@Component
@Endpoint(id = "custom-endpoint")
public class CustomEndpoint {

@ReadOperation
public Map<String, Object> customInfo() {
Map<String, Object> info = new HashMap<>();
info.put("timestamp", System.currentTimeMillis());
info.put("custom-data", "custom-value");
info.put("status", "OK");
return info;
}

@WriteOperation
public void updateCustomData(@Selector String key, @Nullable String value) {
// 更新自定义数据的逻辑
someService.updateCustomData(key, value);
}
}

7. 最佳实践

7.1 生产环境配置建议

  • 限制 Actuator 端点访问:只暴露必要的端点,并通过网络防火墙或 Spring Security 保护
  • 配置合适的采样率:根据应用流量和性能需求,配置合适的 SkyWalking 采样率
  • 启用 Prometheus 导出:使用 Prometheus 收集指标,并结合 Grafana 进行可视化
  • 设置健康检查分组:使用 liveness 和 readiness 分组,支持 Kubernetes 等容器平台的健康检查

7.2 性能优化建议

  • 减少指标收集数量:只收集必要的指标,避免收集过多低价值指标
  • 设置合理的指标采样间隔:根据指标类型设置合适的采样间隔
  • 优化健康检查逻辑:确保健康检查逻辑简单、快速,避免影响应用性能
  • 使用异步健康检查:对于耗时的健康检查,使用异步方式执行

7.3 安全配置建议

  • 保护 Actuator 端点:使用 Spring Security 或网络防火墙限制访问
  • 避免暴露敏感信息:不要在 Actuator 端点中暴露敏感的环境变量或配置信息
  • 使用 HTTPS 访问:在生产环境中,使用 HTTPS 访问所有监控端点
  • 配置访问控制:基于角色的访问控制,只允许授权用户访问监控端点

7.4 监控策略建议

  • 建立监控仪表盘:使用 Grafana 等工具建立统一的监控仪表盘
  • 设置合理的报警阈值:根据应用特点设置合理的报警阈值
  • 定期分析监控数据:定期分析监控数据,发现潜在问题和优化点
  • 监控关联分析:将分布式追踪、日志和指标数据关联分析,快速定位问题

8. 常见问题

8.1 SkyWalking 连接失败

原因:SkyWalking Agent 配置不正确或 SkyWalking OAP 服务器未启动。

解决方案

  • 检查 SkyWalking Agent 的配置参数是否正确
  • 确保 SkyWalking OAP 服务器已启动并可访问
  • 检查网络连接是否正常
  • 查看应用日志和 SkyWalking 日志,查找错误信息

8.2 Actuator 端点无法访问

原因:端点配置不正确或被安全机制阻止。

解决方案

  • 检查 Actuator 端点是否正确暴露
  • 检查网络防火墙是否允许访问 Actuator 端口
  • 检查 Spring Security 配置是否允许访问 Actuator 端点
  • 确保 Actuator 依赖已正确引入

8.3 健康检查异常

原因:应用依赖的服务不可用或健康检查逻辑错误。

解决方案

  • 检查应用依赖的服务(如数据库、Redis、MQ 等)是否正常运行
  • 查看健康检查的详细信息,定位具体问题
  • 检查自定义健康检查逻辑是否存在错误
  • 确保健康检查的超时时间设置合理

8.4 指标收集不完整

原因:指标配置不正确或指标收集器未正确注册。

解决方案

  • 检查指标收集器是否正确配置
  • 确保自定义指标已正确注册到 MeterRegistry
  • 检查指标导出配置是否正确
  • 查看应用日志,查找指标收集相关错误

8.5 日志与追踪不关联

原因:日志框架配置不正确或 SkyWalking Agent 版本不兼容。

解决方案

  • 确保日志框架已正确配置 SkyWalking 集成
  • 检查 SkyWalking Agent 版本与应用日志框架版本是否兼容
  • 查看 SkyWalking 文档,了解正确的日志集成配置
  • 检查应用日志格式是否包含追踪 ID

9. 版本变更

9.1 主要变更

  • 3.4.0

    • 更新监控功能自动配置,支持 SkyWalking 9.0.0
    • 优化健康检查配置,支持分组健康检查
    • 完善指标收集功能,增加更多 JVM 和应用指标
    • 增强 Actuator 端点安全配置
  • 3.3.0

    • 优化分布式追踪配置,支持自定义采样策略
    • 新增自定义 Actuator 端点支持
    • 完善日志与追踪的关联配置
    • 增加监控数据的可视化支持
  • 3.2.0

    • 初始版本,提供 SkyWalking 分布式追踪和 Spring Boot Actuator 集成
    • 支持健康检查和指标收集
    • 提供基本的监控配置和使用指南