欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Spring?Boot自定義監(jiān)控指標(biāo)的詳細(xì)過程

 更新時(shí)間:2023年03月04日 08:36:32   作者:BUG弄潮兒  
這篇文章主要介紹了Spring?Boot如何自定義監(jiān)控指標(biāo)?,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下

1.創(chuàng)建項(xiàng)目

pom.xml引入相關(guān)依賴

<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>

2.自定義指標(biāo)

方式一

直接使用micrometer核心包的類進(jìn)行指標(biāo)定義和注冊(cè)

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 {
 
	/**
	 * 支付次數(shù)
	 */
	private Counter payCount;
 
	/**
	 * 支付金額統(tǒng)計(jì)
	 */
	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包,該包結(jié)合prometheus,對(duì)micrometer進(jìn)行了封裝

<dependency>
			<groupId>io.micrometer</groupId>
			<artifactId>micrometer-registry-prometheus</artifactId>
		</dependency>

同樣定義兩個(gè)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 {
 
	/**
	 * 訂單發(fā)起次數(shù)
	 */
	private Counter orderCount;
 
	/**
	 * 金額統(tǒng)計(jì)
	 */
	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

連續(xù)增加不會(huì)減少的計(jì)數(shù)器,可以用于記錄只增不減的類型,例如:網(wǎng)站訪問人數(shù),系統(tǒng)運(yùn)行時(shí)間等。

對(duì)于Counter類型的指標(biāo),只包含一個(gè)inc()的方法,就是用于計(jì)數(shù)器+1.

一般而言,Counter類型的metric指標(biāo)在冥冥中我們使用_total結(jié)束,如http_requests_total.

Gauge

可增可減的儀表盤,曲線圖

對(duì)于這類可增可減的指標(biāo),用于反應(yīng)應(yīng)用的當(dāng)前狀態(tài)。

例如在監(jiān)控主機(jī)時(shí),主機(jī)當(dāng)前空閑的內(nèi)存大小,可用內(nèi)存大小等等。

對(duì)于Gauge指標(biāo)的對(duì)象則包含兩個(gè)主要的方法inc()和dec(),用于增加和減少計(jì)數(shù)。

Histogram

主要用來統(tǒng)計(jì)數(shù)據(jù)的分布情況,這是一種特殊的metrics數(shù)據(jù)類型,代表的是一種近似的百分比估算數(shù)值,統(tǒng)計(jì)所有離散的指標(biāo)數(shù)據(jù)在各個(gè)取值區(qū)段內(nèi)的次數(shù)。例如:我們想統(tǒng)計(jì)一段時(shí)間內(nèi)http請(qǐng)求響應(yīng)小于0.005秒、小于0.01秒、小于0.025秒的數(shù)據(jù)分布情況。那么使用Histogram采集每一次http請(qǐng)求的時(shí)間,同時(shí)設(shè)置bucket。

Summary

Summary和Histogram非常相似,都可以統(tǒng)計(jì)事件發(fā)生的次數(shù)或者大小,以及其分布情況,他們都提供了對(duì)時(shí)間的計(jì)數(shù)_count以及值的匯總_sum,也都提供了可以計(jì)算統(tǒng)計(jì)樣本分布情況的功能,不同之處在于Histogram可以通過histogram_quantile函數(shù)在服務(wù)器計(jì)算分位數(shù)。而Sumamry的分位數(shù)則是直接在客戶端進(jìn)行定義的。因此對(duì)于分位數(shù)的計(jì)算,Summary在通過PromQL進(jìn)行查詢的時(shí)候有更好的性能表現(xiàn),而Histogram則會(huì)消耗更多的資源,但是相對(duì)于客戶端而言Histogram消耗的資源就更少。用哪個(gè)都行,根據(jù)實(shí)際場(chǎng)景自由調(diào)整即可。

3. 測(cè)試

定義兩個(gè)controller分別使用NativeMetricsMontiorPrometheusMetricsMonitor

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 {
		// 統(tǒng)計(jì)支付次數(shù)
		monitor.getPayCount().increment();
 
		Random random = new Random();
		//int amount = random.nextInt(100);
		if(amount==null) {
			amount = 0.0;
		}
		// 統(tǒng)計(jì)支付總金額
		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 {
		// 訂單總數(shù)
		monitor.getOrderCount()
			.labels("orderCount")
			.inc();
 
		Random random = new Random();
		//int amount = random.nextInt(100);
		if(amount==null) {
			amount = 0.0;
		}
		// 統(tǒng)計(jì)訂單總金額
		monitor.getOrderAmountSum()
			.labels("orderAmountSum")
			.inc(amount);
		return "下單成功, 訂單金額: " + amount;
	}
 
}

啟動(dòng)服務(wù)

訪問http://127.0.0.1:9595/actuator/prometheus;正??吹奖O(jiān)測(cè)數(shù)據(jù)

改變amount多次方式http://127.0.0.1:8080/order?amount=100http://127.0.0.1:8080/pay?amount=10后;再訪問http://127.0.0.1:9595/actuator/prometheus。查看監(jiān)控?cái)?shù)據(jù)

4.項(xiàng)目中的應(yīng)用

項(xiàng)目中按照上面說的方式進(jìn)行數(shù)據(jù)埋點(diǎn)監(jiān)控不太現(xiàn)實(shí);在spring項(xiàng)目中基本通過AOP進(jìn)行埋點(diǎn)監(jiān)測(cè)。比如寫一個(gè)切面Aspect;這樣的方式就非常友好。能在入口就做了數(shù)據(jù)埋點(diǎn)監(jiān)測(cè),無須在controller里進(jìn)行代碼編寫。

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包下的請(qǐng)求方法
    @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();
        // 獲取請(qǐng)求方法
        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;
        // 請(qǐng)求次數(shù)加1
        //自定義的指標(biāo)名稱:custom_http_request_all,指標(biāo)包含數(shù)據(jù)
        Metrics.counter("custom_http_request_all", tags).increment();
        Object object = null;
        try {
            object = joinPoint.proceed();
        } catch (Exception e) {
            //請(qǐng)求失敗次數(shù)加1
            Metrics.counter("custom_http_request_error", tags).increment();
            throw e;
        } finally {
            long endTs = System.currentTimeMillis() - startTs;
            //記錄請(qǐng)求響應(yīng)時(shí)間
           Metrics.timer("custom_http_request_time", tags).record(endTs, TimeUnit.MILLISECONDS);
        }
        return object;
    }
}

