最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

spring-boot整合Micrometer+Prometheus的詳細(xì)過程

 更新時(shí)間:2024年05月23日 15:24:12   作者:太陽傘下的阿呆  
這篇文章主要介紹了springboot整合Micrometer+Prometheus的詳細(xì)過程,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧

環(huán)境:
micrometer 1.8.2
prometheus 0.14.1
spring-boot-actuator 2.6.6

使用案例

<!-- Springboot啟動(dòng)actuator,默認(rèn)會引入依賴:micrometer-core -->
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-actuator</artifactId>
  <version>2.6.6</version>
</dependency>
<!-- micrometer橋接prometheus包,默認(rèn)會引入相關(guān)依賴:io.prometheus:simpleclient -->
<dependency>
  <groupId>io.micrometer</groupId>
  <artifactId>micrometer-registry-prometheus</artifactId>
  <version>1.8.2</version>
</dependency>

Timer

打點(diǎn)記錄任務(wù)的每次執(zhí)行時(shí)間。兜底默認(rèn)的時(shí)間窗口是1分鐘。如果想要修改可以配置:io.micrometer.core.instrument.distribution.DistributionStatisticConfig.Builder#expiry

Metrics.timer("my_name", "my_tag_1", "my_tag_2").record(() -> {
    doMyJob();
});

LongTaskTimer

與Timer類似,記錄任務(wù)執(zhí)行時(shí)間,官方注釋中也說了LongTask是一個(gè)主觀判斷,比如:1分鐘以上的任務(wù)
一個(gè)比較大區(qū)別在于多了一個(gè)接口方法:io.micrometer.core.instrument.LongTaskTimer#activeTasks
獲取當(dāng)前正在執(zhí)行中的任務(wù)數(shù)量???????

Metrics.more().longTaskTimer("my_name", "my_tag").record(doMyJob());

Gague

在服務(wù)器拉取指標(biāo)時(shí),或者客戶端上報(bào)指標(biāo)時(shí),調(diào)用提供的對象與方法獲取當(dāng)前指標(biāo)。即:記錄的是當(dāng)前狀態(tài)

RingBuffer<MatchingOutput> rb = disruptor.getRingBuffer();
Metrics.gauge("ringbuffer_remaining", Tags.of("my_tag_1", "my_tag_2"), rb, RingBuffer::remainingCapacity);

Counter

計(jì)數(shù)器打點(diǎn)

Metrics.counter("my_request", "my_tag_1", "my_tag_2").increment();

DistributionSummary

跟蹤事件的樣本分布。 一個(gè)例子是訪問 http 服務(wù)器的請求的響應(yīng)大小。???????

DistributionSummary ds =  DistributionSummary.builder("my.data.size")
    .tag("type", "my_type_1")
    .publishPercentileHistogram()
    .register(Metrics.globalRegistry);
ds.record(myValue);

配置actuator

配置指標(biāo)拉取端口,以及需要曝光的web接口???????

management:
  server:
    port: 9999
  endpoints:
    web:
      exposure:
        include: '*'
  metrics:
    tags:
      application: myAppName

Springboot整合啟動(dòng)流程

拉取指標(biāo):http://localhost:9999/actuator/prometheus

servlet配置

接口自動(dòng)配置有很多入口,例如下面兩個(gè)

  1. 普通web服務(wù):org.springframework.boot.actuate.autoconfigure.endpoint.web.servlet.WebMvcEndpointManagementContextConfiguration#webEndpointServletHandlerMapping
  2. 云服務(wù)商:org.springframework.boot.actuate.autoconfigure.cloudfoundry.servlet.CloudFoundryActuatorAutoConfiguration#cloudFoundryWebEndpointServletHandlerMapping

servlet邏輯

org.springframework.boot.actuate.metrics.export.prometheus.PrometheusScrapeEndpoint

@ReadOperation(producesFrom = TextOutputFormat.class)
public WebEndpointResponse<String> scrape(TextOutputFormat format, @Nullable Set<String> includedNames) {
    try {
        Writer writer = new StringWriter(this.nextMetricsScrapeSize);
        Enumeration<MetricFamilySamples> samples = (includedNames != null)
        ? this.collectorRegistry.filteredMetricFamilySamples(includedNames)
        : this.collectorRegistry.metricFamilySamples();
        format.write(writer, samples);
        String scrapePage = writer.toString();
        this.nextMetricsScrapeSize = scrapePage.length() + METRICS_SCRAPE_CHARS_EXTRA;
        return new WebEndpointResponse<>(scrapePage, format);
    }
    catch (IOException ex) {
        // This actually never happens since StringWriter doesn't throw an IOException
        throw new IllegalStateException("Writing metrics failed", ex);
    }
}

