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

spring-boot整合Micrometer+Prometheus的詳細過程

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

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

使用案例

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

Timer

打點記錄任務(wù)的每次執(zhí)行時間。兜底默認的時間窗口是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í)行時間,官方注釋中也說了LongTask是一個主觀判斷,比如:1分鐘以上的任務(wù)
一個比較大區(qū)別在于多了一個接口方法:io.micrometer.core.instrument.LongTaskTimer#activeTasks
獲取當(dāng)前正在執(zhí)行中的任務(wù)數(shù)量???????

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

Gague

在服務(wù)器拉取指標時,或者客戶端上報指標時,調(diào)用提供的對象與方法獲取當(dāng)前指標。即:記錄的是當(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

計數(shù)器打點

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

DistributionSummary

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

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

配置actuator

配置指標拉取端口,以及需要曝光的web接口???????

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

Springboot整合啟動流程

拉取指標:http://localhost:9999/actuator/prometheus

servlet配置

接口自動配置有很多入口,例如下面兩個

  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迭代器一次,并收集一次指標

  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匿名實現(xiàn):io.micrometer.prometheus.PrometheusMeterRegistry#newGauge
  4. 將遍歷的child中所有樣本,按照conventionName(例如:ringbuffer_remaining)分組,每個組對應(yīng)一個樣本家庭: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,所有的指標都會帶有該tag:application=myAppName
指標名稱:ringbuffer_remaining
指標tag:type=my_tag_1
指標類型: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實例的弱引用
  2. value:對應(yīng)RingBuffer::remainingCapacity方法

取樣邏輯即直接調(diào)用實例響應(yīng)方法返回的結(jié)果作為打點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,遞增計數(shù)器
  2. totalTime:LongAdder,任務(wù)耗時累加結(jié)果
  3. max:io.micrometer.core.instrument.distribution.TimeWindowMax,簡化版的ringbuffer,用于記錄時間窗口中的最大值
  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)控的方法實際調(diào)用時就會觸發(fā)打點記錄。取樣邏輯只是在接口拉取數(shù)據(jù)時調(diào)用實例實現(xiàn)的接口方法拍一個樣本快照

  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);
    }

時間窗口

io.micrometer.core.instrument.distribution.TimeWindowMax

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

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

  1. wallTime=系統(tǒng)當(dāng)前時間
  2. timeSinceLastRotateMillis = wallTime - lastRotateTimestampMillis,即:當(dāng)前時間距離上次翻轉(zhuǎn)的時間間隔
  3. 如果低于步進,直接返回不需要翻轉(zhuǎn):timeSinceLastRotateMillis < durationBetweenRotatesMillis
  4. 否則更新標志符,表示當(dāng)前正在翻轉(zhuǎn),需要阻塞等待下
  5. 如果timeSinceLastRotateMillis已經(jīng)超出整個隊列的長度了:timeSinceLastRotateMillis >= durationBetweenRotatesMillis * ringBuffer.length
    1. 那么直接重置隊列返回即可
    2. 遍歷ringBuffer所有位置設(shè)置為0
    3. currentBucket更新為0
    4. 更新上次翻轉(zhuǎn)時間:lastRotateTimestampMillis = wallTime - timeSinceLastRotateMillis % durationBetweenRotatesMillis
  6. 否則,將當(dāng)前時間與上次翻轉(zhuǎn)時間之間已經(jīng)超時的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)前時間為4,上次翻轉(zhuǎn)時間為2,隊列大小為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>=隊列長度
    2. 重置currentBucket=0
  3. 更新timeSinceLastRotateMillis=1-1
  4. 更新lastRotateTimestampMillis=3+1
  5. 更新iterations=2,此時timeSinceLastRotateMillis=0,小于durationBetweenRotatesMillis,結(jié)束循環(huán)

一次旋轉(zhuǎn)圖例

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

總結(jié)

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

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

actuator就像是啟動器,會將對接具體時序數(shù)據(jù)庫所需要的配置自動化,例如指標矩陣相關(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等報表工具對接打點數(shù)據(jù)源展示圖表。常見的架構(gòu)有:Micrometer-》Prometheus-〉Grafana
注意:前端頁面渲染存在瓶頸,例如一個指標的tag如果太多會導(dǎo)致報表非常的卡頓,一般5k個tag就會有感知,1W+會明顯影響使用

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

相關(guān)文章

  • Java如何生成壓縮文件工具類

    Java如何生成壓縮文件工具類

    這篇文章主要介紹了Java如何生成壓縮文件工具類問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-06-06
  • Spring?Cloud?Alibaba使用Nacos作為注冊中心和配置中心

    Spring?Cloud?Alibaba使用Nacos作為注冊中心和配置中心

    這篇文章主要為大家介紹了Spring?Cloud?Alibaba使用Nacos作為注冊中心和配置中心的示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-06-06
  • 詳解JAVA 弱引用

    詳解JAVA 弱引用

    這篇文章主要介紹了 JAVA 弱引用的相關(guān)資料,幫助大家更好的理解和學(xué)習(xí)java引用對象,感興趣的朋友可以了解下
    2020-08-08
  • SpringBoot連接PostgreSQL+MybatisPlus入門案例(代碼詳解)

    SpringBoot連接PostgreSQL+MybatisPlus入門案例(代碼詳解)

    這篇文章主要介紹了SpringBoot連接PostgreSQL+MybatisPlus入門案例,本文通過實例代碼圖文相結(jié)合給大家介紹的非常詳細,感興趣的朋友跟隨小編一起看看吧
    2024-07-07
  • Spring Boot Admin(監(jiān)控工具)的使用

    Spring Boot Admin(監(jiān)控工具)的使用

    今天我們將會講解一個優(yōu)秀的監(jiān)控工具Spring Boot Admin。 它采用圖形化的界面,讓我們的Spring Boot管理更加簡單,需要的朋友可以參考下
    2020-02-02
  • Java滾動數(shù)組計算編輯距離操作示例

    Java滾動數(shù)組計算編輯距離操作示例

    這篇文章主要介紹了Java滾動數(shù)組計算編輯距離操作,涉及java字符串與數(shù)組的遍歷、計算、轉(zhuǎn)換等相關(guān)操作技巧,需要的朋友可以參考下
    2019-12-12
  • Spring中IoC優(yōu)點與缺點解析

    Spring中IoC優(yōu)點與缺點解析

    這篇文章主要為大家詳細解析了Spring中IoC優(yōu)點與缺點,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-11-11
  • Java文件(io)編程之文件字符流使用方法詳解

    Java文件(io)編程之文件字符流使用方法詳解

    這篇文章主要為大家詳細介紹了Java文件(io)編程之文件字符流使用方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-08-08
  • 使用IDEA直接連接MySQL數(shù)據(jù)庫的方法

    使用IDEA直接連接MySQL數(shù)據(jù)庫的方法

    這篇文章主要介紹了如何使用IDEA直接連接MySQL數(shù)據(jù)庫,首先需要新建一個空項目,第一次連接 需要先下載驅(qū)動,文中給大家介紹的非常詳細,感興趣的朋友跟隨小編一起看看吧
    2024-04-04
  • JMeter自定義日志與日志分析的實現(xiàn)

    JMeter自定義日志與日志分析的實現(xiàn)

    JMeter與Java程序一樣,會記錄事件日志,本文就介紹一下JMeter自定義日志與日志分析的實現(xiàn),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-12-12

最新評論