編寫好切面后,重啟服務(wù);訪問controller的接口,同樣可以進(jìn)行自定義監(jiān)控指標(biāo)埋點(diǎn)

到此這篇關(guān)于Spring Boot如何自定義監(jiān)控指標(biāo)的文章就介紹到這了,更多相關(guān)Spring Boot自定義監(jiān)控指標(biāo)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • java虛擬機(jī)學(xué)習(xí)高級(jí)篇

    java虛擬機(jī)學(xué)習(xí)高級(jí)篇

    在本篇文章里小編給大家整理了關(guān)于java虛擬機(jī)學(xué)習(xí)高級(jí)篇的相關(guān)內(nèi)容,有興趣的朋友們跟著學(xué)習(xí)參考下。
    2019-06-06
  • 詳解Spring中Spel表達(dá)式和el表達(dá)式的區(qū)別

    詳解Spring中Spel表達(dá)式和el表達(dá)式的區(qū)別

    在?Java?開發(fā)中,表達(dá)式語言是一種強(qiáng)大的工具,而SpEL?表達(dá)式與EL?表達(dá)式是我們常常遇到兩種表達(dá)式語言,下面我們就來看看它們的具體使用與區(qū)別吧
    2023-07-07
  • springboot+mybatis通過實(shí)體類自動(dòng)生成數(shù)據(jù)庫表的方法

    springboot+mybatis通過實(shí)體類自動(dòng)生成數(shù)據(jù)庫表的方法

    這篇文章主要介紹了springboot+mybatis通過實(shí)體類自動(dòng)生成數(shù)據(jù)庫表的方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-07-07
  • Springboot下RedisTemplate的兩種序列化方式實(shí)例詳解

    Springboot下RedisTemplate的兩種序列化方式實(shí)例詳解

    這篇文章主要介紹了Springboot下RedisTemplate的兩種序列化方式,通過定義一個(gè)配置類,自定義RedisTemplate的序列化方式,結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-09-09
  • Intellij idea遠(yuǎn)程debug連接tomcat實(shí)現(xiàn)單步調(diào)試

    Intellij idea遠(yuǎn)程debug連接tomcat實(shí)現(xiàn)單步調(diào)試

    這篇文章主要介紹了Intellij idea遠(yuǎn)程debug連接tomcat實(shí)現(xiàn)單步調(diào)試,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-05-05
  • Java中HttpServletRequestWrapper的使用與原理詳解

    Java中HttpServletRequestWrapper的使用與原理詳解

    這篇文章主要介紹了Java中HttpServletRequestWrapper的使用與原理詳解,HttpServletRequestWrapper 實(shí)現(xiàn)了 HttpServletRequest 接口,可以讓開發(fā)人員很方便的改造發(fā)送給 Servlet 的請(qǐng)求,需要的朋友可以參考下
    2024-01-01
  • Java的Hibernate框架中的組合映射學(xué)習(xí)教程

    Java的Hibernate框架中的組合映射學(xué)習(xí)教程

    組合映射即是指主對(duì)象和子對(duì)象關(guān)聯(lián)且擁有相同的生命周期的映射關(guān)系,這里我們將舉一些數(shù)據(jù)操作的實(shí)例,來講解Java的Hibernate框架中的組合映射學(xué)習(xí)教程
    2016-07-07
  • Springboot配置@Async無效的解決方案

    Springboot配置@Async無效的解決方案

    這篇文章主要介紹了Springboot配置@Async無效的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-09-09
  • Java實(shí)現(xiàn)AOP面向切面編程的實(shí)例教程

    Java實(shí)現(xiàn)AOP面向切面編程的實(shí)例教程

    這篇文章主要介紹了Java實(shí)現(xiàn)AOP面向切面編程的實(shí)例教程,通常Java中的AOP都是利用Spring框架中造好的輪子來開發(fā),而本文則關(guān)注于Java本身AOP的設(shè)計(jì)模式實(shí)現(xiàn),需要的朋友可以參考下
    2016-04-04
  • java二維數(shù)組基礎(chǔ)知識(shí)詳解

    java二維數(shù)組基礎(chǔ)知識(shí)詳解

    這篇文章主要介紹了java二維數(shù)組基礎(chǔ)知識(shí)詳解的相關(guān)資料,需要的朋友可以參考下
    2023-02-02

最新評(píng)論