Prometheus Server 内部架构
#Prometheus
整体的 Prometheus Server 内部架构如下图所示:

Note:箭头代表请求或者连接初始化的方向,而不一定是数据流向。
main 函数
main() 函数初始化并运行所有其他 Prometheus Server 组件,同时将相互依赖的组件连接起来。
读取命令行配置并解析
main()定义服务器命令行标志(flag)并解析配置,保存到局部配置结构体变量cfg,同时对某些值进行额外的校验和初始化。这些基于 flag 的配置独立于后续从配置文件中读取到的配置,配置文件根据 --config.file 选项设置。Promethues 区分了基于flag的配置和基于文件的配置:flag用于不支持在不重启服务器的情况下更新的简单设置,而配置文件中提供的任何设置都必须支持在不重启整个服务器的情况下重新加载。
实例化组件
实例化所有运行组件,并使用信道、引用或传递上下文将他们连接在一起,以便后续协调。这些组件包括:服务发现、目标抓取、存储等。
运行组件
server 以 actor-like 模型运行所有组件,使用 run.Group 来协调所有互相连接的 actor 的启动和关闭。多个信道用于强制执行顺序约束,例如在存储准备就绪和初始配置文件加载完成之前不启用网络接口。
配置
配置子系统负责读取、验证和应用由 --config.file 提供的 yaml 配置文件。Promethues Server 支持读取和应用配置文件,同时有一个 [Goroutine](Go goroutine理解 - 知乎 (zhihu.com)) 来监视从同一个文件中重新加载配置的请求。
读取解析配置
加载初始配置或者后续重新加载时,Promethues 调用 config.LoadFile() 从文件读取配置信息并解析到 config.Config 结构体中,该结构体是 Promethues配置文件的顶层配置。它表示了Promethues服务器及其所有组件的整体配置,其结构体成员反映了配置文件的层次结构,每个结构体成员都有一个默认的配置和UnmarshalYAML()方法,该方法可以将配置文件解析到结构体中,并进行进一步的有效性验证和初始化,最后返回解析成功的配置结构体。
Reload handler
Reload handler 是一个 main 函数中实现的 Goroutine,它监听来自网络接口或者HUP信号的配置重载请求。
收到重载请求后,Reload handler 会使用 config.LoadFile()从磁盘重新读取配置文件,生成config.Config结构体,并调用所有支持热配置的组件的ApplyConfig()方法或者自定义重载函数将配置结构体应用于这些组件。
Termination handler
Termination handler 是一个 main 函数中实现的 Goroutine,它监听来自网络接口或者TERM信号的终止请求。
收到终止请求后,Termination handler 返回,并通过 run.Group 提供的 actor 协调功能触发其他 Promethues 组件有序关闭。
Scrape discovery manager
Scrape discovery manager 是一个 discovery.Manager ,它通过 Promethues 的服务发现功能来查找并持续更新需要抓取指标的监控目标列表,它独立于 scrape manager (实际执行目标抓取的模块)运行,并通过同步信道向其提供目标组更新流。
Scrape discovery manager 在自己的 Goroutine 中运行每个配置定义的服务发现机制实例。比如,如果配置文件中 scrape_config 定义了两个 kubernetes_sd_config,管理器将运行两个独立的 kubernetes.Discovery 实例。每个 discovery 实例都会实现discovery.Discoverer 接口,并通过同步信道向 discovery manager 发送目标更新, discovery manager 会用特定 discovery 实例的信息更新目标组,并将其转发给 scrape manager。
在配置更改时,discovery manager 会停止当前运行的所有发现机制实例,并重新启动新配置文件中定义的新机制。
Scrape manager
scrape manager是一个 scrape.Manager,负责从已发现的监控目标中获取指标,并将抓取的样本转发到存储子系统。
目标更新和整体架构
scrape manager 管理所有的抓取对象,所有的抓取对象按group分组,每个group是一个job_name,每个group下含多个 scrapeTarget ,即具体的抓取目标 endpoint。
scrape manager 为每个 group 运行一个 scrape 池,每个 scrape 池对每个目标 endpoint 启动一个 ScrapLoop,按照配置的循环间隔的抓取对象的指标。
discovery manager 通过同步通道向 scrape manager 发送每个 group 的目标更新,然后 scrape manager 会将这些更新应用到相应的 scrape 池中。
目标标签和目标重标签
每当 scrape manager 从 discovery manager 收到给定 scrape 池的目标更新列表, Scrape 池会为每个目标添加默认的label,然后利用 target relabeling configuration 配置生成最后要抓取的目标列表。
目标哈希和抓取时间 ?
为了在 scrape_config 的抓取间隔内以一致的插槽方式分散 scrape 池中的 scrape,每个目标都会根据其标签集和最终 scrape URL 进行计算哈希值,然后利用哈希值在该区间内选择一个确定的偏移量。
目标抓取
ScrapLoop 会周期性的通过 HTTP 请求抓取目标,并通过特定的格式