本文目录导读:

我来给你一个完整的Java指标统计(Metrics)实操案例,从基础到进阶。
基础实现方案
简单的计数器实现
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.ConcurrentHashMap;
import java.util.Map;
public class SimpleMetrics {
// 原子计数器
private AtomicLong requestCount = new AtomicLong(0);
private AtomicLong successCount = new AtomicLong(0);
private AtomicLong failureCount = new AtomicLong(0);
// 耗时统计(毫秒)
private AtomicLong totalTime = new AtomicLong(0);
// 记录请求
public void recordRequest() {
requestCount.incrementAndGet();
}
// 记录成功
public void recordSuccess(long timeCost) {
successCount.incrementAndGet();
totalTime.addAndGet(timeCost);
}
// 记录失败
public void recordFailure() {
failureCount.incrementAndGet();
}
// 获取统计信息
public Map<String, Object> getStats() {
Map<String, Object> stats = new HashMap<>();
long total = requestCount.get();
long success = successCount.get();
long failure = failureCount.get();
stats.put("totalRequests", total);
stats.put("successCount", success);
stats.put("failureCount", failure);
stats.put("successRate", total > 0 ? (double)success/total * 100 : 0);
stats.put("averageTime", success > 0 ? totalTime.get()/success : 0);
return stats;
}
}
使用示例
public class MetricsDemo {
public static void main(String[] args) throws InterruptedException {
SimpleMetrics metrics = new SimpleMetrics();
// 模拟请求
for (int i = 0; i < 100; i++) {
metrics.recordRequest();
long startTime = System.currentTimeMillis();
try {
// 模拟业务处理
Thread.sleep((long)(Math.random() * 100));
if (Math.random() > 0.1) { // 90%成功率
metrics.recordSuccess(System.currentTimeMillis() - startTime);
} else {
metrics.recordFailure();
}
} catch (Exception e) {
metrics.recordFailure();
}
}
// 输出统计结果
System.out.println("统计结果: " + metrics.getStats());
}
}
使用Micrometer(推荐的生产方案)
引入依赖
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-core</artifactId>
<version>1.12.0</version>
</dependency>
<!-- 如果需要Prometheus输出 -->
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
<version>1.12.0</version>
</dependency>
业务指标监控类
import io.micrometer.core.instrument.*;
import io.micrometer.core.instrument.Timer;
import io.micrometer.core.instrument.composite.CompositeMeterRegistry;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;
public class BusinessMetrics {
private final MeterRegistry registry;
// 计数器示例
private final Counter orderCounter;
private final Counter paymentCounter;
private final Counter refundCounter;
// 仪表盘示例(实时值)
private final Gauge activeUsers;
private final Gauge queueSize;
// 计时器示例
private final Timer orderProcessTime;
private final Timer paymentProcessTime;
// 分布摘要示例(延迟分布)
private final DistributionSummary orderAmount;
// 自定义状态
private final AtomicLong activeUsersValue = new AtomicLong(0);
private final AtomicLong queueSizeValue = new AtomicLong(0);
public BusinessMetrics(MeterRegistry registry) {
this.registry = registry;
// 初始化计数器
orderCounter = Counter.builder("orders.total")
.description("总订单数")
.tag("type", "business")
.register(registry);
paymentCounter = Counter.builder("payments.total")
.description("总支付数")
.register(registry);
refundCounter = Counter.builder("refunds.total")
.description("总退款数")
.register(registry);
// 初始化Gauge
activeUsers = Gauge.builder("users.active", activeUsersValue,
AtomicLong::doubleValue)
.description("活跃用户数")
.register(registry);
queueSize = Gauge.builder("queue.size", queueSizeValue,
AtomicLong::doubleValue)
.description("队列大小")
.register(registry);
// 初始化Timer
orderProcessTime = Timer.builder("order.process.time")
.description("订单处理时间")
.publishPercentiles(0.5, 0.95, 0.99)
.publishPercentileHistogram()
.register(registry);
paymentProcessTime = Timer.builder("payment.process.time")
.description("支付处理时间")
.register(registry);
// 初始化DistributionSummary
orderAmount = DistributionSummary.builder("order.amount")
.description("订单金额分布")
.publishPercentiles(0.5, 0.75, 0.9, 0.99)
.register(registry);
}
// 记录订单
public void recordOrder() {
orderCounter.increment();
}
// 记录支付
public void recordPayment() {
paymentCounter.increment();
}
// 记录订单处理时间
public void recordOrderProcessTime(long duration, TimeUnit unit) {
orderProcessTime.record(duration, unit);
}
// 带lambda的计时方式
public <T> T recordOrderProcess(Supplier<T> supplier) {
return orderProcessTime.record(supplier);
}
// 记录订单金额
public void recordOrderAmount(double amount) {
orderAmount.record(amount);
}
// 更新活跃用户数
public void updateActiveUsers(int count) {
activeUsersValue.set(count);
}
// 更新队列大小
public void updateQueueSize(int size) {
queueSizeValue.set(size);
}
}
实际业务使用
import java.time.LocalDateTime;
import java.util.Random;
import java.util.concurrent.TimeUnit;
public class MetricsService {
private final BusinessMetrics metrics;
private final Random random = new Random();
public MetricsService(MeterRegistry registry) {
this.metrics = new BusinessMetrics(registry);
}
// 订单处理
public void processOrder(Order order) {
long startTime = System.nanoTime();
try {
// 模拟业务处理
Thread.sleep(random.nextInt(200));
// 记录订单
metrics.recordOrder();
metrics.recordOrderAmount(order.getAmount());
// 记录处理时间
metrics.recordOrderProcessTime(
System.nanoTime() - startTime,
TimeUnit.NANOSECONDS
);
} catch (Exception e) {
// 错误处理
}
}
// 支付处理
public void processPayment(Payment payment) {
long startTime = System.nanoTime();
try {
// 模拟支付处理
Thread.sleep(random.nextInt(100));
// 记录支付
metrics.recordPayment();
// 记录处理时间
metrics.recordOrderProcessTime(
System.nanoTime() - startTime,
TimeUnit.NANOSECONDS
);
} catch (Exception e) {
// 错误处理
}
}
// 更新系统状态
public void updateSystemStatus() {
metrics.updateActiveUsers(random.nextInt(10000));
metrics.updateQueueSize(random.nextInt(1000));
}
}
Spring Boot集成方案
添加依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
</dependency>
配置属性
# application.yml
management:
endpoints:
web:
exposure:
include: health,info,metrics,prometheus
metrics:
tags:
application: ${spring.application.name}
export:
prometheus:
enabled: true
step: 1m
# 自定义指标标签
spring:
application:
name: metrics-demo
自定义指标注册
import io.micrometer.core.instrument.MeterRegistry;
import org.springframework.stereotype.Component;
@Component
public class CustomMetricsCollector {
private final MeterRegistry meterRegistry;
public CustomMetricsCollector(MeterRegistry meterRegistry) {
this.meterRegistry = meterRegistry;
initializeMetrics();
}
private void initializeMetrics() {
// 注册自定义指标
meterRegistry.gauge("custom.metric.value", Tags.of("type", "business"),
this, CustomMetricsCollector::getCustomValue);
}
private double getCustomValue() {
// 返回实际的指标值
return Math.random() * 100;
}
}
定时任务收集指标
import io.micrometer.core.instrument.MeterRegistry;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
@Component
public class MetricScheduledTask {
private final MeterRegistry meterRegistry;
public MetricScheduledTask(MeterRegistry meterRegistry) {
this.meterRegistry = meterRegistry;
}
@Scheduled(fixedRate = 60000) // 每分钟执行一次
public void collectMetrics() {
// 收集JVM内存指标
meterRegistry.gauge("jvm.memory.used",
Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory());
// 收集线程指标
meterRegistry.gauge("thread.active.count",
(double) Thread.activeCount());
// 收集自定义业务指标
// ...
}
}
实际监控示例
完整的API监控
import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.core.instrument.Timer;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/api")
public class ApiMetricsController {
private final MeterRegistry meterRegistry;
private final Counter apiCallCounter;
private final Counter errorCounter;
private final Timer responseTime;
public ApiMetricsController(MeterRegistry meterRegistry) {
this.meterRegistry = meterRegistry;
this.apiCallCounter = Counter.builder("api.calls.total")
.description("API调用次数")
.register(meterRegistry);
this.errorCounter = Counter.builder("api.errors.total")
.description("API错误次数")
.register(meterRegistry);
this.responseTime = Timer.builder("api.response.time")
.description("API响应时间")
.publishPercentiles(0.5, 0.95, 0.99)
.register(meterRegistry);
}
@GetMapping("/users/{id}")
public User getUser(@PathVariable Long id) {
Timer.Sample sample = Timer.start(meterRegistry);
try {
apiCallCounter.increment();
// 业务逻辑
User user = findUser(id);
sample.stop(responseTime);
return user;
} catch (Exception e) {
errorCounter.increment();
sample.stop(responseTime);
throw e;
}
}
}
数据库监控
@Component
public class DatabaseMetrics {
private final MeterRegistry meterRegistry;
private final Timer queryTimer;
private final Counter queryCounter;
private final Counter slowQueryCounter;
public DatabaseMetrics(MeterRegistry meterRegistry) {
this.meterRegistry = meterRegistry;
this.queryTimer = Timer.builder("db.query.time")
.description("数据库查询时间")
.register(meterRegistry);
this.queryCounter = Counter.builder("db.query.total")
.description("数据库查询次数")
.register(meterRegistry);
this.slowQueryCounter = Counter.builder("db.slow.query.total")
.description("慢查询次数")
.register(meterRegistry);
}
public <T> T recordQuery(String queryName, Supplier<T> query) {
queryCounter.increment();
return queryTimer.record(() -> {
long startTime = System.currentTimeMillis();
T result = query.get();
long duration = System.currentTimeMillis() - startTime;
if (duration > 1000) { // 超过1秒的慢查询
slowQueryCounter.increment();
log.warn("慢查询: {} 耗时: {}ms", queryName, duration);
}
return result;
});
}
}
Prometheus + Grafana可视化
Prometheus配置
# prometheus.yml
scrape_configs:
- job_name: 'java-app'
metrics_path: '/actuator/prometheus'
scrape_interval: 15s
static_configs:
- targets: ['localhost:8080']
Grafana Dashboard配置示例
{
"panels": [
{
"title": "API请求率",
"type": "graph",
"targets": [
{
"expr": "rate(api_calls_total[5m])",
"legendFormat": "请求率"
}
]
},
{
"title": "响应时间P99",
"type": "graph",
"targets": [
{
"expr": "histogram_quantile(0.99, rate(api_response_time_seconds_bucket[5m]))",
"legendFormat": "P99"
}
]
}
]
}
最佳实践建议
选择合适的指标类型
- Counter: 只增不减的计数(请求数、错误数)
- Gauge: 可增可减的瞬时值(内存使用、连接数)
- Timer: 耗时统计(请求延迟、执行时间)
- DistributionSummary: 数值分布(请求大小、金额)
性能优化
- 使用原子操作(AtomicLong)而不是锁
- 批量处理指标数据
- 异步采集非关键指标
监控要点
- 核心业务指标(订单量、转化率)
- 系统资源(CPU、内存、磁盘)
- 应用性能(响应时间、吞吐量)
- 错误监控(异常频率、错误类型)
告警设置
# 告警规则示例
groups:
- name: java_app_alerts
rules:
- alert: HighErrorRate
expr: rate(error_count_total[5m]) > 0.1
for: 5m
labels:
severity: critical
annotations:
summary: "错误率过高"
这套方案可以应对大部分Java应用的指标监控需求,根据实际场景,你可以选择简单计数器或完整的Micrometer方案。
版权声明:足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播