沒有配置過濾器,獲取枚舉對象
io.prometheus.client.CollectorRegistry#metricFamilySamples -》 io.prometheus.client.CollectorRegistry.MetricFamilySamplesEnumeration#MetricFamilySamplesEnumeration()

io.prometheus.client.CollectorRegistry.MetricFamilySamplesEnumeration

  1. sampleNameFilter
  2. collectorIter:對應(yīng)io.prometheus.client.CollectorRegistry#namesToCollectors屬性的value集合
  3. 構(gòu)造器中查詢一次next:findNextElement

findNextElement

遍歷collectorIter迭代器一次,并收集一次指標(biāo)

  1. io.prometheus.client.Collector#collect(io.prometheus.client.Predicate<java.lang.String>)
  2. io.micrometer.prometheus.MicrometerCollector#collect
  3. 遍歷io.micrometer.prometheus.MicrometerCollector#children集合中所有io.micrometer.prometheus.MicrometerCollector.Child對象
    1. 例如Gauge類型中的lambda匿名實(shí)現(xiàn):io.micrometer.prometheus.PrometheusMeterRegistry#newGauge
  4. 將遍歷的child中所有樣本,按照conventionName(例如:ringbuffer_remaining)分組,每個(gè)組對應(yīng)一個(gè)樣本家庭:io.prometheus.client.Collector.MetricFamilySamples
  5. 返回List,將其迭代器賦給next屬性:io.prometheus.client.CollectorRegistry.MetricFamilySamplesEnumeration#next
  6. 遍歷samples:io.prometheus.client.Collector.MetricFamilySamples#samples
  7. 將sample(io.prometheus.client.Collector.MetricFamilySamples.Sample)數(shù)據(jù)寫入response響應(yīng)結(jié)果:org.springframework.boot.actuate.metrics.export.prometheus.TextOutputFormat#CONTENT_TYPE_004#write

接口輸出案例

公共配置的tag,所有的指標(biāo)都會帶有該tag:application=myAppName
指標(biāo)名稱:ringbuffer_remaining
指標(biāo)tag:type=my_tag_1
指標(biāo)類型:gauge

# HELP ringbuffer_remaining  
# TYPE ringbuffer_remaining gauge
ringbuffer_remaining{application="myAppName",type="my_tag_1",} 1024.0

采樣取數(shù)邏輯

Gauge

結(jié)合前面Gague使用案例的代碼
io.micrometer.core.instrument.internal.DefaultGauge

  1. ref:對應(yīng)ringbuffer實(shí)例的弱引用
  2. value:對應(yīng)RingBuffer::remainingCapacity方法

取樣邏輯即直接調(diào)用實(shí)例響應(yīng)方法返回的結(jié)果作為打點(diǎn)value

public class DefaultGauge<T> extends AbstractMeter implements Gauge {
    ...
    private final WeakReference<T> ref;
    private final ToDoubleFunction<T> value;
    ...
    @Override
    public double value() {
        T obj = ref.get();
        if (obj != null) {
            try {
                return value.applyAsDouble(obj);
            }
            catch (Throwable ex) {
                logger.log("Failed to apply the value function for the gauge '" + getId().getName() + "'.", ex);
            }
        }
        return Double.NaN;
    }
    ...
}

Timer

io.micrometer.prometheus.PrometheusTimer

  1. count:LongAdder,遞增計(jì)數(shù)器
  2. totalTime:LongAdder,任務(wù)耗時(shí)累加結(jié)果
  3. max:io.micrometer.core.instrument.distribution.TimeWindowMax,簡化版的ringbuffer,用于記錄時(shí)間窗口中的最大值
  4. histogramFlavor:直方圖風(fēng)味(類型),當(dāng)前版本只有兩種:Prometheus/VictoriaMetrics
  5. histogram
    1. Prometheus類型:io.micrometer.core.instrument.distribution.TimeWindowFixedBoundaryHistogram#TimeWindowFixedBoundaryHistogram
    2. VictoriaMetrics類型:io.micrometer.core.instrument.distribution.FixedBoundaryVictoriaMetricsHistogram#FixedBoundaryVictoriaMetricsHistogram

