<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          從 Prometheus 到 OpenTelemetry: 指標監(jiān)控的演進與實踐

          共 12906字,需瀏覽 26分鐘

           ·

          2024-06-14 08:08

          在上一篇:從 Dapper 到 OpenTelemetry:分布式追蹤的演進之旅我們講解了 Trace 的一些核心概念:

          • Trace
          • Span
          • Context
          • Baggage 等

          這次我們來講另一個話題 Metrics。

          背景

          關(guān)于 metrics 我最早接觸相關(guān)概念的就是 prometheus,它是第二個加入 CNCF(云原生)社區(qū)的項目(第一個是 kubernetes),可見在云原生領(lǐng)域 Metrics 指標監(jiān)控從誕生之初就是一個非常重要的組件。

          現(xiàn)實也確實如此,如今只要使用到了 kubernetes 相關(guān)的項目,對其監(jiān)控就是必不可少的。

          當(dāng)然也不止是云原生的項目才需要 Metrics 指標監(jiān)控,我們?nèi)魏我粋€業(yè)務(wù)都是需要的,不然我們的服務(wù)運行對開發(fā)運維來說都是一個黑盒,無法知道此時系統(tǒng)的運行情況,因此才需要我們的業(yè)務(wù)系統(tǒng)將一些關(guān)鍵運行指標暴露出來。

          業(yè)務(wù)數(shù)據(jù):比如訂單的增長率、銷售金額等業(yè)務(wù)數(shù)據(jù);同時還有應(yīng)用自身的資源占用情況:

          • QPS
          • Latency
          • 內(nèi)存
          • CPU 等信息。

          在使用 OpenTelemetry 之前,因為 prometheus 是這部分的絕對標準,所以我們通常都會使用 prometheus 的包來暴露這些指標:

          <!-- The client -->
          <dependency>
            <groupId>io.prometheus</groupId>
            <artifactId>simpleclient</artifactId>
            <version>0.16.0</version>
          </dependency>
          <!-- Hotspot JVM metrics-->
          <dependency>
            <groupId>io.prometheus</groupId>
            <artifactId>simpleclient_hotspot</artifactId>
            <version>0.16.0</version>
          </dependency>

          暴露一個自定義的指標也很簡單:

          import io.prometheus.client.Counter;
          class YourClass {
            static final Counter requests = Counter.build()
               .name("requests_total").help("Total requests.").register();

            void processRequest() {
              requests.inc();
              // Your code here.
            }
          }

          這是暴露一個單調(diào)遞增的指標,prometheus 還提供了其他幾種指標類型:

          • Counter
          • Gauge
          • Histogram

          之后我們只需要在 prometheus 中配置一些抓取規(guī)則即可:

          scrape_configs:
            - job_name: 'springboot'
              scrape_interval: 10s
              static_configs:
                - targets: ['localhost:8080'] # Spring Boot ip+port

          當(dāng)然如果是運行在 kubernetes 環(huán)境,prometheus 也可以基于服務(wù)發(fā)現(xiàn)配置一些規(guī)則,自動抓取我們的 Pod 的數(shù)據(jù),由于不是本文的重點就不過多介紹。

          基本組件

          在 OpenTelemetry 中自然也提供了 Metrics 這個組件,同時它也是完全兼容 Prometheus,所以我們理解和使用起來并不復(fù)雜。

          MeterProvider

          不同于 prometheus 客戶端中直接提供了 Counter 就可以創(chuàng)建指標了,在 OpenTelemetry 中會提供一個 MeterProvider 的接口,使用這個接口可以獲取 Meter,再使用 Meter 才可以創(chuàng)建 Counter、Gauge、Histogram 等數(shù)據(jù)。

          下面來看看具體如何使用,這里我以 Pulsar 源碼的代碼進行演示:

          public InstrumentProvider(OpenTelemetry otel) {  
              if (otel == null) {  
                  // By default, metrics are disabled, unless the OTel java agent is configured.  
                  // This allows to enable metrics without any code change.        otel = GlobalOpenTelemetry.get();  
              }    this.meter = otel.getMeterProvider()  
                      .meterBuilder("org.apache.pulsar.client")  
                      .setInstrumentationVersion(PulsarVersion.getVersion())  
                      .build();  
          }

          LongCounterBuilder builder = meter.counterBuilder(name)  
                  .setDescription(description)  
                  .setUnit(unit.toString());

          Meter Exporter

          Meter Exporter 則是一個 OpenTelemetry 獨有的概念,與我們之前講到的一樣:OpenTelemetry 作為廠商無關(guān)的平臺,允許我們將數(shù)據(jù)寫入到任何兼容的產(chǎn)品里。

          所以我們在使用 Metrics 時需要指定一個 exporter:

          Exporter 類型 作用 備注 參數(shù)
          OTLP Exporter 通過 OpenTelemetry Protocol(OTLP) 發(fā)送指標數(shù)據(jù)到 collect。 默認生產(chǎn)環(huán)境中推薦使用,需要將數(shù)據(jù)發(fā)送到支持 OTLP 的后端,如 OpenTelemetry Collector。 -Dotel.metrics.exporter=otlp (default)
          Console Exporter 將指標數(shù)據(jù)打印到控制臺的導(dǎo)出器。 開發(fā)和調(diào)試,快速查看指標數(shù)據(jù)。 -Dotel.metrics.exporter=console
          Prometheus Exporter 將指標數(shù)據(jù)以 Prometheus 抓取的格式暴露給 Prometheus 服務(wù)。 與 Prometheus 集成,適用于需要 Prometheus 監(jiān)控的場景,這個可以無縫和以往使用 prometheus 的場景兼容 -Dotel.metrics.exporter=prometheus

          Metric Instruments

          與 prometheus 類似,OpenTelemetry 也提供了以下幾種指標類型:

          • Counter:單調(diào)遞增計數(shù)器,比如可以用來記錄訂單數(shù)、總的請求數(shù)。
          • UpDownCounter:與 Counter 類似,只不過它可以遞減。
          • Gauge:用于記錄隨時在變化的值,比如內(nèi)存使用量、CPU 使用量等。
          • Histogram:通常用于記錄請求延遲、響應(yīng)時間等。

          同時每個指標還有以下幾個字段:

          • Name:名稱,必填。
          • Kind:類型,必填。
          • Unit:單位,可選。
          • Description:描述,可選。
          messageInCounter = meter  
                  .counterBuilder(MESSAGE_IN_COUNTER)  
                  .setUnit("{message}")  
                  .setDescription("The total number of messages received for this topic.")  
                  .buildObserver();

          還是以 Pulsar 的為例,messageInCounter 是一個記錄總的消息接收數(shù)量的 Counter 類型。

          subscriptionCounter = meter  
                  .upDownCounterBuilder(SUBSCRIPTION_COUNTER)  
                  .setUnit("{subscription}")  
                  .setDescription("The number of Pulsar subscriptions of the topic served by this broker.")  
                  .buildObserver();

          這是記錄一個訂閱者數(shù)量的指標,類型是 UpDownCounter,也就是可以增加減少的指標。

          private static final List<Double> latencyHistogramBuckets =  
                  Lists.newArrayList(.0005, .001, .0025, .005, .01, .025, .05, .1, .25, .51.02.55.010.030.060.0);


          DoubleHistogramBuilder builder = meter.histogramBuilder("pulsar.client.producer.message.send.duration")  
                  .setDescription("Publish latency experienced by the application, includes client batching time")  
                  .setUnit(Unit.Seconds.toString())  
                  .setExplicitBucketBoundariesAdvice(latencyHistogramBuckets);

          這是一個記錄 Pulsar producer 發(fā)送延遲的指標,類型是 Histogram

          backlogQuotaAge = meter  
                  .gaugeBuilder(BACKLOG_QUOTA_AGE)  
                  .ofLongs()  
                  .setUnit("s")  
                  .setDescription("The age of the oldest unacknowledged message (backlog).")  
                  .buildObserver();

          這是一個記錄最大 unack 也就是 backlog 時間的指標,類型是 Gauge。

          案例

          在之前的文章:實戰(zhàn):如何編寫一個 OpenTelemetry Extensions中講過如何開發(fā)一個 OpenTelemetry 的 extension,其實當(dāng)時我就是開發(fā)了一個用于在 Pulsar 客戶端中暴露指標的一個插件。

          不過目前 Pulsar 社區(qū)已經(jīng)集成了該功能。

          其中的核心代碼與上面講到的類似:

          public static void registerObservers() {    
              Meter meter = MetricsRegistration.getMeter();    
              
              meter.gaugeBuilder("pulsar_producer_num_msg_send")    
                      .setDescription("The number of messages published in the last interval")    
                      .ofLongs()    
                      .buildWithCallback(    
                              r -> recordProducerMetrics(r, ProducerStats::getNumMsgsSent));

          private static void recordProducerMetrics(ObservableLongMeasurement observableLongMeasurement, Function<ProducerStats, Long> getter) {    
              for (Producer producer : CollectionHelper.PRODUCER_COLLECTION.list()) {    
                  ProducerStats stats = producer.getStats();    
                  String topic = producer.getTopic();    
                  if (topic.endsWith(RetryMessageUtil.RETRY_GROUP_TOPIC_SUFFIX)) {    
                      continue;    
                  }        observableLongMeasurement.record(getter.apply(stats),    
                          Attributes.of(PRODUCER_NAME, producer.getProducerName(), TOPIC, topic));    
              }}

          只是這里使用了 buildWithCallback 回調(diào)函數(shù),OpenTelemetry 會每隔 30s 調(diào)用一次這個函數(shù),通常適用于 Gauge 類型的數(shù)據(jù)。

          java -javaagent:opentelemetry-javaagent.jar \  
               -Dotel.javaagent.extensions=ext.jar  \
               -Dotel.metrics.exporter=prometheus \
               -Dotel.exporter.prometheus.port=18180 \
               -jar myapp.jar

          配合上 Prometheus 的兩個啟動參數(shù)就可以在本地 18180 中獲取到指標數(shù)據(jù):

          curl http://127.0.0.1:18180/metrics

          當(dāng)然也可以直接發(fā)往 OpenTelemetry-Collector 中,再由它發(fā)往 prometheus,只是這樣需要額外在 collector 中配置一下:

          exporters:
            debug: {}
            otlphttp:
              metrics_endpoint: http://promethus:8480/insert/0/opentelemetry/api/v1/push
          service:
            pipelines:
              metrics:
                exporters:
                - otlphttp
                processors:
                - k8sattributes
                - batch
                receivers:
                - otlp 

          這樣我們就可以在 Grafana 中通過 prometheus 查詢到數(shù)據(jù)了。

          有一點需要注意,如果我們自定義的指標最好是參考官方的語義和命名規(guī)范來定義這些指標名稱。

          比如 OpenTelemetry 的規(guī)范中名稱是用 . 來進行分隔的。

          切換為 OpenTelemetry 之后自然就不需要依賴 prometheus 的包,取而代之的是 OTel 的包:

          compileOnly 'io.opentelemetry:opentelemetry-sdk-extension-autoconfigure-spi:1.34.1'  
          compileOnly 'io.opentelemetry.instrumentation:opentelemetry-instrumentation-api:1.32.0'

          總結(jié)

          相對來說 Metrics 的使用比 Trace 簡單的多,同時 Metrics 其實也可以和 Trace 進行關(guān)聯(lián),也就是 Exemplars,限于篇幅就不在本文展開了,感興趣的可以自行查閱。

          參考鏈接:

          • https://github.com/apache/pulsar/blob/master/pulsar-client/src/main/java/org/apache/pulsar/client/impl/metrics/InstrumentProvider.java
          • https://opentelemetry.io/docs/specs/semconv/general/metrics/
          • https://opentelemetry.io/docs/specs/otel/metrics/data-model/#exemplars
          順便打個廣告:最近在小范圍運營知識星球,已經(jīng)有一些朋友加入了,并且已經(jīng)在持續(xù)輸出內(nèi)容,更多福利和內(nèi)容可以掃碼查看,或者點閱讀原文。
          現(xiàn)在試運營階段是 69-20=49。


          往期推薦

          從 Dapper 到 OpenTelemetry:分布式追蹤的演進之旅

          幾個你或許并不知道 kubernetes 技巧

          實操 OpenTelemetry:通過 Demo 掌握微服務(wù)監(jiān)控的藝術(shù)

          OpenTelemetry 實踐指南:歷史、架構(gòu)與基本概念

          OpenTelemetry agent 對 Spring Boot 應(yīng)用的影響:一次 SPI 失效的調(diào)查

           

          點分享

          點收藏

          點點贊

          點在看

           

          瀏覽 452
          2點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          2點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  999在线免费视频 | 影音先锋人妻啪啪aV资源网站 | 色欲国产精品毛片大全 | 精品区一二三 | 亚洲视频在线观看 |