《凤凰网:基于服务树的监控系统实践》要点:
本文介绍了凤凰网:基于服务树的监控系统实践,希望对您有用。如果有疑问,可以联系我们。
kun:凤凰网运维开发,负责公司运维自动化平台设计开发,InfluxDB contributer、open-falcon contributer 、golang爱好者.
说到监控,大家肯定能列举不少,zabbix、nagios、open-falcon、Prometheus等.凤凰网和其他大多数互联网公司一样,一开始选择了开源的zabbix来做为公司的监控系统.就这样,相安无事,多年过去了.随着公司服务器的不断增长,我们遇到了一些难题:
相信第一个问题很多体量稍大的公司都遇到过,大家用得最多的一个解决方案是拆分zabbix,部署多套来分担压力.但是后端查询过慢的问题没有从根本上解决,而且增加了维护成本,考虑到zabbix后端是c语言写的,二次开发有一定难度,于是我们打算自己造个轮子.
先简单介绍下几个概念:
服务树:某些公司为了方便管理服务集群,利用树形结构建立起了一种服务组织关系,方便集群 服务治理,以服务集群节点为管理单元,而不是某台机器.
Open-Falcon:是小米开源的一套分布式高性能监控系统,支持服务树管理.
有人可能会问,你们为什么不直接用开源的 open-falcon ,不得不承认, open-falcon 的某些设计还是非常不错的,我们也从中学习了很多思路.但是由于小米公司当时没有开源出结合监控的服务树,我们不得不自己设计一套适合自己,也可能适合你的服务树.
基于服务树,我们可以更方便的管理自己的服务, 服务树是整个监控系统的基础服务,后来我们开发的发布系统也是基于服务树实现的.基于 golang 的运维友好性和高性能,整个服务树是用 golang 实现的,对于新手来说,上手难度也不高.服务树架构图如下:
服务树架构图
考虑到服务树(service registry)组件的重要性,架构上一定是高可用的,于是我们底层数据存储 store 层多实例是基于 raft 算法保证数据一致性的,最底层是用了 boltDB 来存储服务树的数据,另外为了提高服务树的读性能我们还为 store 层添加了支持 lru 算法的 cache 模块, cache 结构体如下:
// Cache implements a non-thread safe fixed size LRU cache. type Cache struct { mu sync.RWMutex count int evictList *list.List items map[string]map[string]*list.Element size uint64 maxSize uint64 enable bool logger *log.Logger }
在启动服务树的时候,我们可以指定服务树开启的内存大小,现在我们开启了 50M , 效果还是非常不错的.
如果你启动了 3 个实例,正常情况下 raft 底层是有一个 leader 和两个 follower 的,写操作必须落在 leader 上才能成功,很多开源软件也都是这样的,但是这样服务树就有状态了,对于用户提交数据不是特别友好.
于是我们在 cluster 这一层会做判断,如果进来一个写操作,直接尝试本机,如果失败了,再把请求转发到 leader 上,底层帮助用户做数据转发,这样用户不用关心那个是 leader ,3台对他来说是一样的,前端加个负载均衡可以随便接受请求了.
在这里我们底层还做了一些工作,就是把 cluster 监听的 TCP 端口和 raft 数据同步的端口复用,这样,用户的配置也就精简了.
另外服务器可以根据一定策略自动注册到服务树上的某个服务节点当中,机器,报警,权限在服务中都是一种资源,这种资源都有增删改查的操作,对于服务树来说这些没有什么区别,只是人定义了它,服务树中一切皆资源,后期扩展极为方便.
zabbix 很大的一个问题就是用结构型数据库来存储了时序性数据.考虑到整个监控系统的配置数据和监控指标数据是有不同特点的:
可以考虑把监控配置数据抽象城资源存储到服务树中,保证数据可用性,而对于监控指标数据可以存储到时序性数据库当中,开源的有 OpenTSDB、InfluxDB、Prometheus等.
业务上有越来越多上报打点需求,我们可以考虑从 agent 端开放出接口,把业务上报的数据作为普通数据一起打包入库,这样也复用了监控系统数据传递的整条链路,同时降低了系统维护难度.对于一些标准的基础服务采集,我们采用插件的方式来实现,在 zabbix 中叫模板,比如 nginx 的一些指标, mysql 的一些指标等.
设计需求分析完了,关于凤凰网的监控架构,我们先上架构图:
服务器通过拉取服务树的用户配置采集策略,通过部署的agent进行监控数据采集上报,每个IDC内部会有一个消息队列防止公网传输延迟或丢数据,数据会进入消息队列,然后会有router模块负责把数据写入到InfluxDB中.
由于InfluxDB已经闭源了集群功能,为了保证后端数据的高可用,我们通过router进行多写.受限于大量的写入请求,我们通过router对后端InfluxDB做了分片,这样当后端某个db出问题时,不至于影响其他服务数据写入和报警.
报警我们用了开源的kapacitor,为了提高用户易用性,我们围绕它做了一些改进,也在支持了监控指标的无值监控.
InfluxDB是一个时序数据库,为时序数据而生,它新版的TSM存储引擎性能非常好,数据压缩做的非常好.
举个例子,2000台左右服务器,100天数据占用400G空间.面对10s级别的上报采集频率,这个成绩是非常不错的.
目前,监控系统大部分监控项是10秒级的上报粒度,InfluxDB的每秒写入5w.每天入库的数据点10亿.
agent原生支持Windows,开源社区支持linux做的比较好,但是我们公司有些微软的服务(exchange)是windows服务器,于是我们做了很多工作来原生支持win系统,
支持windows的相关源文件
支持第三方打点上报,方便开发接入监控系统,我认为这个已经是现在监控系统的标配了.
监控上报
插件库支持丰富,得益于开源社区,支持插件监控,拥有完善的插件库
相关插件
更优化的图像展示速度,在长时间跨度查询的时候能够做到快速展示, 支持grafana展示 (原生支持)
仪表板显示
支持自动注册,服务器根据主机名自动注册到服务树相应节点,根据节点的配置自动采集和报警
新节点注册
更优化的agnet,agnet的安全性和性能是我们非常关注的问题,我们尽可能降低agent的资源消耗(mem.used<30MB cpu.used<1%),为此我们还砍了一些采集项.
内存占用率
CPU占用率
支持分级报警,方便值班人员看到正在发生的报警,每个报警持续的时长,以及是否恢复.
报警DashBord
灵活的机器管理,你可以看到当前机器有无报警,机器状态是否online,如果机器维护可以随时设置为维护状态,屏蔽这台机器的所有报警,专注于处理问题.
机器管理
回到文章开头遇到的问题,我们借助于现有的开源时序数据库,大量监控数据的写入和读取已经不是问题了.
服务树的出现可以更好的帮助运维人员管理自己的服务集群,同时我们在 agent 端开启了一个 unix domain socket 用于本机的业务上报,这是一个异步接口,不会阻塞请求,甚至可以把监控平台看成是一个开放的消息总线,通过这个上报接口,给了自己和他人一个无限可能.
未来的监控系统肯定会更加智能,这也是最近比较火的“AIOPS”的一部分,运维监控系统拥有大量的监控原始数据却没能发挥它的价值,通过分析这部分数据我们可以挖掘很多潜在的有价值的信息,从而降低运维成本,提高运维效率,这部分数据甚至可以通过人工标注后进行机器学习,这样监控系统就可以不用设置报警策略来进行报警了.
机器学习、人工智能的盛行给运维工作带来更多畅想和变革,这也是我们正在努力的方向.
转载请注明本页网址:
http://www.vephp.com/jiaocheng/1947.html