取樣邏輯即監(jiān)控的方法實(shí)際調(diào)用時(shí)就會觸發(fā)打點(diǎn)記錄。取樣邏輯只是在接口拉取數(shù)據(jù)時(shí)調(diào)用實(shí)例實(shí)現(xiàn)的接口方法拍一個(gè)樣本快照

  1. io.micrometer.core.instrument.distribution.HistogramSupport#takeSnapshot()
  2. io.micrometer.prometheus.PrometheusTimer#takeSnapshot
  3. io.micrometer.core.instrument.AbstractTimer#takeSnapshot
  4. 如果histogram != null則追加histogramCounts數(shù)據(jù)
--io.micrometer.core.instrument.AbstractTimer#takeSnapshot
    @Override
    public HistogramSnapshot takeSnapshot() {
        return histogram.takeSnapshot(count(), totalTime(TimeUnit.NANOSECONDS), max(TimeUnit.NANOSECONDS));
    }
--io.micrometer.prometheus.PrometheusTimer#takeSnapshot
    @Override
    public HistogramSnapshot takeSnapshot() {
        HistogramSnapshot snapshot = super.takeSnapshot();
        if (histogram == null) {
            return snapshot;
        }
        return new HistogramSnapshot(snapshot.count(),
                snapshot.total(),
                snapshot.max(),
                snapshot.percentileValues(),
                histogramCounts(),
                snapshot::outputSummary);
    }

時(shí)間窗口

io.micrometer.core.instrument.distribution.TimeWindowMax

  1. rotatingUpdater:AtomicIntegerFieldUpdater,rotating標(biāo)志符原子更新方法
  2. clock:Clock,系統(tǒng)時(shí)鐘,返回當(dāng)前系統(tǒng)時(shí)間戳
  3. durationBetweenRotatesMills:long,滾動(dòng)步進(jìn)大小
  4. ringBuffer:AtomicLong[],隊(duì)列
  5. currentBucket:int,隊(duì)列當(dāng)前游標(biāo)
  6. lastRotateTimestampMills:上一次rotate的時(shí)間戳
  7. rotating:int,標(biāo)志符,0 - not rotating, 1 - rotating

每次寫入record,或者查詢poll,都會提前校驗(yàn)下是否需要翻轉(zhuǎn),調(diào)用rotate方法
io.micrometer.core.instrument.distribution.TimeWindowMax#rotate

  1. wallTime=系統(tǒng)當(dāng)前時(shí)間
  2. timeSinceLastRotateMillis = wallTime - lastRotateTimestampMillis,即:當(dāng)前時(shí)間距離上次翻轉(zhuǎn)的時(shí)間間隔
  3. 如果低于步進(jìn),直接返回不需要翻轉(zhuǎn):timeSinceLastRotateMillis < durationBetweenRotatesMillis
  4. 否則更新標(biāo)志符,表示當(dāng)前正在翻轉(zhuǎn),需要阻塞等待下
  5. 如果timeSinceLastRotateMillis已經(jīng)超出整個(gè)隊(duì)列的長度了:timeSinceLastRotateMillis >= durationBetweenRotatesMillis * ringBuffer.length
    1. 那么直接重置隊(duì)列返回即可
    2. 遍歷ringBuffer所有位置設(shè)置為0
    3. currentBucket更新為0
    4. 更新上次翻轉(zhuǎn)時(shí)間:lastRotateTimestampMillis = wallTime - timeSinceLastRotateMillis % durationBetweenRotatesMillis
  6. 否則,將當(dāng)前時(shí)間與上次翻轉(zhuǎn)時(shí)間之間已經(jīng)超時(shí)的bucket重置為0
int iterations = 0;
do {
    ringBuffer[currentBucket].set(0);
    if (++currentBucket >= ringBuffer.length) {
        currentBucket = 0;
    }
    timeSinceLastRotateMillis -= durationBetweenRotatesMillis;
    lastRotateTimestampMillis += durationBetweenRotatesMillis;
} while (timeSinceLastRotateMillis >= durationBetweenRotatesMillis && ++iterations < ringBuffer.length);

例如:當(dāng)前時(shí)間為4,上次翻轉(zhuǎn)時(shí)間為2,隊(duì)列大小為3,durationBetweenRotatesMillis=1,currentBucket=1,那么timeSinceLastRotateMillis=4-2=2
循環(huán)第1輪

  1. 更新ringBuffer[1]=0
  2. 更新currentBucket=2
  3. 更新timeSinceLastRotateMillis=2-1
  4. 更新lastRotateTimestampMillis=2+1
  5. 更新iterations=1

