帶你十天輕鬆搞定 Go 微服務系列(八、服務監控)

kevwan發表於2022-01-26

序言

我們透過一個系列文章跟大家詳細展示一個 go-zero 微服務示例,整個系列分十篇文章,目錄結構如下:

  1. 環境搭建
  2. 服務拆分
  3. 使用者服務
  4. 產品服務
  5. 訂單服務
  6. 支付服務
  7. RPC 服務 Auth 驗證
  8. 服務監控(本文)
  9. 鏈路追蹤
  10. 分散式事務

期望透過本系列帶你在本機利用 Docker 環境利用 go-zero 快速開發一個商城系統,讓你快速上手微服務。

完整示例程式碼:github.com/nivin-studio/go-zero-ma...

首先,我們來看一下整體的服務拆分圖:

8.1 Prometheus 介紹

Prometheus 是一款基於時序資料庫的開源監控告警系統,基本原理是透過 HTTP 協議週期性抓取被監控服務的狀態,任意服務只要提供對應的 HTTP 介面就可以接入監控。不需要任何 SDK 或者其他的整合過程,輸出被監控服務資訊的 HTTP 介面被叫做 exporter 。目前網際網路公司常用的服務大部分都有 exporter 可以直接使用,比如 VarnishHaproxyNginxMySQLLinux 系統資訊(包括磁碟、記憶體、CPU、網路等等)。Promethus 有以下特點:

  • 支援多維資料模型(由度量名和鍵值對組成的時間序列資料)
  • 支援 PromQL 查詢語言,可以完成非常複雜的查詢和分析,對圖表展示和告警非常有意義
  • 不依賴分散式儲存,單點伺服器也可以使用
  • 支援 HTTP 協議主動拉取方式採集時間序列資料
  • 支援 PushGateway 推送時間序列資料
  • 支援服務發現和靜態配置兩種方式獲取監控目標
  • 支援接入 Grafana

8.2 go-zero 使用 Prometheus 監控服務

go-zero 框架中整合了基於 Prometheus 的服務指標監控,go-zero 目前在 http 的中介軟體和 rpc 的攔截器中新增了對請求指標的監控。

主要從 請求耗時請求錯誤 兩個維度,請求耗時採用了 Histogram 指標型別定義了多個 Buckets 方便進行分位統計,請求錯誤採用了 Counter 型別,並在 http metric 中新增了 path 標籤,rpc metric 中新增了 method 標籤以便進行細分監控。

接下來我們分別為前面幾章實現的服務新增 Prometheus 監控,首先我們先回顧下 第二章 服務拆分,為了模擬服務的分散式部署,我們是在一個容器裡啟動了所有的服務,併為其分配了不同的埠號。下面我們再為這些服務分配一個 Prometheus 採集指標資料的埠號。

服務 api 服務埠號 rpc 服務埠號 api 指標採集埠號 rpc 指標採集埠號
user 8000 9000 9080 9090
product 8001 9001 9081 9091
order 8002 9002 9082 9092
pay 8003 9003 9083 9093

8.2.1 新增 user api 服務 Prometheus 配置

$ vim mall/service/user/api/etc/user.yaml
Name: User
Host: 0.0.0.0
Port: 8000

...

Prometheus:
  Host: 0.0.0.0
  Port: 9080
  Path: /metrics

8.2.2 新增 user rpc 服務 Prometheus 配置

$ vim mall/service/user/rpc/etc/user.yaml
Name: user.rpc
ListenOn: 0.0.0.0:9000

...

Prometheus:
  Host: 0.0.0.0
  Port: 9090
  Path: /metrics

8.2.3 新增 product api 服務 Prometheus 配置

$ vim mall/service/product/api/etc/product.yaml
Name: Product
Host: 0.0.0.0
Port: 8001

...

Prometheus:
  Host: 0.0.0.0
  Port: 9081
  Path: /metrics

8.2.4 新增 product rpc 服務 Prometheus 配置

$ vim mall/service/product/rpc/etc/product.yaml
Name: product.rpc
ListenOn: 0.0.0.0:9001

...

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

8.2.5 新增 order api 服務 Prometheus 配置

$ vim mall/service/order/api/etc/order.yaml
Name: Order
Host: 0.0.0.0
Port: 8002

...

Prometheus:
  Host: 0.0.0.0
  Port: 9082
  Path: /metrics

8.2.6 新增 order rpc 服務 Prometheus 配置

$ vim mall/service/order/rpc/etc/order.yaml
Name: order.rpc
ListenOn: 0.0.0.0:9002

...

Prometheus:
  Host: 0.0.0.0
  Port: 9092
  Path: /metrics

8.2.7 新增 pay api 服務 Prometheus 配置

$ vim mall/service/pay/api/etc/pay.yaml
Name: Pay
Host: 0.0.0.0
Port: 8003

...

Prometheus:
  Host: 0.0.0.0
  Port: 9083
  Path: /metrics

8.2.8 新增 pay rpc 服務 Prometheus 配置

$ vim mall/service/pay/rpc/etc/pay.yaml
Name: pay.rpc
ListenOn: 0.0.0.0:9003

...

Prometheus:
  Host: 0.0.0.0
  Port: 9093
  Path: /metrics

提示:配置修改後,需要重啟服務才會生效。

8.2.9 修改 Prometheus 配置

第一章 環境搭建 中我們整合了 Prometheus 服務,在prometheus 目錄下有個 prometheus.yml 的配置檔案,我們現在需要修改這個配置檔案。

