1.概述
當 Prometheus 有配置檔案修改,我們可以采用 Prometheus 提供的熱更新方法實作在不停服務的情況下實作配置檔案的重新加載。
2.熱更新
熱更新加載方法有兩種:
#1. kill -HUP pid #2. curl -X POST http://192.168.1.102:9090/-/reload
當你采用以上任一方式執行 reload 成功的時候,将在 promtheus log 中看到如下資訊:

如果因為配置資訊填寫不正确導緻更新失敗,将看到類似資訊:
ERRO[0161] Error reloading config: couldn't load configuration (-config.file=prometheus.yml): unknown fields in scrape_config: job_nae source=main.go:146
提示:
- 我個人更傾向于采用 curl -X POST 的方式,因為每次 reload 過後, pid 會改變,使用 kill 方式需要找到目前程序号。
- 從 2.0 開始,hot reload 功能是預設關閉的,如需開啟,需要在啟動 Prometheus 的時候,添加
參數。--web.enable-lifecycle
3.熱更新源碼對比
下面我們再來探讨下這兩種方式内部實作原理。
3.1第一種:kill
通過 kill 指令的 HUP (hang up) 參數實作:
首先 Prometheus 在
cmd/promethteus/main.go
中實作了對程序系統調用監聽,如果收到 syscall.SIGHUP 信号,将執行 reloadConfig 函數。
代碼類似:
hup := make(chan os.Signal) signal.Notify(hup, syscall.SIGHUP) go func() { for { select { case <-hup: if err := reloadConfig(cfg.configFile, reloadables...); err != nil { log.Errorf("Error reloading config: %s", err) } } } }()
3.2.第二種:reload
通過 web 子產品的
/-/reload
請求實作:
curl -v -k http://localhost:9090/-/reoad
- 首先 Prometheus 在 web(web/web.go) 子產品中注冊了一個 POST 的 http 請求
, 它的 handler 是/-/reload
函數,該函數主要向web.reload
chan 裡面發送一個web.reloadCh
。error
- 在 Prometheus 的
中有個單獨的 goroutine 來監聽cmd/promethteus/main.go
,當接受到新值的時候會執行 reloadConfig 函數。web.reloadCh
代碼類似:
hupReady := make(chan bool) go func() { <-hupReady for { select { case rc := <-webHandler.Reload(): if err := reloadConfig(cfg.configFile, reloadables...); err != nil { log.Errorf("Error reloading config: %s", err) rc <- err } else { rc <- nil } } } }()
Prometheus 内部提供了成熟的 hot reload 方案,這大大友善配置檔案的修改和重新加載,在 Prometheus 生态中,很多 Exporter 也采用類似約定的實作方式。