十年•杭研技术秀 | 企业级监控系统实践(上)

社区编辑2018-05-15 17:30

2016年对于网易杭州研究院(以下简称“杭研”)而言是重要的 – 成立十周年之际,杭研正式推出了网易云。“十年•杭研技术秀”系列文章,由杭研研发团队倾情奉献,为您展示杭研那些有用、有趣的技术实践经验,涵盖云计算、大前端、信息安全、运维、QA、大数据、人工智能等领域,涉及前沿的分布式、容器、深度学习等技术。正是这些宝贵的实践经验,造就了今天高品质的网易云产品。本文的分享来自杭研运维团队,结合网易杭研的实践解析了现代化的企业级监控体系的构建。

随着企业IT设施以及应用部署复杂度越来越高,监控也就变得越来越重要,从各个运维大会涉及的监控相关的主题就可见一斑。随着业界运维以及开发技术的发展,监控也由原先的简单的服务器指标的监控,逐步拓展到应用性能、网络、手机设备、前端页面等多个领域。业界开源监控也有了Zabbix等产品,商业化解决方案也有听云,OneAPM等。但是开源和商业化方案,与企业内部的实际情况以及集成度不完全匹配,并不能完全满足面向复杂业务逻辑企业的需要。网易对企业级的监控系统也做了一些有效探索和实践,本文通过网易的监控实践,描述监控体系的建立过程,以及如何逐步满足一个企业级监控的需求。


本文分为上下篇,上篇内容包括:

CMDB体系的建立

基于模型的监控体系

监控数据存储,可视化和数据处理

服务器和网络设备监控


下篇内容包括:

应用性能监控以及业务监控

统一Agent

流式监控以及终端设备监控

分布式跟踪系统以及日志分析

统一应用配置中心与应用管控

企业级监控未来的发展趋势


一、CMDB体系的建立



一个企业需要一个CMDB系统来记录各种配置信息,同时也定义了各种监控的对象,这些信息包含服务器的信息、网络设备的信息、VIP信息、应用程序的基本配置等等。



1、服务器设备信息

服务器信息包含物理机和虚拟机的信息。通过在服务器设备上植入Agent,自动采集CPU、内存、网卡、IP地址等服务器基本信息,同时也定期执行相关的监控脚本采集监控数据。



2、应用配置信息

服务器信息有了,为了给线上业务使用以及后续监控,我们定义了如下概念:

应用

应用是对功能和代码的描述,比如电子商务的下单的业务逻辑的应用程序,应用具有类型属性,比如Java应用、C++、Python、数据库类型等。一个应用由于配置不同区分为多个环境,比如测试环境、预发环境、线上环境等,这里的环境我们称之为集群。

集群

集群是应用监控的基本单元,一个应用下的多个集群一般共用一份代码,只是配置和部署方式不一样。

集群服务器

集群建立后,可以将服务器加入集群,一台服务器可以根据使用的方式加入多个应用的多个集群,比如在资源紧缺的情况下,一台服务器可以为多个测试环境使用。这样的组织方式就既可提高资源利用率,同时也可以满足监控需求。

多实例

有一些场景下,一台服务器部署相同的多个进程,每个进程称之为一个实例。



上述的应用、集群、服务器、实例组成了服务器以及应用监控的基本对象。



3、机房信息

记录机房的位置信息、机柜信息、IP地址段信息等等利于监控的全局拓扑的建立。



4、网络设备以及网络拓扑配置

将网络设备信息录入或者采集进入CMDB体系,为后续网络设备相关的监控打好基础。对于网络设备通过Agent远端执行采集逻辑实现监控。



5、无线应用配置信息

随着无线应用的兴起,将无线应用定义在CMDB也利于后续的终端监控。无线应用也可以分为Android、iOS等多种类型。



6、VIP配置信息

VIP的监控也是通过Agent远端探测实现,首先VIP需要定义在CMDB系统才能实现监控。



7、人员信息

将企业的人员信息进入CMDB系统,利于对监控对象的权限的控制。


二、基于模型的监控体系



CMDB定义了监控对象之后,为了实现不同对象的监控需要建立统一的监控体系来实现,这个体系需要满足基本监控需求,也需要具有扩展性,支持未来潜在发展需要。网易监控系统主要通过建模的方式来定义数据的规范,在此基础之上建立监控数据的采集、存储、报警、处理、可视化的规范。



1、采集器

采集器定义了监控数据的采集方式以及数据模型。采集器目前分为如下几种:

脚本采集器。主要用于服务器监控,采集器定义采集执行的脚本以及输出的数据模型。

外部采集器。用于采集VIP数据、外部探测数据,也包含采集的脚本和输出的数据模型,与脚本采集不同的是他是由第三方的Agent(Super Agent)执行采集。

Java应用采集器。主要定义数据的模型信息,实际采集的时候通过基于Java Agent技术的探针来实现。

被动采集器。主要用于在流式处理的时候定义处理的方式以及处理后数据模型。



2、数据模型

数据模型包含在采集器当中,一个采集器可以包含多个数据模型。一个模型代表一个采集的点,比如CPU的数据。一个数据模型包含多个字段,每个字段都定义自己的数据类型。字段的数据类型包含主键和非主键两大类。比如一个system的采集器,下面包含CPU、if_traffic、Memory等多个数据模型,分别描述CPU、网卡流量、内存使用的监控。这一些数据是一次采集上来的,另外比如if_traffic模型,包含ifname、inbps、outbps等字段,其中ifname是网卡名字,是主键数据类型,inbops和outbps是网卡的流量信息,是非主键类型。

定义数据模型的优点是定义了数据上报的规范,也为数据存储、报警表达、数据处理等提供了元数据的支持。这为实现监控的规范化,多样化打好了基础。数据模型化是网易监控系统的最主要特点。



3、 监控项以及监控模板

定义了采集器之后,将采集器加到集群后形成监控项,监控项代表了这个集群需要运行相关的脚本采集监控数据。监控项可以直接加在集群上,这样有可能造成重复添加,比如每个集群的服务器都需要采集CPU信息的。为了解决这个问题,我们引入监控模板,将监控项加在模板上,模板上配置适配规则,这样就大大减少了配置,同时也能满足复杂配置需求。比如基础监控模板定义了基本的系统指标,适用所有的集群。那么只需要定义这么一个基础模板就可以将监控项加到所有的集群上。用户也可以定义满足自己需求的模板。



4、报警

有了数据模型之后,就可以针对采集的数据定义报警规则,报警规则可以通过报警表达式来描述,比如inbps>100. 报警规则根据场景可以分为如下几种:

单机报警: 每当单机采集一笔数据就根据报警表达式求值,满足条件就报警。比如对于磁盘的监控:await >= 1000 || util >= 100。

集群报警: 对于一些业务数据需要针对整个集群的累计值进行报警,为了实现这个功能首先需要实时汇聚出集群的监控数据,之后可以设置集群表达式进行报警。比如:orderCount.sum >= 1000代表集群总的下单量大于阈值就报警。

累计值报警:前面两个都是针对当前值进行报警,有的时候需要对前面多个采集间隔的汇总值进行报警,通过设置表达式,然后通过定时器定期扫描数据也可以实现报警。



报警触发之后,发送报警内容给用户,如果报警状态不变,可能用户持续收到报警。通过对报警设置抑制可以用户收集的报警。有几种抑制方式:

次数抑制,当连续几次满足报警条件才报警。

时间抑制,多少时间之内只发送一次报警。

集群抑制,集群之内多少主机报警只发送一条。

模板抑制,在一定的时间范围内才发送报警。



5、监控项状态

当发生报警之后,监控对象就应该处于一种状态,用户查看状态就可以看到系统存在的问题。状态分为:pending – 数据未采集;error – 采集错误;warning – 触发warning表达式;critial – 触发critical表达式;OK – 采集正常。同时状态也分为单机监控项状态,集群监控项状态,VIP监控项状态等等。


三、监控数据存储,可视化和数据处理



针对监控的采集数据进行建模之后,明确了数据的采集和组织方式,为数据的存储和可视化以及数据处理提供了基础。



1、监控数据的存储

监控数据是时间序列的数据,由于监控的对象数量巨大,所以存储的介质需要支持高的写入吞吐量,良好的扩充性,读取最近的数据速度要快,支持多数据类型,支持多种扫描方式等特点,目前主要的存储方式有SQL和NoSQL两种。通过对比,NoSQL在数据存储吞吐量,扩充性等方面具有优势,SQL在数据类型的支持,扫描多样性具有优势。总体而言NoSQL存储系统相比SQL系统更具有性能上优势,劣势可以通过其他方式弥补。所以我们采用HBase来实现基于时间序列的监控数据的存储。通过模型的变化来支持存储单机的,集群的甚至基线数据存储等。



2、数据的可视化

