报警分发系统:https://github.com/smartxff/dingding_exporter 既然是上篇博客的实现结果,就以上篇的需求为主体结构来进行实现过程的说明和总结
1. 报警输入标记
控制自己的东西,永远比控制自己简单。报警消息发送过来时,只会告诉我那个实例有问题,有什么问题,至于这个实例属于谁,它并不关心。所以发送过来的告警所在的实例属于谁这件事,就得我自己程序实现了。毕竟控制自己简单嘛。
2. 获取报警
报警的获取来源是prometheus的alertmanager。它会发送给我一个固定格式的json,然后我可以从这个json中获取,报警信息。至于其他非prometheus的告警,我怎么获取呢?只要他发送我的消息满足这个json的部分字段,我就可以处理他的报警。所以此部分是以固定格式的请求body来实现复用。
3. 获取报警与接收人对应关系
因为我们prometheus主要的监控来自于docker上跑的服务的url,我们会进行探活,而每个docker的项目的源代码都来自于gitlab。所以报警和接收人的关系就来自于gitlab了。毕竟每个项目都是由创建者和修改着构造的。但是一个gitlab项目不仅可以属于某个人,也可以属于某个组,我肯定不可能给一个组的人都发送报警。我肯定会被打死。我们提交代码时都会commit。但是这个commit属于提交代码时的本地环境。本地环境和线上环境可能不同步,比如你gitlab中叫张三,你本地叫sanzhang,那么commit里面保存的就是sanzhang。所以从commit中获取接收人信息就pass。虽然commit里面的信息不是gitlab上的,但是push代码这个event,事件本身是属于线上本身的。所以我们的报警总会发送给最后一次提交代码的人。简直相当完美呀。我们prometheus除了监控docker里面的项目,还监控了一些手动加上的监控项,比如某个外网url之类的。我们只能通过读取本地对应关系表中的数据,来查找对应关系。此处试用yaml格式存储这些数据。然后没找到对应关系的报警会发送到我们运维所在钉钉群中,我们收到后可以选择手动添加对应关系,和我们自己处理报警。此处算是实现了需求分析。
4. 根据标记和对应关系发送报警
用户基本上就使用两种接受信息的方式,一种是短信,一种是邮件。邮件还是比较好实现的。钉钉群的机器人接口使用特别方便,所以测试阶段以及我们运维接受报警主要使用钉钉群。邮件实现的比较简单,总体内容固定,只有内容和发送对象不同。钉钉因为我们自己使用,我实现的功能就更多一点。首先有一个默认的钉钉接口,主要接受没有匹配的接收人的告警。然后可以通过配置文件自定义哪个实例的告诉发送到那个钉钉群。
其他实现
有些告警信息一时半会儿处理不了,但是prometheus我们设置的同一个报警10,如果未处理10分钟发送一次。所以此处我加入了告警过滤的功能,当然也是以配置文件的形式实现。 钉钉群接口每分钟只能向它发送20次消息,超过这个数,此接口就会失效,必须手动生成新的webhook。所以我打算在钉钉发送消息这上面做一个限制,每分钟最多只能发送20个消息。目前还没实现,不过具体的思路已经有了。创建一个长度为20的chan,没收到一个发送钉钉告警的请求,就起一个goroutine,从chan中获取一个值,然后发出一个钉钉告警消息,sleep 1分钟后在往chan中发送一个值。就算一秒钟发送20个请求,chan里面的值为空,下一个请求,就会一直等待chan中的有值。只有超过一分钟后,其中一个gorutine给chan发送一个值。下一次请求才可执行。此处有点滥用chan的感觉。不过嘛,优秀的程序员都是从写烂代码开始的~~~
不知道自己代码烂 知道自己代码烂,不知道为何烂 知道自己代码烂,知道怎么写好 代码已经能写好,不知道怎么写更高性能的代码 代码能写好,也能写高并发,并且高可用,无状态。 那么,我就算是成为一个合格的程序员了。 加油!