服務發現
概述
如上圖,Prometheus核心功能包括服務發現、數據采集和數據存儲。服務發現模塊專門負責發現需要監控的目標采集點(target
)信息,數據采集模塊從服務發現模塊訂閱該信息,獲取到target
信息后,其中就包含協議(scheme
)、主機地址:端口(instance
)、請求路徑(metrics_path
)、請求參數(params
)等;然后數據采集模塊就可以基于這些信息構建出一個完整的Http Request
請求,定時通過pull http
協議不斷的去目標采集點(target
)拉取監控樣本數據(sample
);最后,將采集到監控樣本數據交由TSDB
模塊進行數據存儲。
【資料圖】
為什么需要服務發現模塊?
類似于微服務通過引入注冊中心組件解決眾多微服務間錯綜復雜的依賴調用。無論是服務主動停止,意外掛掉,還是因為流量增加對服務實現進行擴容,這些服務數據或狀態上的動態變化,通過注冊中心屏蔽服務狀態變更造成的影響,簡化了調用方處理邏輯。
同理,Prometheus
最開始設計是一個面向云原生應用程序的,云原生、容器場景下按需的資源使用方式對于監控系統而言就意味著沒有了一個固定的監控目標,所有的監控對象(基礎設施、應用、服務)都在動態的變化。Prometheus
解決方案就是引入一個中間的代理人,這個代理人掌握著當前所有監控目標的訪問信息,Prometheus
只需要向這個代理人詢問有哪些監控目標即可,這種模式被稱為服務發現(service discovery
)。
目前,Prometheus
支持的服務發現協議是非常豐富的,最新版本(2.41
)已支持接近三十種服務發現協議:
服務發現配置解析
1、Prometheus
服務啟動加載prometheus.yml
配置文件會被解析Config
結構體:
?
Config
結構體是配置類的最頂層結構,內部包含6個字段分別對應prometheus
配置的6大組成部分。
?
2、其中數據采集配置部分ScrapeConfigs
對應的是一個*ScrapeConfig類型
切片,一個ScrapeConfig
對應的是scrape_configs
配置下的一個job
抓取任務,服務發現協議配置對應其中ServiceDiscoveryConfigs
字段:
3、discovery.Configs
對應的是Config
切片:
type Configs []Config
所以,一個job
抓取任務下可以配置多個服務發現協議,如:
- job_name: "prometheus" metrics_path: /metrics static_configs: - targets: ["124.222.45.207:9090"] file_sd_configs: - files: - targets/t1.json - targets/t2.json refresh_interval: 5m
4、Config
是一個接口:
Config
是一個接口的定義,每種服務發現協議都會存在一個對應Config
接口的實現(見下圖)。該接口主要定義兩個方法:
1、Name() string:定義服務發現協議類型,如eureka、kubernetes等等;2、NewDiscoverer(DiscovererOptions) (Discoverer, error):返回一個Discoverer類型變量,該類型也是一個接口,其只定義了一個方法Run方法,即Discoverer是對應的服務發現協議具體運行邏輯封裝,通過Run方法提供統一的運行入口。
服務發現核心原理
說明:
Prometheus
服務發現核心邏輯的入口主要關注Manager
結構體的ApplyConfig
方法:基于服務發現的配置使其生效;
ApplyConfig
方法包括四個主要步驟:
type provider struct { name string d Discoverer subs []string config interface{}}
?一個job下一個服務發現協議對應一個Discoverer。?
provider
還有額外三個字段:
1、name
:provider
名稱,格式:fmt.Sprintf("%s/%d", typ, len(m.providers))
;
2、subs
:string
切片,存放job
名稱,因為可能不同job
下存在一致的服務發現配置,就只會生成一個provider
,然后subs
存放job
列表;
3、config
:服務發現配置
Discoverer
接口Run
方法,讓服務發現邏輯運行;協程中運行updater
方法;Discoverer
接口Run
方法主要基于具體服務發現協議發現target
,然后通過通道傳遞給updater
處理邏輯,將其解析處理放入到Manager
結構體中targets
字段中,并向triggerSend
通道發送信號,表示當前targets
發生變更;Manager
結構體sender
方法每5秒監聽triggerSend
通道信號,并將Manager
結構體中targets
字段處理后放入到syncCh
通道中;數據采集模塊(scrape
)監聽syncCh
通道,就可以獲取到服務發現生成的targets
信息,然后reload
將target
納入監控開始抓取監控指標。啟動provider
:遍歷Manager
結構體中providers
切片,啟動每個provider
,該步驟主要是啟動兩個協程:?Manager
結構體sender
方法是在Prometheus
啟動時discoveryManagerScrape.Run()
方法中啟動。?取消服務發現:配置變更也會調用ApplyConfig
方法,這時就要把基于之前配置運行的服務發現服務取消,然后基于當前配置重新生成;清空:主要清空discoverCancel
、targets
和providers
幾個容器元素,因為要基于當前配置重新生成;注冊provider
:provider
是對Discoverer
的封裝,不同服務發現協議都會實現Config
接口,其中NewDiscoverer
方法就是創建Discoverer
「Prometheus服務發現核心就是三個協程之間協作:」
「協程1:」負責運行Discoverer
接口Run
方法,基于協議發現采集點;「協程2:」負責將協程1發現的采集點信息更新到Manager
結構體中targets
字段的map
中;「協程3:」負責將Manager
結構體中targets
字段的數據通過通道發送給scrape
模塊;scrape模塊獲取到采集點如何進行數據采集后續scrape模塊分析。
監控指標
Prometheus
服務發現通用指標主要有如下5個,都定義在discovery/manager.go
中:
prometheus_sd_discovered_targetsprometheus_sd_failed_configsprometheus_sd_received_updates_totalprometheus_sd_updates_delayed_totalprometheus_sd_updates_total
「1、采集點數量指標」
服務發現主要基于協議發現采集目標,prometheus_sd_discovered_targets
指標反饋各個job
發現的采集目標數:
prometheus_sd_discovered_targets:gauge類型,當前發現的目標數config:job名稱name:取值scrape和notify,區分指標抓取服務發現還是告警通知服務發現示例:prometheus_sd_discovered_targets{config="auth_es1", name="scrape"} 12
?這里基于協議發現的目標數,還未進入采集模塊,并不能區分是在線還是離線。?
「2、服務發現協議異常錯誤指標」
服務發現會給每個發現配置項生成一個provider
,并為每個provider
使用協程運行,如果基于配置項生成provider
錯誤就可以通過prometheus_sd_failed_configs
指標反饋:
prometheus_sd_failed_configs:gauge類型,當前無法加載的服務發現配置數配置數:一個job可能存在多個服務發現協議配置,對應配置項則是多個示例:prometheus_sd_failed_configs{name="scrape"} 10prometheus_sd_failed_configs{name="notify"} 5
一個job
可能對應多個服務發現配置項,如下:這個job
下配置了static_configs
和file_sd_configs
兩個服務發現協議配置,則對應兩個服務發現配置項,注冊兩個provider
,每個provider
在獨立協程中運行:
scrape_configs: # The job name is added as a label `job=` to any timeseries scraped from this config. - job_name: "test" static_configs: - targets: ["localhost:9090"] file_sd_configs: - refresh_interval: 5m files: - targets/manual.*.json
「3、協程交互指標」
服務發現主要涉及3類協程:
Discoverer協程
(多個):封裝provider
,基于協議發現采集點,這里可能會存在多個,一個provider
對應一個Discoverer協程
;updater協程
(1個):Discoverer協程
發現采集點,通過channel通道
通知到updater協程
,updater協程
將采集點更新到Manager結構體
中targets字段
中,然后向Manager結構體
中triggerSend通道
寫入數據,告訴sender
協程targets
有更新;sender協程
(1個):sender協程
每5秒檢測triggerSend
通道數據,檢測到更新則將Manager
結構體targets
數據處理封裝寫入到Manager
結構體syncCh
通道中,scrape
模塊監測該通道,即完成將服務發現模塊
和scrape模塊
交互。這其中涉及三個指標:
prometheus_sd_received_updates_totalprometheus_sd_updates_delayed_totalprometheus_sd_updates_total
關鍵詞: