pom.xml 관련 종속성을 도입합니다
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.olive</groupId> <artifactId>prometheus-meter-demo</artifactId> <version>0.0.1-SNAPSHOT</version> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.3.7.RELEASE</version> <relativePath /> </parent> <properties> <java.version>1.8</java.version> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <spring-boot.version>2.3.7.RELEASE</spring-boot.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <!-- Micrometer Prometheus registry --> <dependency> <groupId>io.micrometer</groupId> <artifactId>micrometer-registry-prometheus</artifactId> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>${spring-boot.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> </project>
micrometer
코어 패키지 클래스를 직접 사용하여 정의하고 등록합니다. 표시기 micrometer
核心包的类进行指标定义和注册
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
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 4种常用Metrics
Counter
连续增加不会减少的计数器,可以用于记录只增不减的类型,例如:网站访问人数,系统运行时间等。
对于Counter类型的指标,只包含一个inc()的方法,就是用于计数器+1.
一般而言,Counter类型的metric指标在冥冥中我们使用_total结束,如http_requests_total.
Gauge
可增可减的仪表盘,曲线图
对于这类可增可减的指标,用于反应应用的当前状态。
例如在监控主机时,主机当前空闲的内存大小,可用内存大小等等。
对于Gauge指标的对象则包含两个主要的方法inc()和dec(),用于增加和减少计数。
Histogram
主要用来统计数据的分布情况,这是一种特殊的metrics数据类型,代表的是一种近似的百分比估算数值,统计所有离散的指标数据在各个取值区段内的次数。例如:我们想统计一段时间内http请求响应小于0.005秒、小于0.01秒、小于0.025秒的数据分布情况。那么使用Histogram采集每一次http请求的时间,同时设置bucket。
Summary
Summary和Histogram非常相似,都可以统计事件发生的次数或者大小,以及其分布情况,他们都提供了对时间的计数_count以及值的汇总_sum,也都提供了可以计算统计样本分布情况的功能,不同之处在于Histogram可以通过histogram_quantile函数在服务器计算分位数。而Sumamry的分位数则是直接在客户端进行定义的。因此对于分位数的计算,Summary在通过PromQL进行查询的时候有更好的性能表现,而Histogram则会消耗更多的资源,但是相对于客户端而言Histogram消耗的资源就更少。用哪个都行,根据实际场景自由调整即可。
定义两个controller分别使用NativeMetricsMontior
和PrometheusMetricsMonitor
package com.olive.controller; import java.util.Random; import javax.annotation.Resource; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import com.olive.monitor.NativeMetricsMontior; @RestController public class PayController { @Resource private NativeMetricsMontior monitor; @RequestMapping("/pay") public String pay(@RequestParam("amount") Double amount) throws Exception { // 统计支付次数 monitor.getPayCount().increment(); Random random = new Random(); //int amount = random.nextInt(100); if(amount==null) { amount = 0.0; } // 统计支付总金额 monitor.getPayAmountSum().record(amount); return "支付成功, 支付金额: " + amount; } } package com.olive.controller; import java.util.Random; import javax.annotation.Resource; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import com.olive.monitor.PrometheusMetricsMonitor; @RestController public class OrderController { @Resource private PrometheusMetricsMonitor monitor; @RequestMapping("/order") public String order(@RequestParam("amount") Double amount) throws Exception { // 订单总数 monitor.getOrderCount() .labels("orderCount") .inc(); Random random = new Random(); //int amount = random.nextInt(100); if(amount==null) { amount = 0.0; } // 统计订单总金额 monitor.getOrderAmountSum() .labels("orderAmountSum") .inc(amount); return "下单成功, 订单金额: " + amount; } }
启动服务
访问http://127.0.0.1:9595/actuator/prometheus
;正常看到监测数据
改变amount多次方式http://127.0.0.1:8080/order?amount=100
和http://127.0.0.1:8080/pay?amount=10
后;再访问http://127.0.0.1:9595/actuator/prometheus
。查看监控数据
项目中按照上面说的方式进行数据埋点监控不太现实;在spring项目中基本通过AOP进行埋点监测。比如写一个切面Aspect
package com.olive.aspect; import java.time.LocalDate; import java.util.concurrent.TimeUnit; import javax.servlet.http.HttpServletRequest; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Pointcut; import org.springframework.stereotype.Component; import org.springframework.util.StringUtils; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import io.micrometer.core.instrument.Metrics; @Aspect @Component public class PrometheusMetricsAspect { // 切入所有controller包下的请求方法 @Pointcut("execution(* com.olive.controller..*.*(..))") public void controllerPointcut() { } @Around("controllerPointcut()") public Object MetricsCollector(ProceedingJoinPoint joinPoint) throws Throwable { HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); String userId = StringUtils.hasText(request.getParameter("userId")) ? request.getParameter("userId") : "no userId"; // 获取api url String api = request.getServletPath(); // 获取请求方法 String method = request.getMethod(); long startTs = System.currentTimeMillis(); LocalDate now = LocalDate.now(); String[] tags = new String[10]; tags[0] = "api"; tags[1] = api; tags[2] = "method"; tags[3] = method; tags[4] = "day"; tags[5] = now.toString(); tags[6] = "userId"; tags[7] = userId; String amount = StringUtils.hasText(request.getParameter("amount")) ? request.getParameter("amount") : "0.0"; tags[8] = "amount"; tags[9] = amount; // 请求次数加1 //自定义的指标名称:custom_http_request_all,指标包含数据 Metrics.counter("custom_http_request_all", tags).increment(); Object object = null; try { object = joinPoint.proceed(); } catch (Exception e) { //请求失败次数加1 Metrics.counter("custom_http_request_error", tags).increment(); throw e; } finally { long endTs = System.currentTimeMillis() - startTs; //记录请求响应时间 Metrics.timer("custom_http_request_time", tags).record(endTs, TimeUnit.MILLISECONDS); } return object; } }방법 2프로메테우스를 결합하여 마이크로미터를 캡슐화하는
micrometer-registry-prometheus
패키지를 도입함으로써rrreee또한 두 개의 측정항목을 정의합니다
rrreee🎜prometheus 4 일반적으로 사용되는 측정항목🎜 🎜Counter🎜 🎜계속 증가하지만 감소하지 않는 카운터입니다. 웹 사이트 방문자 수, 시스템 실행 시간 등 증가만 하고 감소하지 않는 유형을 기록하는 데 사용할 수 있습니다. 🎜🎜카운터 유형 지표의 경우 카운터 + 1에 사용되는 inc() 메서드는 하나만 있습니다. 🎜🎜 일반적으로 카운터 유형 지표 지표는 http_requests_total과 같이 _total로 끝납니다.🎜🎜 게이지🎜🎜할 수 있는 대시보드 증가 또는 감소할 수 있으며, 증가 또는 감소할 수 있는 지표에 대한 그래프🎜🎜를 사용하여 애플리케이션의 현재 상태를 반영합니다. 🎜🎜예를 들어 호스트를 모니터링할 때 호스트의 현재 사용 가능한 메모리 크기, 사용 가능한 메모리 크기 등이 표시됩니다. 🎜🎜게이지 표시기 개체에는 개수를 늘리거나 줄이는 데 사용되는 두 가지 주요 메서드 inc() 및 dec()가 포함되어 있습니다. 🎜🎜Histogram🎜🎜은 주로 데이터 분포를 계산하는 데 사용됩니다. 이는 대략적인 백분율 추정 값을 나타내고 모든 개별 지표 데이터가 각 값 범위에 속하는 횟수를 계산하는 특수 측정항목 데이터 유형입니다. 예: 일정 기간 내에서 0.005초 미만, 0.01초 미만, 0.025초 미만의 http 요청 응답의 데이터 분포를 계산하려고 합니다. 그런 다음 히스토그램을 사용하여 각 http 요청의 시간을 수집하고 동시에 버킷을 설정합니다. 🎜🎜Summary🎜🎜Summary와 Histogram은 둘 다 이벤트의 수나 크기는 물론 분포도 계산할 수 있으며, 둘 다 계산할 수 있는 통계도 제공합니다. 차이점은 히스토그램이 histogram_Quantile 함수를 통해 서버에서 분위수를 계산할 수 있다는 것입니다. Sumamry의 분위수는 클라이언트에서 직접 정의됩니다. 따라서 분위수 계산의 경우 PromQL을 통해 쿼리할 때 Summary가 더 나은 성능을 보이는 반면, Histogram은 더 많은 리소스를 소비하지만 Histogram은 클라이언트에 비해 더 적은 리소스를 소비합니다. 어떤 것을 사용하든 실제 장면에 따라 자유롭게 조정할 수 있습니다. 🎜🎜3. 테스트🎜🎜NativeMetricsMontior
및 PrometheusMetricsMonitor
를 사용하여 두 개의 컨트롤러 정의🎜rrreee🎜서비스 시작🎜🎜http://127.0.0.1:9595를 방문하세요. Actuator/prometheus
;모니터링 데이터 정상적으로 보기🎜🎜🎜🎜금액을 http://127.0.0.1:8080/order?amount=100
및 http://127.0.0.1:8080 /으로 여러 번 변경하세요. pay?amount=10
; 그런 다음 http://127.0.0.1:9595/actuator/prometheus
를 방문하세요. 모니터링 데이터 보기🎜🎜🎜🎜 4. 프로젝트 내 적용🎜🎜스프링 프로젝트에서는 위에서 언급한 방식으로 데이터 매장지 모니터링을 하는 것이 현실적이지 않으며, 기본적으로 AOP를 통해 매장지 모니터링을 진행하고 있습니다. 예를 들어 Aspect
측면을 작성해 보세요. 이 방법은 매우 친숙합니다. 컨트롤러에 코드를 작성할 필요 없이 입구에서 데이터 매립지 모니터링이 가능합니다. 🎜rrreee🎜애스펙트를 작성한 후 서비스를 다시 시작하고 컨트롤러 인터페이스에 액세스하면 사용자 정의 모니터링 표시기를 저장할 수도 있습니다🎜🎜🎜🎜위 내용은 Spring Boot에서 모니터링 표시기를 사용자 정의하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!