看大众点评如何通过实时监控系统CAT打造7*24服务
CAT是一个实时监控系统,它侧重于Java应用的监控,基本接入了点评所有核心应用。CAT已经在中间件框架(MVC框架、RPC框架、数据库框架、缓存框架等)中得到广泛应用,为点评各业务线提供系统的性能指标、健康状况、基础告警等。
CAT很大的优势是它是一个实时系统,从数据生成到服务端处理结束是毫秒级别;第二个优势,数据是接近全量统计。
大众点评监控系统CAT是由@吴其敏@携程(前大众点评首席架构师,现携程架构负责人)主导设计。我们平常都称吴其敏为老吴,老吴之前在eBay工作超过10年,对于eBay的CAL系统有深入了解,CAL是CAT系统当初的原型。
监控应该是一个很宽泛的问题,任何可能出问题地方都需要加入监控。
我们把服务端监控的报表分为两类:
故障发现类的报表有如下几个:
以上讲了我们做的给运维,更准确的是24小时值班监控团队的监控大屏,主要目的是快速发现问题,这里不需要很华丽的数字,主要用精确的红色来代表发现故障,需要立刻通知解决。
什么东西才可以作为一个大盘:这里需要看公司整体运维的故障情况,TopN以及业务指标应该属于通用,数据库和网络大盘是点评在实际经验中经常容易出故障的地方,所以我们做成大盘这样比较直观的形式,用于发现问题。比如平时因为发布引起故障比较多,他们也做了一个发布大盘,实时监控线上的发布情况。
下面我会讲到服务端分析问题的报表,在这之前我介绍几个CAT监控的几个基础概念。
首先第一点就是监控的模型,监控最需要解决的两个问题,响应时间和访问量。
在这个基础上我们定义监控最基础的模型,Transaction和Event,这个也是后续问题最多的地方。
后面还扩展定期执行某些代码以及一个指标变化值,第三个可以理解为心跳(主要是框架使用)。最后一个一个指标变化值,主要用于业务指标的监控。 在这个基本模型的基础上,我们定义了我们监控的Java的API,Sample大致如下:
这个API里面Transaction以及Event都有两层分类,为什么是两层分类,从实际的经验中两层分类可以解决大部分的问题,所以定义了两层。 当业务程序完成了API的情况,后面会产生CAT的原始监控请求,这里我们称之为Logview。
这个Logview是一个树的结构,根节点一般都是Transaction,Transaction可以嵌套子的Transaction,Event就是一个单个节点,不能嵌套。这个longview将应用程序的执行路径按照时间序列组成一个Logview。
它还有另外一种展现形式,它很直观看到整个调用路径中最慢的地方。
整个点评迈向SOA化,Web调用服务,服务再调用其他的服务,调用关系的跟踪很有必要。
在点评Call表示一个远程访问,当遇到一个远程访问时候,会有一个show节点,点击show就能知道服务端对应这次Call的它的访问序列,如果这个服务还调用其他的服务,一样可以跟踪下去。比如如下请求是URL,调用了groupService的服务,groupService的服务还调用了userBaseService的服务
以上部分讲诉了整个CAT监控最核心的模型以及在此基础上产生的Logview,后续监控产生所有的原始数据都来自于Logview。在点评监控,目前是做的全量监控,也意味着每次URL请求,SQL请求、缓存请求、远程请求都有对应的实时Logview发送CAT以供实时处理。
监控里面,尽量做全量监控,这样看到的问题才足够接近真实。监控尽可能做到实时,延迟一分钟或者几分钟都意味着故障处理总时间的延长。
CAT每天大约有300亿Logview,3500GB消息,Logview太多了人已经没办法处理,所以基于Logview肯定有一些实时分析的report,下面我讲诉监控系统基于这些logview产生几个核心的report。
这个是TransationReport的第一个视图,左上角可以选择项目进行切换,一个项目定义为一个独立的war包上线单元。报表时间是一段时间,CAT统计报表的时间跨度是一个小时。根据一个小时的report,后续可以合并为天、周、以及月。
Machines: 有一个All以及具体的机器明显,可以看所有机器,也可以看单个某台机器,如果某台机器出现的问题,则可以很容易看到。
这里展示了一个Transaction的第一层分类的视图,可以知道这段时间里面一个分类运行的次数,平均响应时间,延迟,95线以及99.9线。95line表示95%的请求的响应时间比这个值要小。
上图这里面是点击URL进去的第二层,可以看到第二层的具体明细,统计值也是一样。
比如看到URL下面dependency的访问量为566,响应时间为778ms,就需要多想,这样的耗时有么与办法优化,这样的访问量是否合理。主要响应时间和访问量,任何优化就可以开始以及有了根据。
TransactionReport是我们平时做优化最最常用的一张report。 点击最左边Show可以按照时间展示,可以看到按照分钟粒度的精确的展示,1分钟是CAT监控最小的粒度单元。
这里的Transaction的埋点的Type和Name是业务自己定义。
2、EventReport
EventReport整体是和TransactionReport结构几乎一样,可以根据项目,ip进行导航,但是少了一个响应时间的概念,这里只有访问量。可以按照type展示,查询二级目录的情况,可以看到show,看到分钟级别的趋势图。具体参考transaction,这边我不多讲了。
Event有个比较作用能方便帮助业务做一些业务上统计,举个例子比如看每天用户登录次数或者代码里面有三个分支,可以很简单使用Event API帮你做统计。
之前讲述过每个应用每次的请求都会有CAT的监控的Logview,这样庞大的数量下,ProblemReport等于定义了很多特征,特征包括如下,ProblemReport就是把一堆logview中存在这些特征的给聚合为一个报表,让用户发现问题。
上诉报表就是tuangou-web项目一段时间内的产生的各种问题,右边Looooooooog之类,就可以看到原始出错的logview。这个loview可以看到很多明细,比如输入的参数等,还有前后一些逻辑。这样的logview信息是很容易帮助用户发现问题。
上图我点击一个异常的后面的O,就看到这次异常出现的完整的上下文信息。
点击show,可以看到此类错误对应的机器分布情况以及分钟粒度的趋势图,通过这个很容发现是否某台机器故障还是全局问题等。
业务开发他们需要fix里面一些比较严重的问题。比如SQL慢响应很多(比如通过索引或者缓存),服务慢响应(如何优化),调用下游错误(如果推动下游服务端解决),异常(NPE)等等。
这里主要CAT客户端定期一分钟向服务端汇报当前运行时候的一些状态,几个比较常用的指标有:
展示方式按照某台机器的维度查询
心跳报表还需要有一定扩展性,这里CAT提供了一个SPI让业务实现并注册上来,这样可以每分钟上报心跳并回调,让后把数据一起传回服务端,并作监控展示。常见的使用场景有:当前机器每个数据库的连接数、当前jvm使用队列的当前队列数量等。
这个报表主要作用了解决在RPC框架里面的一些上下游调用链路的问题,统计粒度支持项目、具体某一IP、具体的服务方法。
比如上图是当前项目xx-web调用了4个服务,调用每个服务的响应时间,访问量以及错误量。
点击某个项目进去可以知道具体调用此服务的具体每台机器的情况如下,记得前端时间微博的同事分享过线上一台服务挂了,导致了1/8的请求有问题,如果CAT能接入进去,应该是很快就能立刻发现是其中一台服务出现故障。
点击ALL或者单台机器可以知道调用具体此服务某个方法耗时情况。
这个报表还有很多其他作用了,比如作为一个服务端,他可以知道当前有多少客户端访问我,可以查询服务端一个方法被多少客户端调用,每个客户端调用的响应以及耗时等等。(这里往往会发现个别比较糟糕应用用一些不太合理的方式调用,比如夜里的Job,大量的batch调用等,这样就会考虑独立部署几台给个别应用调用)。
CAT还有其他的一些报表,这里我就不一一介绍了,有兴趣同学可以参考下CAT的文档。
CAT一些离线分析报表,比如jar版本分析,服务可用性排行等等。
如上图CAT在当初设计的基本几个点,在再次基础上我们后面很多方案都是基于此来实现。对应用无影响是必须的,实时性我们要求做到毫秒级,由于是全量监控,所以吞吐量也是需要保证,最后是开销,开销不能因为应用接入监控提高很多的延迟。
最后两个可靠性,应用端是否确定把所有消息传输到服务端,以及服务端是否必须处理所有消息,我们认为是没有必要的,但从实际的结果看来,有4个9的可用性。比如昨天数据,一共处理240亿,丢了50w消息。
下面讲到客户端设计一些要点
下图是整个文件存储的设计图
在消息ID设计上,是${domain}+${ip}+${timestamp}+${index},这作为唯一的KEY,所以CAT不支持同一个IP部署两个相同的应用。同一个IP部署多个不同的应用是没有问题的。所有的文件都加上cat的consumer的ip作为后缀,保证文件上传到hdfs上不会有文件的冲突。
压缩采用的是分块压缩,数据块的大小在64K以内,所以记录每个消息对应的所在块以及消息在所在块的偏移量。当需要找到某个消息,先随机访问到某一个块,将这个块全部读取出来,然后根据块内偏移地址找到对应的Logview,因为消息可能是在多个文件中,最后检查下读取到的logview的id等于查询时候的id,即找到消息。
这里说下点评实际的一些经验。
很快到了今天总结的时候,这部分我会讲讲监控在点评一路的情况,有些问题的解决,如果还有其他的疑问,后续大家可以提问
整个CAT项目从2012初到现在,到现在大约3年多时间,整个过程持续2-3个人,几点感触和大家分享
在今天演讲的最后,请允许我打一次广告,CAT的地址 https://github.com/dianping/cat 有兴趣可以按照步骤搭建下,搭建过程我们写了一键工具。 CAT很多其他的文档都写搭建的系统首页上,只要本机有个mysql即可,CAT就能单机部署并运行起来。
CAT是全量数据采集,心跳数据是1分钟一次。如果服务器或者硬件监控,一般几秒一次。如果是特别重要的,可以一秒一次。
比较通用的监控项,也就是核心框架里面监控项目,比如远程访问,数据库访问,缓存访问的响应时间,访问量等。
心跳里面的监控项有
建议报表系统还是自己做比较合适,报表这类需求定制太多了,比如按照部门、产品线等统计。
开源的监控系统,比如zabbix,nagios,cacit算是很成熟的一套监控系统,他们能通过脚本或者snmp协议等收集很多服务端的性能数据,并配置很多监控规则来发现服务器等一些问题。点评这些也在用,主要是zabbix,他和CAT互相补充。
之前小米开源的系统应该也是基于指标的画图以及告警,和CAT应该是两类不同的系统。
服务端监控,就应该类似于我上面讲的CAT在服务端监控一些做法,不仅仅包括问题发现,还包括了性能调优,路径分析等等,这样才能把帮助业务分析并找到问题。
App监控,由于时间问题,今天没有讲到,这里说几个点吧。App监控点评做了三个部分:
Dubbo是阿里的一套PRC开源框架,目前我们没有集成的case,CAT和点评PRC组件集成得很好,坚信应该不是问题。
个人觉得运维成本不大,主要是使用以及依赖组件很少,MySQL,极端情况HDFS都可以不需要。
基于性能考虑。Netty本身是非常成熟的开源网络组件,event机制、全异步、高性能,还有简单易用,非常适合于框架和基础设施开发。CAT用Netty做长连接通讯,吞吐量非常高,健康检测、故障转移和故障恢复能力都非常强。消息队列根本不适合这么底层的数据传输,它的overhead太大,很多feature CAT并不需要。
用CAT可以将在多台机器或多个进程的消息串起来,组成调用链。基本的思路是,在常用的场景中,客户端产生一个新的消息ID,连同自己的消息ID在调用时作为参数传递到服务端,然后在服务端的消息使用传过来的消息ID,来存储,并用客户端的消息ID作为向上的链接。这样客户端和服务器端就可以有双向的链接了。但是这需要在相关的框架中埋点。
CAT客户端有一个queue,queue是固定大小了,CAT一台客户端会连向几个服务端,当一个服务端出问题,数据不会丢失。当所有服务端都挂掉,消息会存入queue,当queue满了,就丢弃了,没有做数据存储本地等工作。
上下游调用,主要用到全局统一项目名,这是点评一套架构上的规范,可以理解为环境信息。RPC能在当前的运行环境下知道自己当前的项目名以及调用者的项目名。
支持JAVA和 .Net。
当一个客户端不 work,client 会自动连接上 next server,所以有一个管理连接的线程,保持一个活动有效的连接,如果 server 全部挂了,消息就丢弃了。
所有的消息都是基于消息队列处理,如果队列满了,会有记录。
没有。
不是通过脚本,具体的收集可以参考源码 StatusInfoCollector,主要用到 MemoryMXBean, MemoryPoolMXBean等。
数据上报的格式也是logview,是客户端主动一分钟上报一次。
服务端尽量做到高可用吧。
手机监控其实是另外一套系统,最后展示层在CAT。
服务端会分析上报logview,埋点信息会有客户端和服务端的项目名信息,后端可以用此数据进行实时分析。
UDP在线下测试很不稳定,经常丢弃什么,TCP的比UDP多的开销其实对业务影响很小。
CAT系统最初的设计者吴其敏补充说:如果系统的消息丢失率达到一定的比例,那么它的的可信度就会降低,所以保证足够多的消息能够被好好处理是很重要的。CAT设计成不可靠系统,但实际上我们希望系统足够可靠,只是不愿为承诺可靠而付出高额代价。 以前研究过Dapper,觉得它的机制与CAT相差很远,监控的全面性不够。当然如果到了Google的量级,情况就很不一样了。
TCP是有连接的,有拥塞控制;UDP无连接,一般情况下内网成功率还是挺高的,极端情况下将非常糟糕。