背景 : Prometheus 是近年來最流行的開源監控框架, 其功能強大且易于使用, 擁有各種主流后端語言(Java/Go/Python/Node.js等)與各種場景(如web handler/ k8s/Nginx/MySQL等)的客戶端, 并自帶圖形化顯示頁面。分享一個快速入門Prometheus 的教程, 實現一個極簡的, 后端開發需要特別關注的 QPS 監控。
Docker 部署 Prometheus
命令行輸入
css
復制代碼
docker run -d --name prometheus-node1 -p 9090:9090 bitnami/prometheus:latest
這條命令會創建一個名為 prometheus-node1 的容器, 使用 bitnami/prometheus:latest 的鏡像, 宿主機的 9090 端口與容器內的9090端口相通。
修改 prometheus 配置文件
bash
復制代碼
docker cp prometheus-node1:/opt/bitnami/prometheus/conf/prometheus.yml prometheus.yml
這將 prometheus-node1 容器內的 prometheus.yml 配置文件拷貝出來, 大概長這樣:
yaml
復制代碼
# 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']
簡單看看這個配置文件里面最重要的兩個配置。先看 global 下面的兩個配置項, scrape_interval: 15 s 表示 每15秒獲取一次監控指標(prometheus 中叫 target), evaluation_interval: 15s 表示 每15秒執行一次 rules。 scrape_configs 直接定義了監控的 target. job_name 為 這個 target的名字, static_configs 下面的 tartgets 直接指出了監控的 IP:端口。剩下的配置留給大家自己去學習,出于快速上手 Prometheus的目的,我就不細講了。
我們下面修改一下 targets 配置, 變成這樣:
yaml
復制代碼
# 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: ['172.17.0.2:20001'] # 需要監控的 IP:端口
我們修改了 targets 配置, 將他修改成需要監控的 IP:端口, 這里的 172.17.0.2 為另外一個 docker 容器的 IP地址(待會會將), 20001 為要監控的端口(待會會將)
然后將修改后的 配置文件放回 docker 容器
bash
復制代碼
docker cp prometheus.yml prometheus-node1:/opt/bitnami/prometheus/conf/prometheus.yml
再重啟 容器
復制代碼
docker restart prometheus-node1
寫一個 Web Handler 和 Web Client
創建一個 prometheus_demo 目錄, 命令行輸入
go
復制代碼
go mod init prometheus_demo go mod tidy
文件目錄如下:
lua
復制代碼
-- prometheus_demo -- go.mod -- main.go -- client --- client.go
其中main.go 為 server 端, client.go 為客戶端
其中 main.go 如下:
go
復制代碼
package main import ( "fmt" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promhttp" "net/http" "time" ) // 只可增加的一個計數器 var req_counter_vec = prometheus.NewCounterVec( prometheus.CounterOpts{ Name: "req_counter_vec", Help: "request counter vector", }, []string{"endpoint"}, ) func main() { prometheus.MustRegister(req_counter_vec) http.Handle("/metrics", promhttp.Handler()) http.HandleFunc("/hello", HelloHandler) errChan := make(chan error) go func() { errChan <- http.ListenAndServe(":20001", nil) }() err := <-errChan if err != nil { fmt.Println("Hello server stop running.") } } func HelloHandler(w http.ResponseWriter, r *http.Request) { path := r.URL.Path req_counter_vec.WithLabelValues(path).Inc() time.Sleep(100 * time.Millisecond) }
服務端比較簡單, 定義了 一個 counter vector, 里面裝的是prometheus 四種數據類型的 Counter。Name 為 vector 的 名字, help 為詳細的解釋, 都可以自取。[]string{"endpoint"} 表示以 endpoint 進行區分 vector 內不同的 counter。這就好比一個數組, 用 索引0,1,2 區分數組內的不同元素。
Counter 正如我注釋里面寫的, 就是一個計數器, 一次只能增加1, 比如每次來一個請求, 那么就增加1。與 Counter 相對的是 Prometheus 的四種數據類型中的 Gauge。 Gauge 可加可減。數據類型 name 為變量名字, help 為變量詳細 解釋, 隨后將這個變量注冊一下, 以便被 prometheus 監控到。當然還有另外兩種用于直方圖的 數據類型 Histogram 和 Summary, 我就不細說了。
隨后定義了一個簡單的 web handler, 里面干了兩件事, 一件是記錄將 counter 加 1, withLabelValues 就是就和剛才的 endpoint 相對應, 相當于標記一下這個 vector 中的 哪一個 counter 加一。 另一件事情就是休眠100ms, 不至于太快結束不利于觀察。
client.go 如下
go
復制代碼
package main import ( "log" "net/http" "sync" "time" ) func main() { for { wg := sync.WaitGroup{} for i := 0; i < 50; i++ { wg.Add(1) go func(i int) { defer wg.Done() resp, err := http.Get("http://localhost:20001/hello") if err != nil { log.Println(err) return } resp.Body.Close() }(i) } wg.Wait() time.Sleep(5 * time.Second) } }
客戶端就更簡單了, 死循環里面開50個 go routine 不斷發請求。
隨后將 prometheus_demo 文件部署到 docker 中, 如何在 docker 中搭建 go 開發環境可以參考我的另一篇 文章:?保姆級從0到1講解go遠程開發環境搭建(從Docker安裝到使用Goland遠程部署和調試)。
然后在docker容器中 prometheus_demo 目錄 和 prometheus_demo/client 目錄下 分別使用下面兩個命令運行服務端和客戶端
go
復制代碼
go run main.go go run client.go
打開 Prometheus Web 界面
在宿主機上用瀏覽器打開 http://localhost:9090/targets?search= 如果可以觀察到下面這樣, 說明 prometheus 部署成功。
注意,上面這幅圖一定要啟動 prometheus_demo 的 main.go 才能觀察得到, 因為 prometheus 監控 20001 端口, 如果 server 端沒啟動, prometheus 當然啥都監控不到。
下面來看如何監控 QPS, 在宿主機上用瀏覽器打開, http://localhost:9090/graph
然后在放大鏡旁邊的框框內輸入下面這一串指令
ini
復制代碼
rate(req_counter_vec{endpoint="/hello"}[15s])
再點擊 graph 應該看到下面這樣類似的圖片
解釋一下, rate(req_counter_vec{endpoint="/hello"}[15s]) 這句指令是什么意思。 req_counter_vec 就是之前定義的裝 counter 的 vector, {endpoint="/hello"} 也就是 HelloHandler 里面記錄請求次數的 那個counter, rate 接 [15s] 表示每15秒(和 配置文件里面的15秒保持一致)記錄一下 counter 的變化情況(因為 counter只能增加, 所以變化為一個 非負數), 總請求次數除以時間段, 就是一個范圍內的 QPS。我們這里并不是1秒, 而是15秒, 也就可以近似看作 QPS。
如果有同學發現沒有圖形出現, 顯示 empty query result, 可能是北京時間和標準時間不同步, 可以勾選 use local time, 或者 調整一 圖形界面的窗口時間(我圖片上的 5m 和 2022-12-27 20:14:02 那里) 。
還有點同學出現的不是直方圖而是一個個小的線段, 這是因為圖形的不同展示方式的原因, 可以 點一下 Hide Exemplars 左邊的兩個小圖標。
巨人的肩膀
yunlzheng.gitbook.io/prometheus-…
hub.docker.com/r/bitnami/p…
juejin.cn/post/707865…
cjting.me/2017/03/12/…
??
下面是配套資料,對于做【軟件測試】的朋友來說應該是最全面最完整的備戰倉庫,這個倉庫也陪伴我走過了最艱難的路程,希望也能幫助到你!
?
軟件測試面試小程序
被百萬人刷爆的軟件測試題庫!!!誰用誰知道!!!全網最全面試刷題小程序,手機就可以刷題,地鐵上公交上,卷起來!
涵蓋以下這些面試題板塊:
1、軟件測試基礎理論 ,2、web,app,接口功能測試 ,3、網絡 ,4、數據庫 ,5、linux 6、web,app,接口自動化 ,7、性能測試 ,8、編程基礎,9、hr面試題 10、開放性測試題,11、安全測試,12、計算機基礎
?編輯資料獲取方式 :xiaobei_upup,添加時備注“csdn alex”