# my global config
global:
  scrape_interval: 15s # Set the scrape interval to every 15 seconds. Default is every 1 minute. 
  evaluation_interval: 15s # Evaluate rules every 15 seconds. The default is every 1 minute.     
  # scrape_timeout is set to the global default (10s).

# Alertmanager configuration
alerting:
  alertmanagers:
    - static_configs:
        - targets:
          # - alertmanager:9093

# Load rules once and periodically evaluate them according to the global 'evaluation_interval'.  
rule_files:
  # - "first_rules.yml"
  # - "second_rules.yml"

# A scrape configuration containing exactly one endpoint to scrape:
# Here it's Prometheus itself.
scrape_configs:
  # The job name is added as a label `job=<job_name>` to any timeseries scraped from this config.
  - job_name: "prometheus"

    # metrics_path defaults to '/metrics'
    # scheme defaults to 'http'.

    static_configs:
      - targets: ["localhost:9090"]

  # 我們自己的商城專案配置
  - job_name: 'mall'
    static_configs:
      # 目標的採集地址
      - targets: ['golang:9080']
        labels:
          # 自定義標籤
          app: 'user-api'
          env: 'test'

      - targets: ['golang:9090']
        labels:
          app: 'user-rpc'
          env: 'test'

      - targets: ['golang:9081']
        labels:
          app: 'product-api'
          env: 'test'

      - targets: ['golang:9091']
        labels:
          app: 'product-rpc'
          env: 'test'

      - targets: ['golang:9082']
        labels:
          app: 'order-api'
          env: 'test'

      - targets: ['golang:9092']
        labels:
          app: 'order-rpc'
          env: 'test'

      - targets: ['golang:9083']
        labels:
          app: 'pay-api'
          env: 'test'

      - targets: ['golang:9093']
        labels:
          app: 'pay-rpc'
          env: 'test'

提示:配置檔案修改好後,需要重啟 Prometheus 服務容器才能生效。

8.2.10 訪問 Prometheus 視覺化介面

  • 第一章 環境搭建 中我們整合了 Prometheus 服務,併為其埠號9090 做了宿主機埠 3000 的對映關係,所以在瀏覽器中輸入 http://127.0.0.1:3000/ 訪問 Prometheus 介面。

  • 選擇 Status -> Targets 選單,即可看到我們配置的採集目標的狀態和自定義的標籤。

  • 我們多次訪問 api 服務的介面後,選擇 Graph 選單,在查詢輸入框中輸入 {path="api介面地址"} 或者 {method="rpc介面方法"} 指令,即可檢視監控指標。

8.3 使用 Grafana 視覺化 Prometheus 指標資料

8.3.1 新增 Prometheus 資料來源

  • 第一章 環境搭建 中我們整合了 Grafana 服務,併為其埠號3000 做了宿主機埠 4000 的對映關係,所以在瀏覽器中輸入 http://127.0.0.1:4000/ 訪問 Grafana 介面。點選左側邊欄 Configuration -> Data Source -> Add data source 進行資料來源新增。

  • 然後選擇 Prometheus 資料來源

  • 填寫 HTTP 配置中 URL 地址(我這裡的 IP地址Prometheus 所在容器的 IP地址),然後點選 Save & test 按,上方會提示 Data source is working,說明我們資料來源新增成功且正常工作。

8.3.2 新增 Variables 用於服務篩選

  • 點選左側邊欄 Dashboard 選擇右上角 Dashboard settings 按鈕,在 Settings 頁面選擇 Variables -> Add variable 新增變數,方便針對不同的標籤進行過濾篩選。

  • 分別新增 api_app API服務名稱,rpc_app RPC服務名稱變數,用於不同服務的篩選。變數資料來源選擇 Prometheus 資料來源,使用正規表示式提取出對應的 app 標籤。

8.3.3 新增 api 介面 qps 儀表盤

  • 回到 Dashboard 頁面選擇右上角 Add panel 按鈕,然後再選擇 Add an empty panel 新增一個空的皮膚。

  • 皮膚編輯頁,修改皮膚標題為 API介面QPS,在 Metrics 中輸入 sum(rate(http_server_requests_duration_ms_count{app="$api_app"}[5m])) by (path)path 維度統計 api 介面的 qps

8.3.4 新增 rpc 介面 qps 儀表盤

  • 再新建一個皮膚,修改皮膚標題為 RPC介面QPS,在 Metrics 中輸入 sum(rate(rpc_server_requests_duration_ms_count{app="$rpc_app"}[5m])) by (method)method 維度統計 rpc 介面的 qps

8.3.5 新增 api 介面狀態碼儀表盤

  • 再新建一個皮膚,修改皮膚標題為 API介面狀態碼,在 Metrics 中輸入 sum(rate(http_server_requests_code_total{app="$api_app"}[5m])) by (code)code 維度統計 api 介面的狀態碼

8.3.6 新增 rpc 介面狀態碼儀表盤

  • 再新建一個皮膚,修改皮膚標題為 RPC介面狀態碼,在 Metrics 中輸入 sum(rate(rpc_server_requests_code_total{app="$rpc_app"}[5m])) by (code)code 維度統計 rpc 介面的狀態碼

8.3.7 儲存儀表盤

  • 調整下皮膚位置,選擇右上角 Save dashboard 按鈕儲存儀表盤。

專案地址

github.com/zeromicro/go-zero

歡迎使用 go-zerostar 支援我們!

微信交流群

關注『微服務實踐』公眾號並點選 交流群 獲取社群群二維碼。

本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章