循環(huán)第2輪

  1. 更新ringBuffer[2]=0
  2. 更新currentBucket=3
    1. currentBucket>=隊(duì)列長度
    2. 重置currentBucket=0
  3. 更新timeSinceLastRotateMillis=1-1
  4. 更新lastRotateTimestampMillis=3+1
  5. 更新iterations=2,此時(shí)timeSinceLastRotateMillis=0,小于durationBetweenRotatesMillis,結(jié)束循環(huán)

一次旋轉(zhuǎn)圖例

當(dāng)發(fā)現(xiàn)上次旋轉(zhuǎn)時(shí)間(lastRotateTimestampMillis)已經(jīng)落后當(dāng)前時(shí)間(wallTime)4個(gè)單位后,lastRotateTimestampMillis向右移動(dòng)4個(gè)時(shí)間單位,currentBucket也向右移動(dòng)4個(gè)單位。但是因?yàn)閏urrentBucket是數(shù)組的index,當(dāng)越界的時(shí)候就移動(dòng)到0繼續(xù)(一個(gè)環(huán))。例如下圖:
currentBucket向右移動(dòng)4個(gè)單位,隊(duì)列長度為3,當(dāng)前index=0,那么移動(dòng)后index=2(轉(zhuǎn)了一圈)

總結(jié)

Micrometer可以整合Prometheus也可以整合influxDB等時(shí)序數(shù)據(jù)庫,主要作用就是橋接,類似于Slf4j與log4j,logback的關(guān)系。提供一個(gè)通用的打點(diǎn)能力,并將打點(diǎn)數(shù)據(jù)對接到相應(yīng)的時(shí)序數(shù)據(jù)庫,用戶只需要關(guān)心何時(shí)打點(diǎn)即可。例如:

  1. 橋接包中的io.micrometer.prometheus.PrometheusMeterRegistry,將打點(diǎn)數(shù)據(jù)橋接至io.prometheus.client.CollectorRegistry
  2. 橋接包中的io.micrometer.influx.InfluxMeterRegistry,將打點(diǎn)數(shù)據(jù)按照influx協(xié)議橋接push至influxDB。
    1. 默認(rèn)push頻率為1分鐘一次,可以按需配置:io.micrometer.core.instrument.push.PushRegistryConfig#step
    2. 線程池默認(rèn)為單線程:java.util.concurrent.Executors#newSingleThreadScheduledExecutor(java.util.concurrent.ThreadFactory)
    3. 線程池線程命名規(guī)則針對influxDB實(shí)現(xiàn):influx-metrics-publisher

actuator就像是啟動(dòng)器,會將對接具體時(shí)序數(shù)據(jù)庫所需要的配置自動(dòng)化,例如指標(biāo)矩陣相關(guān)的:Prometheus曝光web接口的相關(guān)配置,influx相關(guān)配置,micrometer metrics等等相關(guān)配置

  1. org.springframework.boot.actuate.autoconfigure.metrics.JvmMetricsAutoConfiguration
  2. org.springframework.boot.actuate.autoconfigure.metrics.KafkaMetricsAutoConfiguration
  3. org.springframework.boot.actuate.autoconfigure.metrics.Log4J2MetricsAutoConfiguration
  4. org.springframework.boot.actuate.autoconfigure.metrics.LogbackMetricsAutoConfiguration
  5. org.springframework.boot.actuate.autoconfigure.metrics.SystemMetricsAutoConfiguration

最終可以通過Grafana等報(bào)表工具對接打點(diǎn)數(shù)據(jù)源展示圖表。常見的架構(gòu)有:Micrometer-》Prometheus-〉Grafana
注意:前端頁面渲染存在瓶頸,例如一個(gè)指標(biāo)的tag如果太多會導(dǎo)致報(bào)表非常的卡頓,一般5k個(gè)tag就會有感知,1W+會明顯影響使用

