<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搞定微服務監(jiān)控

          共 5404字,需瀏覽 11分鐘

           ·

          2021-03-27 06:38

          最近對服務進行監(jiān)控,而當前監(jiān)控最流行的數(shù)據(jù)庫就是 Prometheus,同時 go-zero 默認接入也是這款數(shù)據(jù)庫。今天就對 go-zero 是如何接入 Prometheus ,以及開發(fā)者如何自己定義自己監(jiān)控指標。

          監(jiān)控接入

          go-zero 框架中集成了基于 prometheus 的服務指標監(jiān)控。但是沒有顯式打開,需要開發(fā)者在 config.yaml 中配置:

          Prometheus:
            Host: 127.0.0.1
            Port: 9091
            Path: /metrics

          如果開發(fā)者是在本地搭建 Prometheus,需要在 Prometheus 的配置文件 prometheus.yaml 中寫入需要收集服務監(jiān)控信息的配置:

          - job_name: 'file_ds'
              static_configs:
                - targets: ['your-local-ip:9091']
                  labels:
                    job: activeuser
                    app: activeuser-api
                    env: dev
                    instance: your-local-ip:service-port

          因為本地是用 docker 運行的。將 prometheus.yaml 放置在 docker-prometheus 目錄下:

          docker run \
              -p 9090:9090 \
              -v dockeryml/docker-prometheus:/etc/prometheus \
              prom/prometheus

          打開 localhost:9090 就可以看到:

          點擊 http://service-ip:9091/metrics 就可以看到該服務的監(jiān)控信息:

          上圖我們可以看出有兩種 bucket,以及 count/sum 指標。

          go-zero 是如何集成監(jiān)控指標?監(jiān)控的又是什么指標?我們?nèi)绾味x我們自己的指標?下面就來解釋這些問題

          以上的基本接入,可以參看我們的另外一篇:https://zeromicro.github.io/go-zero/service-monitor.html

          如何集成

          上面例子中的請求方式是 HTTP,也就是在請求服務端時,監(jiān)控指標數(shù)據(jù)不斷被搜集。很容易想到是 中間件 的功能,具體代碼:https://github.com/tal-tech/go-zero/blob/master/rest/handler/prometheushandler.go。

          var (
           metricServerReqDur = metric.NewHistogramVec(&metric.HistogramVecOpts{
            ...
              // 監(jiān)控指標
            Labels:    []string{"path"},
              // 直方圖分布中,統(tǒng)計的桶
            Buckets:   []float64{51025501002505001000},
           })

           metricServerReqCodeTotal = metric.NewCounterVec(&metric.CounterVecOpts{
            ...
              // 監(jiān)控指標:直接在記錄指標 incr() 即可
            Labels:    []string{"path""code"},
           })
          )

          func PromethousHandler(path string) func(http.Handler) http.Handler {
           return func(next http.Handler) http.Handler {
            return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
                // 請求進入的時間
             startTime := timex.Now()
             cw := &security.WithCodeResponseWriter{Writer: w}
             defer func() {
                  // 請求返回的時間
              metricServerReqDur.Observe(int64(timex.Since(startTime)/time.Millisecond), path)
              metricServerReqCodeTotal.Inc(path, strconv.Itoa(cw.Code))
             }()
             // 中間件放行,執(zhí)行完后續(xù)中間件和業(yè)務邏輯。重新回到這,做一個完整請求的指標上報
                // [??:洋蔥模型]
             next.ServeHTTP(cw, r)
            })
           }
          }

          其實整個很簡單:

          1. HistogramVec 負責請求耗時搜集:
            • bucket 存放的就是 option 指定的耗時指標。某個請求耗時多少就會被聚集對應的桶,計數(shù)。
            • 最終展示的就是一個路由在不同耗時的分布,很直觀提供給開發(fā)者可以優(yōu)化的區(qū)域。
          2. CounterVec 負責指定 labels 標簽搜集:
            • Labels: []string{"path", "code"}
            • labels 相當一個 tuple。go-zero 是以(path, code)作為整體,記錄不同路由不同狀態(tài)碼的返回次數(shù)。如果 4xx,5xx過多的時候,是不是應該看看你的服務健康程度?

          如何自定義

          go-zero 中也提供了 prometheus metric 基本封裝,供開發(fā)者自己開發(fā)自己 prometheus 中間件。

          代碼:https://github.com/tal-tech/go-zero/tree/master/core/metric

          名稱用途搜集函數(shù)
          CounterVec單一的計數(shù)。用作:QPS統(tǒng)計CounterVec.Inc() 指標+1
          GuageVec單純指標記錄。適用于磁盤容量,CPU/Mem使用率(可增加可減少)GuageVec.Inc()/GuageVec.Add() 指標+1/指標加N,也可以為負數(shù)
          HistogramVec反應數(shù)值的分布情況。適用于:請求耗時、響應大小HistogramVec.Observe(val, labels) 記錄指標當前對應值,并找到值所在的桶,+1

          另外對 HistogramVec.Observe() 做一個基本分析:

          我們其實可以看到上圖每個 HistogramVec 統(tǒng)計都會有3個序列出現(xiàn):

          • _count:數(shù)據(jù)個數(shù)
          • _sum:全部數(shù)據(jù)加和
          • _bucket{le=a1}:處于 [-inf, a1] 的數(shù)據(jù)個數(shù)

          所以我們也猜測在統(tǒng)計過程中,分3種數(shù)據(jù)進行統(tǒng)計:

          // 基本上在prometheus的統(tǒng)計都是使用 atomic CAS 方式進行計數(shù)的
          // 性能要比使用 Mutex 要高
          func (h *histogram) observe(v float64, bucket int) {
           n := atomic.AddUint64(&h.countAndHotIdx, 1)
           hotCounts := h.counts[n>>63]

           if bucket < len(h.upperBounds) {
              // val 對應數(shù)據(jù)桶 +1
            atomic.AddUint64(&hotCounts.buckets[bucket], 1)
           }
           for {
            oldBits := atomic.LoadUint64(&hotCounts.sumBits)
            newBits := math.Float64bits(math.Float64frombits(oldBits) + v)
              // sum指標數(shù)值 +v(畢竟是總數(shù)sum)
            if atomic.CompareAndSwapUint64(&hotCounts.sumBits, oldBits, newBits) {
             break
            }
           }
           // count 統(tǒng)計 +1
           atomic.AddUint64(&hotCounts.count, 1)
          }

          所以開發(fā)者想定義自己的監(jiān)控指標:

          1. 在使用 goctl 生成API代碼指定要生成的 中間件:https://zeromicro.github.io/go-zero/middleware.html
          2. 在中間件文件書寫自己需要統(tǒng)計的指標邏輯
          3. 當然,開發(fā)者也可以在業(yè)務邏輯中書寫統(tǒng)計的指標邏輯。同上。

          上述都是針對 HTTP 部分邏輯的解析,RPC 部分的邏輯類似,你可以在 攔截器 部分看到設(shè)計。

          總結(jié)

          本文分析了 go-zero 服務監(jiān)控指標的邏輯,當然對于一些基礎(chǔ)設(shè)施的監(jiān)控,prometheus 可以通過引入對應的 exporter 來完成。



          推薦閱讀


          福利

          我為大家整理了一份從入門到進階的Go學習資料禮包,包含學習建議:入門看什么,進階看什么。關(guān)注公眾號 「polarisxu」,回復 ebook 獲??;還可以回復「進群」,和數(shù)萬 Gopher 交流學習。

          瀏覽 50
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

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

          手機掃一掃分享

          分享
          舉報
          <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>
                  国产高清无码内射视频在线观看 | 麻豆精产国品免费观看mv | 夜夜嗨无码 | 无码视频免费看 | 国产肏屄网站 |