数据模型定义了数据的存储格式,也为监控数据可视化的引擎提供了可行性。通过提供一种类似SQL的查询引擎EQL(Event Query Language)来驱动数据的可视化是一种满足多方面需求并且是可扩充的方式。下面描述了数据的可视化主要的几种方式:



最近数据表格:展示最近的一笔监控数据,比如磁盘的容量监控。EQL简单的语义描述:

create view

type= latesttable

objectId= myapp

model = system.disk

aggrFun=last(free_pct) as 剩余, last(used_pct) as 已用

enumFilter= path in (path1,path2)

groupby= path as 路径

汇总数据表格:用于展示一段时间之内的汇总值,比如最近一个小时所有的方法调用的汇总,用表格方式展示并且排序,并且点击某个方法可查看某个方法的调用趋势,平均RT等。

趋势图:一段时间之内某个数据项的趋势走向。

对比图:跟过去某个时间的对比的趋势图。

饼图:一段时间之内数据占比的百分比饼状图。

区域图:监控数据在各个区域的分布图,这个适合用于手机客户端或者前端的监控。

散点图:对于一些原始数据抽样图。

通过不断的扩充查询语言来提供更多的数据展示方式,这样就可以大大提高视图的可重用性,减少开发,提升数据可视化的效率。在数据展示的时候可以采用插件化的展示体系,那么可以将数据植入第三方应用,提高监控数据的开放度。



3、数据的处理

监控数据的处理,主要包含如下几种:

数据的聚合。需要实时将单机数据聚合成一个集群的汇总数据,一方面可用于集群报警,另外一方面可以提高查询集群视图的效率。

数据的归档。监控数据的原始采集间隔一般比较小,比如分钟级,那么展示长时间的数据的视图需要扫描过多数据,展示比较慢,如果将数据归档成按小时,和按天的数据,那么展示时间跨度大的数据的效率大大提高,另外也可以实现长时间跨度报警。

多维度流式聚合。可以按任何维度,实现更复杂的数据聚合,比如计算某个产品的所有主机的CPU使用效率。

四、服务器和网络设备监控



上面的章节建立了监控的基本体系,由于服务器和网络设备在企业中数量众多,所以服务器和网络设备监控是首要解决的监控方式。



1、服务器监控

服务器在安装上Agent之后,首先连接监控的服务,注册自己,然后在CMDB系统中将当前服务器使用到应用和集群之中,并且添加相应的监控项。接下来服务器连接统一的配置中心获取需要在机器执行的监控项,监控项包含了需要执行的脚本,以及执行周期。Agent收到监控项之后周期执行脚本,并且上报执行的结果数据到监控服务器端,服务器端对数据进行存储和报警。脚本的输出需要按照采集器定义的规范,例如:



==CPU

no=1,usr=0.2,idle=0.3

no=2,usr=0.3,idle=0.5

==if_traffic

ifname=eth0,inbops=1234,outbps=234

ifname=eth1,inbops=233,outbps=678



2、网络与监控域

一个企业的网络问题是错综复杂的,为了实现监控,首先所有的服务器能够连接到统一的注册中心,并且维持连通状态,这个中心我们称之为Master。然后所有的服务器可以根据网络情况,划分监控域,每个域设置监控服务器,每个域的服务器将监控数据发送到当前域的监控服务器,进而转发给存储和报警中心,实现服务器的监控。同时每个域可以设置Super Agent,执行外部探测任务。网络问题也是一个企业实施监控的重要方面。



3、主机存活监控

一般的服务器监控通过执行脚本上报监控数据触发报警表达式报警。但是如果一台服务器down了,用这种方式就不合适了。用于判断主机存活的监控项与一般的监控项应该不一样,通常有两种方式:一种是根据常连接判断,当Agent失去与服务器的常连接认为是机器down了,这种方式优点是及时,但是遇到网络问题容易导致大批量的报警;另外一种方式是通过Task来判断所有Agent的心跳和监控数据,如果两者都不上来,可以结合总的数量来判断本机是真的down了还是网络问题。



4、VIP监控,网络设备监控,外部探测监控

一般的系统监控是在本机上执行脚本,但是对于其他的一些监控对象,比如VIP、网络设备,以及外部探测的情况,需要其他的服务器执行相关的脚本,比如ping。我们在各个监控域安装了Agent的监控机,我们称之为Super Agent,将监控任务下发到Super Agent,执行相关的脚本实现监控。监控域之间可以交叉方式实现监控,比如监控机房之间的ping延时。




——叶锋

网易杭州研究院运维部