运维监控管理的问题与价值
你是一名企业应用IT管理员,在一个阳光明媚的早晨,你兴匆匆的来到公司办公,你所运维的应用系统面向3000名用户,突然间系统的某一功能不可用了,抑或功能的性能变得非常差,无法满足用户的需求,用户投诉电话连连不断,上级领导要求尽快恢复并查明原因,你问自己为什么这异常一点征兆都没有,你确定昨天晚上什么也没做过,而且你很自信的对应用系统的构成非常熟悉,你尝试这在脑海里回顾可能的问题点,你召集了应用系统构成组件的运维管理人员,大家登陆到各自管理设备上将命令跑了一把,并且每一个人都回复“没有问题,一切正常”。一轮轮分析诊断下来终于找到了原因,挂载在主机上的某一个存储卷的访问响应时间突然变得非常慢。你看看了手表,大半天的时间就这么过去了,你再看看会议室中聚集的人群,还在疲惫的分析中。会议上领导狠狠的批评大家,为什么这么长时间才定位到问题?为什么没有做好应该做的监控?为什么没有相关数据趋势的对比?在为什么的背后是确实因为异常而造成了实际的业务损失,在一家全国领先的大型金融IT机构中,一个小小的失误,几分钟的中断都可能造成难以想象的经济损失。
我们对外部客户提供的是服务,服务的运行由各应用系统来支撑,而一个应用系统则由底层基础资源所构建,它们可能是一组运行在linux服务器上的weblogic进程,他们的权限认证由一个ldap服务器负责,系统域名则由一组DNS服务器来解析,它可能还会挂载nas存储卷,数据存储在后端的Oracle之中,这些组件的通讯还要经过中间的网络设备,可能会有交换机、路由器以及防火墙,这里我们仅仅考虑一个独立运行的应用。我们看到一个应用的健康运行与IDC很多组件都有关系,而这些组件的健康指标又有哪些呢?目前服务器的CPU负载是多少,历史高峰期又是度搜好,磁盘使用率是多少,网卡流量是否正常,内存使用率是多少,SWAP区域是否够用,打开文件数有没有超过限制,使用的网络端口数是否达到了极限?vanish缓存命中率是否正常?安全管理进程是否全部启动中?mysqlreplication是否同步了,数据是否一致?。这里仅仅是看一个OS以及其上的一些对象,一个OS是节点,一个大型IT公司IDC的监控节点数在10万以上,而作为健康指标的监控项会很轻松的突破千万。
监控管理的无形价值
运维岗位的价值体现在无形,不能出故障,不能出问题,在整个IT生态圈中要看不到运维的存在,这就是运维管理的最高境界,而“存在即合理”,看似不存在的也会看似不合理,也就看似没有价值,优秀的运维管理者以及技术人员处在一个极其复杂的矛盾中,但优秀的人员往往对事务的美好是有向往与追求的,他们会想尽一切办法驯服业务层面下的形形色色资源,如同压制妖魔鬼怪一样不断提升运维技能,他们仍旧会螺旋式的追求无形境界。在追求的过程中才能让他们满足。
要怎样才可以保证服务的质量?你可能会说高可用(highavailable),在十年运维生涯之中,我看过最复杂的高可用应用“架构”,应用服务从上至下都是双备、双活的,前端负载均衡是主备,应用层通过ejbcluster集群,主机网卡都是双网卡绑定,主备虚拟机存活在不同的物理宿主主机上,编制了特定的规则来严禁主备机器跑在一台服宿主之上。我们假设的前提是应用本身是无法承受任何错误的。在一个追求完美的高可用下,弊端自然而生,对于不同级别的应用底层资源的组成结构有很大的差别,为了识别、定制、客户化这些零散差异,底层资源的交付速度大大下降。完美高可用的架构下对运维管理的复杂度也会相应的提升,你可以说提前定义好所有的规则通过自动化来实现,应用对底层资源的要求差异化太大,标准化、自动化定制很难形成。高可用带来的另一个问题是运维成本的提升,在长年的运维经验中,终于明白了应用可用率的99.99%,为什么小数点后面的9位数越来月长,实现的成本会陡增。
保证服务质量与稳定性的另一个利器就是我们本章要的主题了,一套完善的监控平台。运维是IT价值中的无形,则监控是运维价值中的无形了。监控职能如同运维一样处在一个比较尴尬的位置,告警节点与告警项的维护本身就是一大难题,告警节点是否有遗漏,告警项是否合适,我们是否有足够灵活而快捷的监控平台帮助我们应对各种各样的监控节点,以及是否有一个快速而方便的接口让我们迅速从CMDB中导入监控节点。
告警监控职能与告警处理职能常常是分割的,我们将所有的告警类型集中起来由专门的人员负责,告警添加人、告警监控人、告警处理人,在一个不稳定、不灵活的监控平台下常常造成严重的误解。作为运维过一套品牌公司商业版的运维人员来说,我目睹过恶劣的告警风暴的来临,以及风暴来临之后运维人员为了清理这些垃圾告警而做得重复而繁重的工作,要在一个受到license限制的界面上一条一条的删除海量的误报信息是何其的无聊。告警处理人也会问告警监控人,我已经在处理了,请不要通知我,但告警在30分钟后还是报出来了,到底要不要处理呀。告警监控人也会问告警添加维护人,为什么你添加的告警是如此的不负责任啊,90%都是误报无需处理,如果真的有那么多特殊情况无需处理的话有没有办法提前注释条啊,你发版本停应用无需处理,你大数据分析导致内存高无需处理,实在是有太多的原因无需处理了,面对“宁可误报一千,不可错漏一个”的监控要求,对于优秀的运维人员来说,对于有追求的运维人员来说,一定要另辟蹊径,选择精细、精准化监控管理方式。
监控商业软件的选择
商用的运维工具能够一蹴而就的满足我们的期望吗?商业产品能够在短时间内满足我们的暂时性的需求,商业监控软件的购买不仅仅是购入了一套产品,还能够帮助我们领悟到一套监控管理的方法论,但随后而来的是什么?随着你监控内容、任务越来越明晰,对细节控制要求越来越高,商业软件此时的弊端也就尽显无疑。对于那些品牌公司的商业软件来说,我们还是在不考虑动辄几百万价格的产品、服务费用的基础上考虑问题。当你在招标采购时,所有的销售人员会告诉你他们的产品支持所有的监控内容,他们的监控系统是最强大的,一旦选型完毕,产品入住,你可能为了增加一个定制化的oracle脚本监控而被要求需要几十万的客户化费用,这又是另一条规则,IT人员的价值远远高于硬件、软件,当然是优秀IT人员,或者是一名普通的IT人员站在了封闭的软件系统之上。商用软件的最大弊端成本昂贵与定制化的不及时。前者可以通过避免品牌产品规避,而后者则更多的依赖于监控产品公司的技术实力,在产品设计时是否考虑到了足够的灵活性,是否采用公有协议而兼容社区插件,是否由一个强大的售后服务团队。
当我们需要对某对象进行监控时,我们可以选择超过上10种的方法,例如对Linuxcpu负载的监控,不同的运维人员可能通过vmstat、top、sar命令来达到目的,为了快速的完成我们的通知工作,我们会在脚本的末尾加上一句
echo "`hostname` your cpu loadis too high" | mail [email protected]
完成最后的告警通知工作,这是一种非常原始的监控手段,但对于一个基础的IT运维来说,这样一行脚本可能是他以后覆盖IDC所有监控的起始点,他会逐渐的扩大他的代码量,渐渐的开始规划他自己完整的监控平台,比如建立标准文件夹结构,包括bin、conf、lib,把所有需要的代码、配置文件、依赖库全部放进去,之后定义一些鲜为人知的规则,内创的MVC,优雅的面向对象接口实现等等,对于一个初级IT运维人来说这些场景确实是一个比较好的锻炼机会,在一天或一个月的时间内完成了自己对监控的理解。这样的监控实现方式也是程序员的“通病”,实现为王,能够跑起来再说,不关注问题的分析与设计过程。而实际上一套专业的、面向企业级的监控平台是经过过3~5年的运维经验后沉淀下来,并由一个团队来构建的。零散的将调度、采数、通知等动作积聚在一个脚本中的监控会让组织的运 维工作越来越复杂。
再回头看看监控的手段,我们可以通过哪些方式来获取监控对象的健康指标数据,监控与被监控对象是不在一个物理容器之内,监控主动方通过TCP/IP协议去抓取所需要的数据,对于网络设备,常常SNMP协议标准供我们使用,而服务器操作系统对象,则通常部署一套agent在其上,服务器上的Java进程,遵循JMX标准来抓取我们所需的内容。
行业内除了基础资源监控外,还强调应用监控,模拟真实用户发起访问应用系统,并确认他是否可用,我们会通过httpclient等开源组件封装一个模拟业务的http请求发起访问。但应用监控告诉我们的是出问题了,但具体在哪里出问题还要有底层资源来把持,端到端E2E(end toend)监控指的是覆盖应用所有组成资源各方面的监控,应用层是一个入口,在这个层面上的监控定制化需求更加强烈。
不要期望一个人、一个团队在半年内建立起一个完善的运维监控平台。它需要有丰富的监控经验来帮助我们明确监控需求与工具体系,通过需求来选择开源或者高性价比的商业化软件,同时监控工具要保持开放性,要不拥有API接口,要不有易读的源代码,运维团队使用这开放性来提升监控管理效率,做好二次开发。
好的工具让监控事半功倍,好的原则使告警巨细靡遗。IDC的基础资源告警会集中起来,将网络、服务器、应用等告警信息在一个终端输出。组织架构会设置专门的监控职能岗,7*24的对基础资源进行监控。所谓监控,乃监测与控制,器(工具)在于监测,术(原则)注重控制,再好的利器若未合理运用,就无法发挥其本有的作用。监控岗的原则是什么?没高深的道理,也无太多细则,记住四个词,Watching(监控)、Answer(响应)、Notify(通知)、Track(跟踪),总结起来就是WANT。 Watching(监控)。原则的最高级别,值班人员保证每隔5分钟扫一遍监控面板。 有人会觉得不够人性化,我们不是有手机吗?我们不是有APP推送通知嘛?为什么非得一直盯着面板呢?对于几十万的监控项,常常会出现扑面而来、连连不断的告警,邮件、消息类通知方式除非采用分散式专人专属,否则极易形成垃圾风暴,实际经验证明邮件、消息一般作为辅助监控手段。对于集中式监控管理方式,将网络、服务器、中间件等告警集中在一个面板,组织内会定义专门的监控职责,值班人员配备多屏,通过班次轮换,并行监控保证这个原则的执行。
Answer(响应)。 对于紧急度高、影响范围大、级别严重的告警要第一时间响应。 除了监控面板上显示的重要告警外,组织内还会定义重大问题处理流程,监控值班人员会从不同的渠道收到告警通知,例如紧急处理流程的邮件列表、上级或相关部门邮件等,值班人员收到邮件后都习惯性的先查问题再反馈,从内部看这种方式对问题处理的过程与结果无太大影响,但外部体验上会很差。
Notify(通知)。将有效告警通知到处理人,重大问题及时升级。 在集中监控下,监控和处理的职能并不在一个人身上,值班人员要对告警进行基本判断,这条告警是什么?是在发版本吗?是已知问题吗?过滤掉无效告警后通知到它的处理人。处理人的通知分为多种情况,有的通过监控平台关联事件系统,直接上报事件给后线工程师处理,有的则通过CMDB查到基础资源上的应用管理人员,邮件、电话告知处理。监控项与配置项是关联的,借助于监控平台上的“器”,将告警信息在面板上自动关联到监控组件的责任人,便于监控值班同事查找。 对于关键服务、系统,或者大面积异常的告警,要及时升级,将问题与现象第一时间反馈给上级,待上级决策。
Track(跟踪)。记录下待确认、未解决的告警,做好班次交接。 值班人员在班次内记录下所有待确认的告警,比如通知到某技术条线人员查看某设备,但对方未确认告警组件已恢复,或告知无需关注的,这类告警要记录下并转交给下一班次人员,直到告警恢复,或告警已转入了问题、事件管理系统中,有专人负责处理,并由流程保证告警问题被解决。
监控平台的需求分析
尽管已有了很多开源的监控平台工具供我们选择,如nagios、zabbix,但我们一开始先不进入到一个具体的使用过程,它们都是优秀的开源产品,但我不希望大家一下子就陷入到一个软件安装、配置的复杂过程中,我们先搞清楚自己的原始需求是什么,我们要一个怎样的监控平台,在明晰了自己到底要什么,再来选择合适的产品,会让我们后续的工作事半功倍。在附录中我们会对zabbix的具体使用进行详细介绍。
调度、规则和告警,一次监控过程
在实际的生产环境中我们要对weblogic Java进程进行监控,对linux服务器进行监控,还要对网络设备进行监控。那么我们先来剖析weblogic进程的监控过程。
监控程序按照一定的频率,遵循JMX标准向weblogic进程发起请求,请求的内容是weblogic的各项健康指标,JMX的mbean名称和属性则是这个指标,每一个weblogic进程有一批需监控的指标,例如线程数、heap大小等等,在将指标数据取回来后,我们先进行数据存储,以便以后查看历史数据,之后按照一定的规则来判断是否需要发出告警,告警的类型又可以分为邮件、短信、监控面板。除了发出告警,你可能还需要对现场信息进行收集,打一个threaddump是经常使用的方法。我们用一个图来描述我们这次监控的过程:
上图对一次简单的weblogic进程监控过程进行了说明,对于主机我们是否可以有同样的过程呢?监控程序发起对一个主机的监控访问,当然,主机会响应我们的请求吗?对于一般的网络ping、telnet操作会,但对于比较复杂层面的健康指标的请求会响应吗?比如当前打开文件数,当前每个磁盘IO的响应时间等,很可能不会,我们可以设计成ssh自动登陆将脚本嵌入到命令行发送给linux主机,我们也可以在主机上开发一个agent程序,接收我们的请求,并按照我们要求返回数据,不管怎样,我们也可以按照和weblogic的方式一样请求我们想要的数据,并且取回来后也可以存储到数据库中便于日后使用,数据的告警处理以及告警判断之后的预定义行为设置和weblogic监控是一样的。在确定主机和weblogic进程一样可以给予同一个模式进行监控后,我们试着提炼出参与这个过程的对象。
上图是我们尝试着从weblogic监控这个需求中提炼出来的类,我们逐一分析。
Job,我们提到这个类时,最开始想到的是发起一次监控访问,哦,不对,绝对不是一次。对于一个监控对象而言我们是要持续的对其进行监控,并且遵循一定的时间周期,比如每隔30s访问一次,既然出现了定时的、周期性的完成一批不同类别的Job,我们需要设计一个调度程序来完成这项任务。
对于每一个Job,我们周期性的发起监控请求操作,监控请求的处理时间需要包括在这个周期间隔内,我们的监控间隔是10s,一个监控请求的响应是2s,那么准确的应该是等待8s后再开启下次监控情况,而不是在程序请求结束完毕后使用sleep(10)循环这个监控请求动作。有两种意外情况会发生:1调度程序自身繁忙而错过了对一个任务的启动,这种情况是可能发生的,因为调度程序要将job分发给一个具体的执行线程处理,如果执行线程都在忙碌,则调度程序必须等待,一旦错过原来的调度时间,调度程序应将任务启动时间调整为当下,下一次任务的启动时间以当下为基准计算。2监控请求的过程可能会发生异常,监控请求的时间超过了监控周期,对于这种情况,调度程序也需要调整时间,避免重复启动程序,如下图所示
除了在错过正常调度时间后进行自我调整外,调度程序还要考虑到屏蔽时间,在设备维护、应用版本发布、定期批处理任务等时段,监控获取的数值会异常,但这些时间段的异常是允许的,因此调度程序对每一个任务要接收屏蔽时间段参数。
在Job的具体细节上,要一次性将所有的Item取回来,例如获取OS信息,一次将cpu、内存、磁盘信息全部获取,而不是发起多次访问。另外,对于需要认证的步骤,只做一次,之后缓存凭证,以便下次使用。Java的JMX访问如果每次都对远程用户进行认证,执行效率会大大降低,因此需要缓存subject凭证信息。在设计调度程序时,对于周期性访问要区分第一次和以后每一次的逻辑,要留存一个空间保存Job的全局性数据。最初所有的Job是存放在数据库中的,第一次加载后要按照Job的目标访问地址进行错开排序,这样做的原因是避免产生对同一目标地址发起并发访问,因监控而造成目标对象的性能损耗。
根据以上的论述我们需要一个调度程序(Scheduler),它依据一定的时间周期以及屏蔽原则(Timer),对各种各样的任务(Job)进行调度。
有大量开源调度库库供我们使用,在Java领域我们会使用quartz(http://www.quartz-scheduler.org/),它可以集成到我们的应用中,按照计划的时间点以及频度来执行任务。除了任务的调度与执行外,quartz从企业级架构上考虑设计问题,支持集群与事务。
Object,监控对象。我们希望这个监控对象能够涵盖所有的监控实体,有服务、主机、网络设备。实体之间的差别在于如何访问、采集监控数据,这是一种动作。这些动作又基于不同的协议LDAP、SNMP、HTTP,或者不同的规范框架之下,如JMX。在这里需要定义一个足够抽象的接口来掩盖具体的动作细节,我们定义poller方法来采集监控对象的数据,采集的监控指标定义在了Item中,因此Items会作为参数传入到collect中。在采集数据时需要建立连接并考虑是否需要保持住这个连接,在这里有一个连接管理过程。在Job中,对采集回来的数据是执行告警还是动作都是与Object关联的,Object等同于任务中的门面对象,对采集回来数据进行告警、以及回调诊断方法都将在这个类中实现。Object的实现类的复杂之处在于poller方法,就以JMX来说,与远程对象建立起连接的方式就有很多种,笔者遇到过复杂的情况有对weblogic的不同版本通过JMX监控,发起连接的client类名一致,但版本不同,最后在建立连接的动作中实现不同的类加载器才解决此问题。开源产品可以提供一个监控处理的方法与框架,但在细节层面上很难有一个产品的灵活性足够满足我们的需求,对于运维来说安装、配置、启动一个开源产品非常容易,但要驯服它,完全按照我们的思路运转则需要花费大量的精力,不管是开源还是商用,只有公开源代码并且具有对它足够的控制能力后才能自由的支撑起IT运维,对一个开源产品的二次开发需要专业的开发人员,在这里也在此强调了运维人员的开发能力。
Item,监控项,也就是监控对象自身的监控指标,每一个Item有一个独有名字,比如weblogic线程数,我们会将它取名为weblogic.10.jmx.thread.active.count,对这个名称加上别名,“weblogic10活动线程数”,我们还要定义监控项的值类型,是浮点、整型、字符型,对于我们获取的值我们将如何判断并处理,因此他必然关联上rule。Item还要携带一类有效数据帮助Object来collect,如果是JMX,他可能是mbean name,而对于SNMP,则是oid编码。我们要预留足够的空间给有效数据,它区分为静态与动态,我们以一个磁盘检测的Item举例,Item静态的是DiskUsageStats,磁盘使用率,它告诉Object对象在收集时获取什么类型数据。动态名称则一个具体的磁盘名称,例如/nfsc/im_core5,告诉Object具体采集哪个磁盘的,设计Item时考虑到各种问题发生的情况,有时候动态数据还是通过正则表达式实现的,比如/nfsc/im_core*,要检索所有符合正则表达式的磁盘。
Rule,规则,对Item的值进行判断,是否要出发一次告警或动作,并且根据Item的值解析完毕后设置一个状态,状态包括OK、INFO、WARN、CRITCAL等等。对于Item来说这是它当前的状态,对于alert来说这是告警的级别,一个Item关联到了多个Rule,那么以最高级别的状态为准。Rule的属性中有一个最重要的是规则表达式,“在阀值超过90,并连续三次后,确认为WARN状态”,这就是一个规则语言,其中包括了逻辑,规则语言的重要性在于将逻辑作为参数传递,将逻辑动态化了,rule如同规则引擎般。我们来看看关于weblogic排队线程数的规则表达式,“critical={>,0,2}”,这句话表示当数值大于0且连续两次则将状态修改为critical,严重。
我们看看zabbix的的规则表达式,下面是一条cpu负载的表达式:
{www.zabbix.com:system.cpu.load[all,avg1].last(0)}>5 |
“www.zabbix.com”表示监控对象,这里的”system.cpu.load[all,avg1]”类似于Item的唯一属性,last表示取最近的一次值,当最近的一次值的负载大于5时,则认为有问题。Zabbix的规则比之前的要复杂也完善很多,再来看下面这条规则
{www.zabbix.com:system.cpu.load[all,avg1].last(0)}>5|{www.zabbix.com:system.cpu.load[all,avg1].min(10m)}>2 |
当cpu的负载大于5或者在最近10分钟内负载大于2时确定为异常。读者注意到,zabbix的设计与上例不一样了,它的Rule与Item之间是没有关系的,Rule是以一个集合的方式直接关联到Object,这样才可以实现对不同Item之间的与、或的规则定义。Rule到底和谁关联跟合适,显而易见Rule应该与Object关联才能在全量的Item数据中进行匹配判断,这才是最灵活的,相比于做完一件事后判断他的对错,更合适的方式是做完所有的事情后再来全局判断,设计细节的会给产品的扩展性带来很大的影响,需求永远是在变的,为了保持绝对的灵活性,必须深挖需求,这样才能辨识出对象之间到底是否存在必然的关系。我们在之前的的抽象关联图上再进一步细化,并调整关联关系,如下图:
规则表达式中要涵盖很多元素,阀值,最终Item值对比的数值;操作符,大于、等于或小于;重复次数;zabbix还定义了一些函数对值进行操作,比如取值时间段等等。
Alert,告警。在Rule命中后则会进入到Alert,告警的方式很多,发短信、发邮件、dashboard面板展示以及其他方方面面,对于Rule触发的Alert而言,它仅仅只是把一条消息发送到给告警的接收者,但要注意的是在生产环境中非常容易出现告警风暴,笔者经历过连续不断的短信在凌晨扰人经历,让人无法入眠,经验证明将告警邮件、短信广播到所有的当事人,不如将告警集中在一个dashboard上,由7*24的值班人员负责值班监控。在dashboard面板上,值班人员对告警的响应方式便捷很多,他可以采用注释、确认、转事件、升级、问题管理等诸多方法,一个注释的告警要说明注释原因以及注释时间段。为了防止出现风暴、冗余现象,我们要做一层filter,而这些filter如同Rule一样也是基于规则的,他们会关联到Object的维护时间、变更窗口,甚至与实际的应用运维部署动作关联,从而大量减少无效告警。在Alert传递给终端用户前必须经过层层过滤,在告警类型与告警过滤上来看,开源产品本身无法满足要求。
Dashboard告警和MSG(短信、邮件)告警方式各有所长。Dashboard是主动型,由监控人主动的从面板中“拉”回告警信息,在运维职责中,有专门的值班人员负责盯着监控面板,面板定期刷新,将最新的告警信息更新进来。MSG是被动型,告警信息会推送到接收人终端设备上。 Dashboard的优势在于在一个集中的面板上展示了所有告警信息,便于关联分析;对于重复的告警只显示一条,可防止告警风暴;对于告警的处理可关联CMDB,监控人员判断是否需要联系上层业务应用管理员;关联事件管理系统,对于已知的问题上报case给后端事件团队。而MSG方式认为,理想情况下告警处理人员可以做自己的事情,只有当告警通知时才开始处理。在大型IDC运维中心,一般将MSG作为一种可选通知方式,而重点采用dashboard方式。智能手机已经成为日常生活中必不可少的随身件,将dashboard传统的网页版移植到app上,既可以保持原有优势,同时也可以得到MSG通知功能。
由于Dashboard是所有告警信息的集中面板,必须在上游建立告警阀值规则时就确保设置精准,否则会出现大批批无需处理的无效告警,这种规则的调整是一个长期过程,监控项与配置项一样有专属的owner团队,接收前端监控人员的反馈,及时消除无效规则。上述的反馈过程不是马上见效的,为了保证面板整洁,还需要提供诸多的功能帮助监控人员。告警注释功能就是其一,注释告警时定义注释时长、注释原因、注释人;告警转事件,与ITIL流程管理系统关联是功能其二,将一条告警转发给后端团队处理。
在Dashboard上要保证信息精简有效,拒绝无效的数据与格式,类似于在面板中嵌入一个仪表盘的功能是完全无必要,占用空间大,且只能反映一条当前容量信息,这类功能属于“展示”类需求,在监控运维中无实际的用处。
Action,动作。严格的说Alert属于Action的一类,那为什么要加以区分?Action是一个一个回调函数,当Rule命中时出发我们采取的行动。我常常苦恼于问题在那么刹那间而过,虽然保留了一些痕迹、线索,但这些内容是不足以让我们找到问题根本原因,我们希望有一个自定义的接口让我们在第一时间运行诊断工具,比如DB主机cpu高,但这个告警出现时,我可以定义一套诊断序列来分析哪个进程cpu高,如果是DB进程,我们看看等待事件、看看topSql等。对于java进程,它打出threaddump、heapdump,对于heapdump的分析还可以延伸至对象之间的引用关系,看到真正是那个对象的占比高。提供一个开放的接口会引发大家的思考,进而朝运维自动化迈进。
在核心需求的分析完毕后,我们可以对此模块展开设计工作,同步进行的还有其他需求的收集与分析,敏捷迭代开发的过程在于从需求中选择出最核心的部分进行分析、设计,并开始编码实现,在随后的迭代过程组中继续完善其他非核心需求。
百分位裁剪、趋势分析、正态分布,数据图形化
核心需求所关注的是Object的可用性、健康与否以及通知监控人员处理。所有的监控系统同时又需要具备将存储的Item监控项指标数据图形化展示的能力。图形化数据体现在容量、性能两方面。容量与性能的区别在于我们是否对某一项监控指标有了明确的基线,并且能够换算成百分比。磁盘的空间使用率、CPU的系统空间使用率就是已度量好基线的容量。而性能则不同,它的基线不是显而易见的,他代表着在单位容量的情况下完成的业务请求、响应时间、吞吐量,性能调优可以帮助我们在固定的容量资源下完成更多更好的任务,当一切趋于平衡的时候我们要度量出单位容量完成的业务处理能力。图形展示中的这些容量、性能数据对我们有什么帮助?我们会在以下的情况中使用这些以时间轴为单位在图形中展示的数据。
判断异常点的依据。我们期望大多数异常的线索在日志中体现,但很可惜的是异常点本身就不是以一个可记录的Error出现的。有些异常会在没有任何日志记录的情况下间歇性出现,这个时候我们唯一能够做的就是从历史Item数据的突变点中查找线索。将数据按时间轴,排列在曲线图、柱状图中是我们常用来展示数据的方式。采集了的大量数据在异常判断时往往只会用到一点点,即便异常本身不出现,某些Item数据在图中的波动也会引发相关人员的关注并对问题进行查找。由于采集的数据量比较大,而一般关注的数据的时间都是最近点,在数据点的存储上会将7天或30天后的数据粒度粗化,以释放数据存储空间。每天晚上会有一个后台批量程序进行数据粒度的有效裁剪。
百分位数法(percentile),是数据裁剪的常用算法。它是统计学术语,如果将一组数据从小到大排序,并计算相应的累计百分位,则某一百分位所对应数据的值就称为这一百分位的百分位数。可表示为:一组n个观测值按数值大小排列如,处于p%位置的值称第p百分位数。
我们常常说P97,举例而言,采集回来的cpu使用率数据是以30s为间隔,在100个数据中,我们对其进行排序,保留排在第97位的一个数据,其余的99个值全部丢弃。实际情况我们不会严格的按照P97来计算,而是按照缩放比例,一般会采用1:7的缩放,7个数据排序,取第6位作为有效位,从而压缩空间。
对于某些特殊的Item指标的监控数据不高值,比如空闲线程数,越低代表越要关注,因此采样时要使用P3。
定义基线。我们需要定义Item指标数据的基线,某一个核心业务操作的数量在什么范围内是正常的,在什么情况需要引起我们关注。在业务核心功能访问量上常常会试着将采集到的数据进行基线建立。比如寿险出单系统,我们采集了过去三个月每周一早上10:00~12:00两小时内的出单数据,将其分布在一个X、Y数据轴上,X是我们录单数,将其作为一个随即变量,按照正态分布模型,我们可以计算出当前哪些数值情况是在异常范围内,需要我们关注。
正态分布(Normal Distribution),自然科学与行为科学中的定量现象的一个便捷模型。正态分布也叫做钟形分布,这个名字是因为正态分布的数值在图形上类似一口钟而得来。在一系列的数值当中,靠近中值附近的数值数量最多,而偏离中值的数值数量则不断减少。人类社会的很多行为都符合正态分布的特点,那些“大多数”都集中在中值附近,而“非主流”则偏离中值。
趋势分析。什么时候会出现瓶颈,什么时候要追加资源,对于那些已经给出了预警峰值的容量型数据,可以通过趋势图推测出未来到达峰值的时间点。提前做好扩容准备的工作。
最小二乘法(Least squares)是一种数学优化技术。它在X、Y轴上采集一定数量的点,通过最小化误差的平方来计算出趋势直线。对于每一个Item,评估出其预警峰值,在与趋势直线相交的点为瓶颈点。
图形展示模块是可配置的,这体现在一张图中,我们可以将任意Object的Item组合在一张按时间点一致展示。对于多张图表,我们也可以自定义的将它们组合在一个页面上,从而形成由用户完全自定义配置的监控对象集合。
监控项与配置项一样,要录入到监控平台系统中管理,在监控平台上也要考虑用户界面基本功能,包括数据录入、权限控制,这与配置管理的要求是样的。Monitor object和CI的属性很大程度上是重合的,监控项依赖配置项,二者的数据要打通共享。
有很多开源的WEB前端图表工具可供使用,按照API要求将数据加载到图表中。在选择通用开源工具包前要考虑几点,包括功能上是否完全满足自己的需求,开源社区的资料是否充足、浏览器的兼容性上是否做得处理得好。
Highcharts(http://www.highcharts.com)是一款纯javascript编写的图表库,我们能够使用它很简单便捷的在Web网站或Web应用中添加交互性的图表。在兼容性上它做得非常出色,几乎支持所有的现代浏览器,包括IE6 +、iPhone/iPad、Android。它在标准(W3C标准)浏览器中使用SVG技术渲染图形,在遗留的IE浏览器中使用VML技术来绘图。其完全基于本地浏览器技术,不依赖任何插件(例如Flash、java),不需要安装任何服务器环境或动态语言库支持,只需要两个js文件就可以运行。目前可绘制直线图、曲线图、面积图、曲线面积图、面积范围图、曲线面积范围图、柱状图、柱状范围图、条形图、饼图、散点图、箱线图、气泡图、误差线图、瀑布图、雷达图等,其中很多图表可以集成在同一个图形中形成综合图,并支持图表的缩放。
Highcharts具备足够的灵活性,提供丰富的API接口,可以很方便的对图表的任意点、线和文字等进行增加、删除和修改操作。支持众多的Javascript事件,其结合jQuery、MooTools、Prototype等javascript框架提供的Ajax接口,可以实时地从服务器取得数据并实时刷新图表,支持多种数据形式,包括Javascript数组、json文件、json对象和表格数据等,这些数据来源可以是本地、不同页面,甚至是不同网站。
Highcharts在国内拥有开源的中文站,到目前为止该网站拥有 “中文论坛”、“在线演示”、“中文教程”、“中文API”、“在线测试”、“相关资源”六大核心资源,其中的资源还在不断完善。
开源借鉴与选择,zabbix,nagios
日志分析
监控平台的部署架构