到此這篇關(guān)于spring-boot整合Micrometer+Prometheus的文章就介紹到這了,更多相關(guān)spring-boot整合Micrometer+Prometheus內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 基于Struts2實(shí)現(xiàn)防止表單重復(fù)提交

    基于Struts2實(shí)現(xiàn)防止表單重復(fù)提交

    這篇文章主要介紹了基于Struts2實(shí)現(xiàn)防止表單重復(fù)提交,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-10-10
  • Java中BigDecimal類的簡單用法

    Java中BigDecimal類的簡單用法

    這篇文章主要介紹了Java中BigDecimal類的簡單用法,是Java應(yīng)用程序開發(fā)中非常實(shí)用的技巧,本文以實(shí)例形式對此進(jìn)行了簡單的分析,需要的朋友可以參考下
    2014-09-09
  • RabbitMQ工作模式中的發(fā)布確認(rèn)模式示例詳解

    RabbitMQ工作模式中的發(fā)布確認(rèn)模式示例詳解

    發(fā)布確認(rèn)模式用于確保消息已經(jīng)被正確地發(fā)送到RabbitMQ服務(wù)器,并被成功接收和持久化,本文通過實(shí)例代碼給大家介紹RabbitMQ工作模式之發(fā)布確認(rèn)模式,感興趣的朋友一起看看吧
    2025-05-05
  • SpringBoot中的@ControllerAdvice使用方法詳細(xì)解析

    SpringBoot中的@ControllerAdvice使用方法詳細(xì)解析

    這篇文章主要介紹了SpringBoot中的@ControllerAdvice使用方法詳細(xì)解析, 加了@ControllerAdvice的類為那些聲明了@ExceptionHandler、@InitBinder或@ModelAttribute注解修飾的 方法的類而提供的專業(yè)化的@Component,以供多個(gè) Controller類所共享,需要的朋友可以參考下
    2024-01-01
  • Java中break、continue、return語句的使用區(qū)別對比

    Java中break、continue、return語句的使用區(qū)別對比

    這篇文章主要介紹了Java中break、continue、return語句的使用區(qū)別對比,本文用非常清爽簡明的語言總結(jié)了這三個(gè)關(guān)鍵字的使用技巧,并用一個(gè)實(shí)例對比使用結(jié)果,需要的朋友可以參考下
    2015-06-06
  • 高效數(shù)據(jù)傳輸?shù)拿孛芪淦鱌rotobuf的使用教程

    高效數(shù)據(jù)傳輸?shù)拿孛芪淦鱌rotobuf的使用教程

    Protobuf(Protocol?Buffers)是由?Google?開發(fā)的一種輕量級、高效的數(shù)據(jù)交換格式,它被用于結(jié)構(gòu)化數(shù)據(jù)的序列化、反序列化和傳輸,本文主要介紹了它的具體使用方法,需要的可以參考一下
    2023-05-05
  • Mybatis實(shí)現(xiàn)增刪改查(CRUD)實(shí)例代碼

    Mybatis實(shí)現(xiàn)增刪改查(CRUD)實(shí)例代碼

    MyBatis 是支持普通 SQL 查詢,存儲過程和高級映射的優(yōu)秀持久層框架。通過本文給大家介紹Mybatis實(shí)現(xiàn)增刪改查(CRUD)實(shí)例代碼 ,需要的朋友參考下
    2016-05-05
  • Java代碼注釋規(guī)范詳解

    Java代碼注釋規(guī)范詳解

    代碼附有注釋對程序開發(fā)者來說非常重要,隨著技術(shù)的發(fā)展,在項(xiàng)目開發(fā)過程中,必須要求程序員寫好代碼注釋,這樣有利于代碼后續(xù)的編寫和使用。下面給大家分享java代碼注釋的規(guī)范,需要的朋友參考下
    2016-02-02
  • Java實(shí)現(xiàn)在線SQL編程最新完整版

    Java實(shí)現(xiàn)在線SQL編程最新完整版

    這篇文章主要介紹了Java實(shí)現(xiàn)在線SQL編程,在使用JDBC來進(jìn)行數(shù)據(jù)庫的操作,在使用時(shí)由于對其方法并不是全部了解,所以需要邊看源碼邊改善功能,感興趣的朋友跟隨小編一起看看吧
    2022-06-06
  • IDEA2022版本創(chuàng)建maven?web項(xiàng)目的兩種方式詳解

    IDEA2022版本創(chuàng)建maven?web項(xiàng)目的兩種方式詳解

    創(chuàng)建maven?web項(xiàng)目有兩種方式,一種是使用骨架方式,一種是不使用骨架的方式,本文結(jié)合實(shí)例代碼給大家介紹了IDEA2022版本創(chuàng)建maven?web項(xiàng)目的兩種方式,需要的朋友可以參考下
    2023-02-02

最新評論

南京市| 馆陶县| 寻乌县| 聊城市| 彭州市| 河源市| 修水县| 会同县| 定边县| 乐平市| 乌海市| 抚松县| 太保市| 黄山市| 肃南| 介休市| 尼勒克县| 赣榆县| 黄浦区| 普格县| 确山县| 南通市| 林芝县| 吴江市| 古蔺县| 涟水县| 盐边县| 哈密市| 乐山市| 鄯善县| 丹东市| 安仁县| 牟定县| 炎陵县| 丘北县| 汤原县| 龙海市| 义马市| 中宁县| 水富县| 永宁县|