目标:
jvm监控,应用 网关\ 服务监控(自定义监控指标)
springboot 接入:
Maven引入:
<!--actuator-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!-- prometheus -->
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
<version>1.5.1</version>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
<version>1.5.1</version>
</dependency>
Ymal配置:
management:
health:
rabbit:
enabled: false
elasticsearch:
enabled: false
endpoints:
web:
exposure:
include: '*'
metrics:
export:
prometheus:
enabled: true
tags:
application: ${spring.application.name}
启动类:
@SpringBootApplication
@Slf4j
public class ApplicationGateWay {
public static void main(String[] args) throws Exception {
SpringApplication.run(ApplicationGateWay.class, args);
}
@Bean
MeterRegistryCustomizer<MeterRegistry> meterRegistryCustomizer(@Value("${spring.application.name}") String applicationName) {
return meterRegistry -> meterRegistry.config()
.commonTags("application", applicationName);
}
}
启动项目,访问http://127.0.0.1:7721/actuator
{
"_links": {
"self": {
"href": "http://127.0.0.1:7721/actuator",
"templated": false
},
"nacosconfig": {
"href": "http://127.0.0.1:7721/actuator/nacosconfig",
"templated": false
},
"beans": {
"href": "http://127.0.0.1:7721/actuator/beans",
"templated": false
},
"caches": {
"href": "http://127.0.0.1:7721/actuator/caches",
"templated": false
},
"caches-cache": {
"href": "http://127.0.0.1:7721/actuator/caches/{cache}",
"templated": true
},
"health": {
"href": "http://127.0.0.1:7721/actuator/health",
"templated": false
},
"health-path": {
"href": "http://127.0.0.1:7721/actuator/health/{*path}",
"templated": true
},
"info": {
"href": "http://127.0.0.1:7721/actuator/info",
"templated": false
},
"conditions": {
"href": "http://127.0.0.1:7721/actuator/conditions",
"templated": false
},
"configprops": {
"href": "http://127.0.0.1:7721/actuator/configprops",
"templated": false
},
"env-toMatch": {
"href": "http://127.0.0.1:7721/actuator/env/{toMatch}",
"templated": true
},
"env": {
"href": "http://127.0.0.1:7721/actuator/env",
"templated": false
},
"logfile": {
"href": "http://127.0.0.1:7721/actuator/logfile",
"templated": false
},
"loggers": {
"href": "http://127.0.0.1:7721/actuator/loggers",
"templated": false
},
"loggers-name": {
"href": "http://127.0.0.1:7721/actuator/loggers/{name}",
"templated": true
},
"heapdump": {
"href": "http://127.0.0.1:7721/actuator/heapdump",
"templated": false
},
"threaddump": {
"href": "http://127.0.0.1:7721/actuator/threaddump",
"templated": false
},
"prometheus": {
"href": "http://127.0.0.1:7721/actuator/prometheus",
"templated": false
},
"metrics-requiredMetricName": {
"href": "http://127.0.0.1:7721/actuator/metrics/{requiredMetricName}",
"templated": true
},
"metrics": {
"href": "http://127.0.0.1:7721/actuator/metrics",
"templated": false
},
"scheduledtasks": {
"href": "http://127.0.0.1:7721/actuator/scheduledtasks",
"templated": false
},
"mappings": {
"href": "http://127.0.0.1:7721/actuator/mappings",
"templated": false
},
"sentinel": {
"href": "http://127.0.0.1:7721/actuator/sentinel",
"templated": false
},
"refresh": {
"href": "http://127.0.0.1:7721/actuator/refresh",
"templated": false
},
"features": {
"href": "http://127.0.0.1:7721/actuator/features",
"templated": false
}
}
}
访问 http://127.0.0.1:7721/actuator/prometheus
返回Prometheus收集的监控指标及自定义监控指标项
Prometheus接入:
prometheus.yml增加配置,重启 prometheus
- job_name: 'order-center-service' #应用名称,和1.3中applicationName保持一致
metrics_path: '/actuator/prometheus' #暴露监控指标路径
static_configs:
- targets:
- 192.168.0.130:7721 #服务地址
Grafana监控配置:
jvm及http相关指标监控大盘Grafana官方提供有很多模板,可以自行查询使用。
官网地址:[https://grafana.com/grafana/dashboards/](https://grafana.com/grafana/dashboards/)
dubbo服务监控
自定义监控指标
import io.prometheus.client.Counter;
import io.prometheus.client.Gauge;
import io.prometheus.client.Histogram;
import io.prometheus.client.Summary;
/**
* 自定义指标
* @author zhucy
*/
public class Metrics {
/**
* 计数器可以用于记录只会增加不会减少的指标类型,比如记录应用请求的总量(http_requests_total),
* cpu使用时间(process_cpu_seconds_total)等。 一般而言,Counter类型的metrics指标在命名中
* 我们使用_total结束。
*/
public static Counter requestCounter = Counter.build()
.name("dubbo_server_http_requests_total")
.labelNames("application","path", "method")
.help("Total requests.").register();
/**
* 使用Gauge可以反映应用的当前状态,例如在监控主机时,主机当前空闲的内容大小(node_memory_MemFree),
* 可用内存大小(node_memory_MemAvailable)。或者容器当前的CPU使用率,内存使用率。这里我们使用
* Gauge记录当前应用正在处理的Http请求数量。
*/
public static Gauge inprogressRequests = Gauge.build()
.name("dubbo_server_http_inprogress_requests").labelNames("application", "path", "method")
.help("Inprogress requests.").register();
/**
* 主要用于在指定分布范围内(Buckets)记录大小(如http request bytes)或者事件发生的次数。
* 以请求响应时间requests_latency_seconds为例
*/
public static Histogram requestLatencyHistogram = Histogram.build()
.labelNames("application", "path", "method")
.name("dubbo_server_http_requests_latency_seconds_histogram")
.help("Request latency in seconds.")
.register();
public static Histogram.Timer histogramRequestTimer;
/**
* 和Histogram类似,不同在于Histogram可以通过histogram_quantile函数在服务器端计算分位数,而
* Sumamry的分位数则是直接在客户端进行定义。因此对于分位数的计算。 Summary在通过PromQL进行查询时
* 有更好的性能表现,而Histogram则会消耗更多的资源。相对的对于客户端而言Histogram消耗的资源更少
*/
public static Summary requestLatency = Summary.build()
.name("dubbo_server_http_requests_latency_seconds_summary")
.quantile(0.5, 0.05)
.quantile(0.9, 0.01)
.labelNames("application", "path", "method")
.help("Request latency in seconds.").register();
public static Summary.Timer requestTimer;
public Metrics(){
}
}
自定义dubbo filter
import com.alibaba.dubbo.common.Constants;
import com.alibaba.dubbo.common.extension.Activate;
import com.alibaba.dubbo.rpc.*;
import com.alibaba.dubbo.rpc.support.RpcUtils;
import com.xfs.oms.constants.Metrics;
import com.xfs.oms.enums.ApplicationNameEnum;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
/**
* dubbo filter扩展
* @author zhucy
*/
@Activate(group = Constants.PROVIDER)
@Slf4j
public class PrometheusFilter implements Filter {
@Override
public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
log.info("----------------prometheus filter---------------");
String serviceName = invoker.getInterface().getName();
String methodName = RpcUtils.getMethodName(invocation);
Metrics.inprogressRequests.labels(ApplicationNameEnum.orderCenterService.getName(),serviceName,methodName).inc();
Metrics.histogramRequestTimer = Metrics.requestLatencyHistogram.labels(ApplicationNameEnum.orderCenterService.getName(),serviceName, methodName).startTimer();
Metrics.requestTimer = Metrics.requestLatency.labels(ApplicationNameEnum.orderCenterService.getName(),serviceName, methodName).startTimer();
Long beginTime = System.currentTimeMillis();
try {
Result result = invoker.invoke(invocation);
return result;
} catch (RpcException e) {
Metrics.exceptionCounter.labels(ApplicationNameEnum.orderCenterService.getName(),serviceName, methodName).inc();
log.error("PrometheusFilter.RpcException>>>methodName:{}",serviceName + "." + methodName);
throw e;
} finally {
Metrics.requestCounter.labels(ApplicationNameEnum.orderCenterService.getName(),serviceName, methodName).inc();
Metrics.inprogressRequests.labels(ApplicationNameEnum.orderCenterService.getName(),serviceName,methodName).dec();
Metrics.histogramRequestTimer.observeDuration();
Metrics.requestTimer.observeDuration();
log.info("PrometheusFilter>>>methodName:{},times:{}",serviceName + "." + methodName, System.currentTimeMillis() - beginTime);
}
}
}
设置仪表盘