通常使用 Grafana 进行监控数据的展示,使用 AlertManager 组件进行提前预警
Skywalking 是使用探针技术(JavaAgent)来实现的。通过在 Java 的启动参数中,加入 javaagent 的 Jar 包,即可将性能数据和调用链数据封装,并发送到Skywalking 的服务器
Micrometer
Micrometer 为 Java 平台上的性能数据收集提供了一个通用的 API,应用程序只需要使用 Micrometer 的通用 API 来收集性能指标即可。Micrometer 会负责完成与不同监控系统的适配工作。这就使得切换监控系统变得很容易。Micrometer 还支持推送数据到多个不同的监控系统。Micrometer类似日志系统中SLF4J。
Micrometer中有两个最核心的概念,分别是是计量器(Meter)和计量器注册表(MeterRegistry)
计量器(Meter)
Meter用来收集性能指标数据(Metris)
Prometheus 整体的架构
时序数据库(TSDB)
全称时间序列数据库,主要分为时间戳(timestamp)、标签(tag)、存档(filed)三大部分,按照时间顺序记录数据。
物联网时代的兴星,万物互联的的思想,利用物联网设备的传感器传输设备的实时数据到时序数据库,对设备的异常、IO等数据进行记录。
指标依赖
// actuator依赖提供指标
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
<version>2.6.3</version>
</dependency>
// 将指标转换成prometheus可使用的格式
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
<version>1.8.2</version>
</dependency>
//Counter只允许增加值,Counter所表示的计数值是double类型,默认情况下增加的值是1.0
Counter counter = registry.counter("api" + monitoring.method(), tags);
DistributionSummary summer = registry.summary("api" + monitoring.method(),tags);
summer.record(getByteSize(result));
Timer timer = registry.timer("api_" + monitoring.method(), tags);
// actuator依赖提供指标 org.springframework.boot spring-boot-starter-actuator 2.6.3
// 将指标转换成prometheus可使用的格式 io.micrometer micrometer-registry-prometheus 1.8.2
指标依赖
1、不依赖于时间单位的记录值的测量,例如服务器有效负载值,缓存的命中率等。
举个相对具体的例子: public class DistributionSummaryMain {
private static final DistributionSummary DS = DistributionSummary.builder("cacheHitPercent")
.register(new SimpleMeterRegistry());
private static final LoadingCache<String, String> CACHE = CacheBuilder.newBuilder()
.maximumSize(1000)
.recordStats()
.expireAfterWrite(60, TimeUnit.SECONDS)
.build(new CacheLoader<String, String>() {
@Override
public String load(String s) throws Exception {
return selectFromDatabase();
}
});
public static void main(String[] args) throws Exception{
String key = "doge";
String value = CACHE.get(key);
record();
}
private static void record()throws Exception{
CacheStats stats = CACHE.stats();
BigDecimal hitCount = new BigDecimal(stats.hitCount());
BigDecimal requestCount = new BigDecimal(stats.requestCount());
DS.record(hitCount.divide(requestCount,2,BigDecimal.ROUND_HALF_DOWN).doubleValue());
}
DistributionSummary summary = DistributionSummary
.builder("response_size")
.description("response_size") // optional
.baseUnit("byte") // optional (1)
.tags("zizhen", "test") // optional
.scale(888) // optional (2)
.register(registry);
summary.record(999);
public final void record(double amount) {
if (amount >= 0.0) {
double scaledAmount = this.scale * amount;
this.histogram.recordDouble(scaledAmount);
this.recordNonNegative(scaledAmount);
}
}
{name=~"response_size.*"}
package com.olive.monitor;
import javax.annotation.PostConstruct;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import io.micrometer.core.instrument.Counter;
import io.micrometer.core.instrument.DistributionSummary;
import io.micrometer.core.instrument.MeterRegistry;
@Component
public class NativeMetricsMontior {
/**
* 支付次数
*/
private Counter payCount;
/**
* 支付金额统计
*/
private DistributionSummary payAmountSum;
@Autowired
private MeterRegistry registry;
@PostConstruct
private void init() {
payCount = registry.counter("pay_request_count", "payCount", "pay-count");
payAmountSum = registry.summary("pay_amount_sum", "payAmountSum", "pay-amount-sum");
}
public Counter getPayCount() {
return payCount;
}
public DistributionSummary getPayAmountSum() {
return payAmountSum;
}
}
方式二
通过引入micrometer-registry-prometheus包,该包结合prometheus,对micrometer进行了封装
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
</dependency>
同样定义两个metrics文章来源站点https://www.yii666.com/
package com.olive.monitor;
import javax.annotation.PostConstruct;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import io.prometheus.client.CollectorRegistry;
import io.prometheus.client.Counter;
@Component
public class PrometheusMetricsMonitor {
/**
* 订单发起次数
*/
private Counter orderCount;
/**
* 金额统计
*/
private Counter orderAmountSum;
@Autowired
private CollectorRegistry registry;
@PostConstruct
private void init() {
orderCount = Counter.build().name("order_request_count")
.help("order request count.")
.labelNames("orderCount")
.register();
orderAmountSum = Counter.build().name("order_amount_sum")
.help("order amount sum.")
.labelNames("orderAmountSum")
.register();
registry.register(orderCount);
registry.register(orderAmountSum);
}
public Counter getOrderCount() {
return orderCount;
}
public Counter getOrderAmountSum() {
return orderAmountSum;
}
}
prometheus 每个组一条数据(含Tag) value 不一样
api_bytes_byte_sum{instance="10.10.80.5:18432",corpNo= "20210709105445110145"}[5m]