【prometheus】-02 一张图彻底搞懂Prometheus服务发现机制
概述
Prometheus是基于Pull模式抓取监控数据,首先要能够发现需要监控的目标对象target,特别Prometheus
最开始设计是一个面向云原生应用程序的,云原生、容器场景下按需的资源使用方式对于监控系统而言就意味着没有了一个固定的监控目标,所有的监控对象(基础设施、应用、服务)都在动态的变化。而对于Prometheus而言其解决方案就是引入一个中间的代理人(服务注册中心),这个代理人掌握着当前所有监控目标的访问信息,Prometheus只需要向这个代理人询问有哪些监控目标控即可, 这种模式被称为服务发现(service discovery)。
(资料图片仅供参考)
如上图,SD模块专门负责去发现需要监控的target信息,Prometheus去从SD模块订阅该信息,有target信息时会推送给Prometheus,然后Prometheus拿到target信息后通过pull http协议去拉取监控指标数据。
Prometheus支持的服务发现协议是非常丰富的,目前已支持多达二十多种服务发现协议:
服务发现原理图
上图描述Prometheus服务发现协议比较笼统,Prometheus服务发现实现原理大致如下图:
如上图所述,Prometheus服务发现机制大致涉及到三个部分:
1、配置处理模块解析的prometheus.yml
配置中scrape_configs
部分,将配置的job
生成一个个Discoverer
服务,不同的服务发现协议都会有各自的Discoverer
实现方式,它们根据实现逻辑去发现target
,并将其放入到targets
容器中;
2、discoveryManager
组件内部有个定时周期触发任务,每5秒检查targets
容器,如果有变更则将targets
容器中target
信息放入到syncCh
通道中;
3、scrape
组件会监听syncCh
通道,这样需要监控的targets
信息就传递给scrape
组件,然后reload
将target
纳入监控开始抓取监控指标。
配置处理部分会根据scrape_configs
部分配置的不同协议类型生成不同Discoverer
,然后根据它们内部不同的实现逻辑去发现target
,discoveryManager
组件则相当于一个搬运工,scrape
组件则是一个使用者,这两个组件都无感知服务发现协议的差异。
下面分别来分析下配置处理、discoveryManager
组件和scrape
组件在服务发现方面的具体实现流程。
配置处理
上节分析Prometheus
启动流程,有个配置加载
组件通过reloadConfig
加载解析prometheus
配置文件后,在reloader
中循环调用各个组件的ApplyConfig(cfg map[string]Configs)
方法处理配置,这其中就包括discovery/manager.go
:
reloader
中定义如下:
{name:"scrape_sd",//从配置文件中提取Section:scrape_configsreloader:func(cfg*config.Config)error{c:=make(map[string]discovery.Configs)for_,v:=rangecfg.ScrapeConfigs{c[v.JobName]=v.ServiceDiscoveryConfigs}returndiscoveryManagerScrape.ApplyConfig(c)},}
那下面就从discovery/manager.go
中定义的ApplyConfig()
方法分析。
1、根据配置注册provider:
forname,scfg:=rangecfg{//根据配置注册providerfailedCount+=m.registerProviders(scfg,name)discoveredTargets.WithLabelValues(m.name,name).Set()}
其中关键的是m.registerProviders(scfg, name)
,继续跟踪:
d,err:=cfg.NewDiscoverer(DiscovererOptions{Logger:log.With(m.logger,"discovery",typ),})
2、然后将所有注册到m.providers
数组中的provider
进行启动:
for_,prov:=rangem.providers{//启动服务发现实例m.startProvider(m.ctx,prov)}
跟踪到m.startProvider(m.ctx, prov)
方法中:
updates:=make(chan[]*targetgroup.Group)//执行run 每个服务发现都有自己的run方法。gop.d.Run(ctx,updates)//更新发现的服务gom.updater(ctx,p,updates)
发现这里主要是启动两个协程,它们之间使用updates通道类型变量进行通信。
总结来说(见下图):
1、每个Config
都会对应创建一个Discoverer
实例,并被封装到provider
存储在m.providers
数组中;
2、然后遍历providers
数组进行启动操作,启动操作启动了两个协程:
a、Discoverer.Run
协程逻辑中主要根据发现协议发现targets
;
b、然后通过通道传递给discovery/Manager.updater
协程中,将其存放到m.targets
集合map中;
配置处理这里还有个比较关键的:Discoverer
会根据不同协议实现发现target
,它是如何实现的呢?
首先,我们来看下Discoverer
实例创建:d, err := cfg.NewDiscoverer()
,它是一个接口定义:
typeConfiginterface{Name()stringNewDiscoverer(DiscovererOptions)(Discoverer,error)}
每种服务发现协议都在自己的SDConfig
中实现了各自的NewDiscoverver()
方法,这样就可以将服务发现逻辑封装到Discovererver
实现中:
discoveryManager组件
上节《Prometheus启动流程》一节分析过会启动discoveryManagerScrape
组件通过通道将targets
数据信息传递给scrapeManager
组件(见下图):
1、discoveryManagerScrape
组件启动入口:
g.Add(func()error{err:=discoveryManagerScrape.Run()level.Info(logger).Log("msg","Scrapediscoverymanagerstopped")returnerr},func(errerror){level.Info(logger).Log("msg","Stoppingscrapediscoverymanager...")cancelScrape()},)
2、一直跟踪会进入到sender()
方法中,配置处理模块说过,有个协程会将Discoverer
组件发现的targets
信息存储到m.targets
集合map
中,然后给m.triggerSend
发送信号,sender
方法中就是启动定时周期触发器监听m.triggerSend
信号:
func(m*Manager)sender(){//周期性定时器定时触发任务,这里是5s触发一次ticker:=time.NewTicker(m.updatert)deferticker.Stop()for{select{case<-m.ctx.Done():returncase<-ticker.C://Somediscovererssendupdatestoooftensowethrottlethesewiththeticker.select{case<-m.triggerSend:sentUpdates.WithLabelValues(m.name).Inc()select{casem.syncCh<-m.allGroups():default:delayedUpdates.WithLabelValues(m.name).Inc()level.Debug(m.logger).Log("msg","Discoveryreceiver"schannelwasfullsowillretrythenextcycle")select{casem.triggerSend<-struct{}{}:default:}}default:}}}}
监听到m.triggerSend
信号,则执行m.syncCh <- m.allGroups()
,我们来看下m.allGroups()
干了什么?
func(m*Manager)allGroups()map[string][]*targetgroup.Group{m.mtx.RLock()deferm.mtx.RUnlock()tSets:=map[string][]*targetgroup.Group{}forpkey,tsets:=rangem.targets{varnintfor_,tg:=rangetsets{//Evenifthetargetgroup"tg"isemptywestillneedtosendittothe"Scrapemanager"//tosignalthatitneedstostopallscrapeloopsforthistargetset.tSets[pkey.setName]=append(tSets[pkey.setName],tg)n+=len(tg.Targets)}discoveredTargets.WithLabelValues(m.name,pkey.setName).Set(float64(n))}returntSets}
其实就是将m.targets
数据发送到m.syncCh
通道上,所以,discoveryManager
组件比较简单,就是一个搬运工。
scrape组件
scrapeManager
组件启动:scrapeManager.Run(discoveryManagerScrape.SyncCh())
,通道syncCh是被scrapeManager组件持有的,跟踪进入Run方法中:
func(m*Manager)Run(tsets<-chanmap[string][]*targetgroup.Group)error{gom.reloader()for{select{//通过管道获取被监控的服务(targets)casets:=<-tsets:m.updateTsets(ts)select{//关闭ScrapeManager处理信号//若从服务发现(serviceDiscover)有服务(targets)变动,则给管道triggerReload传值,并触发reloader()方法更新服务casem.triggerReload<-struct{}{}:default:}case<-m.graceShut:returnnil}}}
通过case ts := <-tsets
获取到syncCh通道上传递过来的targets数据,然后调用m.updateTsets(ts)
将targets
数据存储到scrapeManager.targetSets
中,然后给m.triggerReload
发送信号。
这个方法中go m.reloader()
启动了一个协程,进入reloader()
方法中:
func(m*Manager)reloader(){//定时器5sticker:=time.NewTicker(*time.Second)deferticker.Stop()for{select{case<-m.graceShut:return//若服务发现(serviceDiscovery)有服务(targets)变动,就会向管道triggerReload写入值,定时器每5s判断一次triggerReload管道是否有值,若有值,则触发reload方法case<-ticker.C:select{case<-m.triggerReload:m.reload()case<-m.graceShut:return}}}}
也是通过定时周期触发任务监听m.triggerReload
信号,执行m.reload()
将targets
加载进来。
总结
前面分析了服务发现运行机制,可以看下面图梳理下前面流程逻辑:
标签:
为您推荐
广告
- 【prometheus】-02 一张图彻底搞懂Prometheus服务发现机制
- 内网通是什么软件 今头条
- 世界热文:汪峰做亲子鉴定,章子怡人设崩塌?
- 北京高校大学生创业园(沙河园)揭牌
- 葡萄糖有什么作用和功效_葡萄糖有什么作用|全球新资讯
- 全球快资讯:江化微:3月22日融资净买入417.4万元,连续3日累计净买入1380.43万元
- 新中国首次参加奥运会的时间是哪一年
- 酒精消毒的适用范围是什么(酒精消毒的适用范围)
- 一到晚上就咳嗽的厉害是什么病_一到晚上就咳嗽的厉害是什么原因
- 环球速讯:关于感恩父母的语句_关于感恩父母的诗歌
- IN视频|全长1320米 深圳黄木岗交通枢纽下沉隧道正式通车-每日热讯
- 2015年11月17日黄历
- 世界快报:疯丫头杜真子漫画_疯丫头杜真子
- 环球热门:第三家美国银行快崩了,华尔街出手也没用,2008年的恐惧卷土重来
- 红米Note11T Pro十个月使用体验,如今降价500还值得入手吗?-全球视讯
- 库库雷利亚:世界杯时就喜欢阿根廷24号,之后恩佐就加盟了球队_今日报
- 【环球时快讯】石家庄市财贸工会为家政行业女工送关爱
- 江苏园博园建设公司9.5亿元私募债状态更新为“终止”-今日最新
- 隔夜外盘:美股三大指数收高 银行、科技股普涨-当前最新
- 程序员20岁吃青春饭,35岁以后怎么办?
- 1惨淡!2月法系车销量盘点,总销量仅4755辆,只有2款车超3百辆
- 2世界看点:仁度生物: 首次公开发行部分限售股上市流通公告.docx
- 3天天通讯!中俄会晤当天,美两次请求与中方通话,称正安排两大代表团访华
- 4江西一店员打包拿错衣服,隔天顾客找上门不退差价:不要衣服就走 世界速递
- 5上海义务教育学校课后服务100%全覆盖!精准定位减负,提供个性化体验
- 6无主灯 有沐光——沐光无主灯品牌发布会暨全国首家旗舰店开业盛典谢幕
- 72023年天津最低工资多少钱一个月_天津最低工资标准2023最新调整是多少
- 8山里有群护松人
- 9暗黑破坏神4》法师词条选什么?法师职业装备词缀推荐速参考具体是什么情况
- 10普通话考试最后一题万能模板朗读_普通话考试最后一题万能模板
- 1CBA最新积分榜:稠州稳居第一,上海4连胜,广州双杀同曦-全球看点
- 2正弦电气核心技术人员杨志洵、梁克宇、张强离职 全球新动态
- 3世界快资讯丨MFS投资管理:预计美联储本周将继续加息,但不确定性仍存 ;
- 4北京明天扩散条件仍较差 周三又将迎来风沙
- 5重点聚焦!2023年中国联通四川省分公司校招
- 6微动态丨华泰证券:GPT大语言模型有望重塑数字世界入口 看好后续国内应用落地
- 7“双减”后课余生活做减法更做加法!上海盘活校外教育资源供给链
- 8贵州一煤矿发生煤与瓦斯突出事故致5人被困 救援仍在紧张进行中 天天新消息
- 9冬至快乐英语怎么说_赶紧来看看吧 当前通讯
- 10天天信息:中国蓝经济观察丨“空箱堆港”到底怎么了?
广告
- 环球快资讯:Imp鞭尸UZI!向女粉炫耀:UZI和我打BO5,他一次都没有赢过
- 精选!陶红是谁的前妻_陶红的丈夫是谁
- 上海二手房成交活跃,以价换量是主流 当前动态
- 焦点快播:大风降水降温!河南小麦浇水打药先暂停,是“治愈”还是辛苦?
- 黄脚胡蜂图片_黄脚胡蜂
- 天天热文:如何使用格式工厂将mp4转换成mp3?
- 火箭若抽签失利或向下交易,哈金斯轰34+5难续约,马丁在场输27分|全球讯息
- 到处的拼音怎样拼_到处的拼音 观察
- 难忘的元宵节300字作文_难忘的元宵节
- 西郊线开启“桃花观赏季”模式
- 这个加工投资不大,原材料不值钱,虽不暴利,但前景好,适合在农村长期干-快播报
- 卧虎藏龙贰手游官网_卧虎藏龙贰
- 字节跳动再缩边界,聚焦信息平台和电商两大主业|钛快讯-今日热门
- 全球微头条丨世卫组织更新新冠病毒变异株的跟踪系统和工作定义 新冠第二波高峰期时间(今日/头条)
- 即时焦点:保湿水和爽肤水的区别是什么呢_保湿水和爽肤水的区别
- 天天观察:王俊凯个人资料_说一说王俊凯个人资料的简介
- 2023年金山区财政审计税务工作会议召开|头条
- bigbang解散了么_bigbang解散_每日焦点
- 科翔股份(300903):3月16日北向资金减持39.24万股
- 曾被那英疯狂追求, 章子怡跪求提携, 退出娱乐圈下海经商身价上亿