简介
背景
CAT(Central Application Tracking)是由吴其敏(前大众点评首席架构师,现携程架构负责人)主导设计基于Java开发打造的实时应用监控平台,为大众点评网提供了全面的监控服务和决策支持。AT作为大众点评网基础监控组件,它已经在中间件框架(MVC框架,RPC框架,数据库框架,缓存框架等)中得到广泛应用,为点评各业务线提供系统的性能指标、健康状况、基础告警等。
吴其敏采访及一些备注
分布式系统已经诞生了很长时间,随着计算能力和存储价格的降低,我们见证了分布式系统大爆炸的时代,现代互联网公司规模都变得异常庞大,系统也变得越来越复杂,给监控工作带来了极大的难度:海量日志数据如何处理,服务如何追踪,如何高效定位故障缩短故障时常…… 监控作为运维工作中最重要的环节,一直是运维工作者关注的话题。 吴其敏是平安银行零售网络金融事业部首席架构师,曾在 eBay 工作多年,先后担任过大众点评和携程的架构负责人,同时吴其敏也是开源的实时监控系统 CAT 的作者。 吴其敏老师担任本届 InfoQ 全球运维技术大会 CNUTCon 的联席主席,听说有几个出品人也是吴其敏老师的学生.
吴其敏: 我理解的常用监控手段
按监控层次分:业务监控、应用监控和基础监控等; 按监控日志来源分:基于日志文件监控、基于数据库监控和基于网络监控等; 按监控领域分:前端监控、后端监控、全链路监控、业务间监控等; 按监控目标分:系统故障监控、业务指标监控、应用性能监控、用户行为监控、安全合规监控等。 监控领域非常复杂,像开源实施分布式监控系统 CAT,从监控分层看,它擅长应用监控,有一定的业务监控和基础监控能力;它是基于网络来完成日志数据的传输的,将来会支持日志文件和数据库作为数据源;它已经覆盖前后端监控能力,通过良好的实施可以做到全链路监控和业务间监控,监控的目标更是非常多样化。但 CAT 对监控团队的技术开发和运维能力提出了很高的挑战,一般在大型互联网公司,都设有专门的监控研发团队,基于 CAT 做二次开发,支持业务的多样化需求。
分布式系统的监控难点在哪里?如何解决?
吴其敏:
太多了!以 CAT 为例,CAT 在美团点评每天新增监控日志量有 400TB 以上(部分系统日志采样),在携程也早就超过 300TB,在这样的数据量压力下,通常情况下的一个小问题都会被放大千倍万倍,成为一个大问题,要么是系统稳定性受到影响,要么系统吞吐量有问题,要么系统出现热点导致资源使用不平衡而浪费,要么存储系统顶不住等,最可拍的是监控出问题导致的业务问题。 CAT 在设计之初就充分认识到监控领域是一个深水区,对每一方面领域问题都非常重视,对每一个新报表都经过长时间多角度的推敲认证,在编码实现时每一行核心代码都经过严格 Review,最极端的情况下一个类每一行代码 Review 后都需要修改。 CAT 具备单机开发条件,也就是说只要一台机器,一下子就可以将 CAT 系统启动起来,进行开发、测试和排障,开发效率极大提升,同时核心系统有大量单元测试覆盖,辅以完善的建模和代码生成工具,研发效率保持很高。 CAT 可以做到监控 CAT(最底层监控除外),即构建起了一个最小的应用场景,同时可以完善 CAT 自身能力,这一点也是非常重要的;轻量而独立的平台,是 CAT 的一个重要特点,很多人经常会问:Spring 是现在最流行的框架,功能强大,CAT 为什么不依赖它?我想说这里面有一个依赖层次问题,一般都是高层依赖低层的,不会底层要反向依赖高层的,否则会出现什么问题呢?其实这就是典型的耦合性问题,底层依赖于高层,底层的应用范围就会收到严重的约束,就像 C# 是一门好语言(除了 PHP 哈),C# 要做.NET CLR 上运行,.NET 有需要跑在 windows 上,就很容易想象.NET 现在所面临的窘境了。当然.NET core 经过改造应该也是可以跑在 Linux 上了,但是功能还是收到很大的限制。 像 CAT 客户端 SDK,我们刚开始的目标就是可以跑在 JDK 1.6 以上,各种不同的平台上,包括 Spring 和其他技术栈。有了这一个假设,就意味着 CAT 要尽可能少的依赖其他运行时组件,如果一定要依赖的话,最好也要避免与上层应用发生任何冲突,比如最基本的 log 和网络通讯组件 netty 等。但是在系统集成方面,CAT 是可以与各种流行的规范、系统和组件做更好的集成的,比如标准的 J2EE Web 项目,只要做 WAR 配置一个 filter 即可,针对 spring 也可以加一个自动注册的 filter 等等,做这些外围的集成,挑战应该不会很大,大家也可以自己完成。 再说说数据量方面的挑战吧,如果每天有 300TB 的数据量,意味着正常情况下平均每秒要处理 6GB 的数据量(高峰时加倍,与网站业务类型有关),至少需要 60 块千兆网卡(1Gb)共同来完成,先不说监控数据怎么采集,就传输这么多数据到 CAT 系统做分析就是一个很大的挑战。有人会说,能不能做客户端先做一些预处理,比如聚合分析,或者灰度采样,或者压缩?可以,但是这可能会牺牲数据处理的多样化(有些报表会没有明细)和时效性,并且增加业务节点的计算和存储负担。传输问题最核心的是如何解决多节点间负载不均衡的问题,这个问题看似是小问题,实际上是一个涉及整个系统架构的机制问题,CAT 在这方面有很多考虑,细节将来有机会再分享。 传输问题之后是就是怎么消费的问题,CAT 在日志消息的序列化 / 反序列化效率,日志消息异步化分发和独立线程内消费,分领域分时段统计等机制(小时报表、日报表、周报表、月报表等)。CAT 有一个很好的机制是可以做到在单一线程内,不强调线程安全,可以大大简化代码编写要求,降低同步问题发生的概率,保持代码良好的可读性,和运行时高效率。但是从长远发展来看,存储问题是大数据量应用永远要面对的挑战。存储不但要解决吞吐问题,不能有堆积,同时还要解决财务成本问题,关注性价比,小企业还好,大企业会特别关注这一块。CAT 的存储引擎已经发展到了第六版本(V6),每一个版本都是重新设计,从头再来。V6 版本从构思到编码、到整合验证上生产,历史半年之多,方方面面的挑战都很大。结果不错,它与 V5 引擎读写效率大幅提升,文件数大大减少(具体数字尤勇在美团点评的 CAT 分享中有提及)。 如果上面说的都是技术实现方面的挑战,那么 CAT 监控实施落地将是另一个挑战。不管是在代码中做侵入式埋点,还是通过字节码技术做无侵入埋点,监控首先要解决的是目标设定,到底要解决什么问题,关注什么指标,不管现存的还是潜在的,如果没有问题就不需要监控。如果目标明确了,第二步就可以指定方案,怎么样通过已有的机制解决,或者使用新的创造性的方法,达到目标。接下来就是方案的落地实施了,数据在哪里,需要通过什么手段拿到,通过 CAT API 传递到后台分析。最后一步,就是等系统上线有结果后,需要去做验证,是不是真的达到了预期,还是目标设定需要调整。这四步可以不断迭代,直到各种监控问题都可以被解决。
国内外有哪些比较好的分布式系统监控项目
吴其敏:
国内外分布式系统监控项目应该有很多,能开源并且愿意开源的不多,最近比较常用的,国外有 ELK、ZipKin 和 Pinpoint,国内的有 CAT、SkyWalking、Open-falcon 等。真正经过大公司的多场景和大流量考验的应该不多,CAT 算一个吧。目前 CAT 在国内数百家公司有自发部署,感兴趣的开发者有上千人。最近美团点评对 CAT 的开源高度重视,大力投入,加上几个大中型互联网公司(如携程,平安银行、猎聘网、陆金所等)的大量应用,相信 CAT 将来会更加广泛应用。ELK 是基于日志文件做监控的,ZipKin 和 Pinpoint 有些功能不错,小公司用的多一点,相对比较简单,功能不是很丰富,公司做大了以后会碰到很多可扩展性方面问题。
分布式监控系统包含哪些模块
吴其敏:
一个监控系统往往包含日志采集、日志传输、日志分析、日志报表、日志存储和报表展示等关键模块,系统通过每一个模块等分工协作来共同完成。不同的产品应该有不同的侧重点和优势,CAT 架构设计力求简单高效,开发简单,运维简单、高效运行。之前跟一个大厂做过一个对比,它的监控系统机器数与被监控的应用机器数比是 30 左右,而 CAT 是 300。 意思也就是说,跟美团一样的超一线互联网公司,他们服务器是一台监控机对应三十台,而cat监控能做到一台监控三百台.
为什么想做Cat这个项目,cat的优势在那些方面,还有那些地方不怎么完善?
吴其敏:
说起来话长,应该说是 7 年前(2011 年末)我刚到大众点评的时候(那时候美团与点评还没有合并),本来是信心满满的,以为在 eBay 十多年学了一身的本领,可以大展身手的。没想到当时大众点评整个网站经常有各种各样的故障,弄得大伙不得安宁,领导们也很着急,出问题总是导亲自在现场指挥,甚至亲自到电脑上排查问题,也不乏有凑热闹者将领导围得里三层外三层,场面非常壮观(可惜当时没有拍照)。一会怀疑网络问题,一会怀疑数据库问题,一会有怀疑缓存有问题,...(此处省略一万字)。但问题终究是问题,不会因为你是领导就卖你个面子,放你一马,所以最后故障解决时长总是很长,就是故障恢复了,根因也是不清不楚的。故障过程中经常会有比较沉重冷静的工程师,突然大叫一声,我在什么机器什么日志中发现有什么样的报错,可能与故障有关。大家一听,不妨一试,做相应处理后,一会故障现象消失,故障结束。然而,怎么缩短故障时长,故障是怎么形成的,根因是怎么定位的,还有大家应该从此次故障中吸取什么样的教训,经常是不明不白的。 在这样的一种情况下,我突然意识到,原来公司最缺的是应用监控,上面的一堆问题只是缺乏好监控而导致的现象。现在大家可能知道,eBay 内部有一套很好的应用监控叫 CAL,据说是 eBay 的一大法宝。我没有参与 CAL 的研发,但是我是资深的用户,时不时也会给兄弟团队分享 CAL 的使用经验。于是我主动请缨要做监控,写下 CAT 第一行代码,刚开始的几个月就是我一个人,从架构师到程序员,从后端到前端,从测试到运维,全部自己搞定。 CAT 的优势应该有很多,分布式集群、丰富的实时报表、全量日志采集、高可靠 / 高可用系统等。监控领域这么大,CAT 不完善的地方肯定也是很多了,比如学习门槛高、定制难、易用性不够、与其他生态的集成度不够、对语言的支持还是不够多(虽然已经有了对 C/C 、Python、golang、Node.js 等语言对支持)、对异步多线程的支持力度不够、后台配置管理有待加强、与 docker 等云集成不够等等。这些都是将来需要与社区一起不断完善的,也欢迎大家加入到 CAT 的社区来。
研发CAT时有哪些印象深刻的事情
吴其敏: 还是讲一讲CAT刚开始研发时的事吧,
当时大众点评已经有一个监控系统 Hawk,它是基于数据库存储日志的(那时候还没有 ELK),已经开发了近一年时间,基本能用,正在全面推广阶段。我加入大众点评后,听完他们介绍以后,就觉得可扩展性很有问题。于是提出要研发一套新的监控系统,画了一个好大的一个脑图(可惜那台电脑坏了,图拿不出来),跟公司相关同事介绍需求的时候,大家听得一愣一愣的,现场连一个问题也没有,我当时的感觉是:他们肯定觉得老吴在吹牛,反正架构师嘛大家都懂得,说说都是容易的。当我要求 Hawk 系统停止推广,一下子很多人来找我,表示各种担忧或者不解。那是时候,我就下定决心,一定要做 CAT,玩意搞砸了就走人呗,反正 eBay 是随时欢迎我回去的。然后我就一个人默默的做设计和开发,现在想想或许这就是我作为一个人程序员最好的时光,每天都很充实。还记得那时我的领导找我吃饭时,问我要什么样的支持,我就跟领导说,给我几个月时间,甭管我做什么,怎么做,请不要打断我,就是对我最大的支持。领导同意了我的要求,后来也做到了。经过 2 个月的奋战,我做出了第一版 CAT 原型,越领导时间给领导做 demo,场景是事先设计好的,也就是在应用正常运行时中做后台随便搞几个错误,看看 CAT 能不能精准抓到,准确告诉我错误在哪里,作为架构师这点小技能还是有的。当时演示很成功,领导当场就高兴地站起来,拍拍我的肩膀,表示支持我继续研发。在得到领导的认可和信任后,后面的进展相对来说就比较顺利了。当然也不是一帆风顺的,出现过几个小波折,也帮人背过黑锅,但总体上还算顺利。
在云原生时代的监控有什么特点
吴其敏:
云原生时代对应用架构提出了全面的挑战,监控方面也不例外。但是本质核心的东西没有变,只是形式有不同。以 docker 为例,云上应用监控它的粒度比物理机和虚拟机 VM 都要小,以前很多系统是以 IP 地址来区分集群节点的,如果一个 docker 实例的 IP 地址不断地变化,会对监控有挑战;在 Kubernetes 的 Pod 中的 docker 实例,可能是内部 IP 地址,对外可见 IP 地址是 Pod 地址,这样可能会导致一些场景串不起来;另一方面,docker 容器应用生命周期可能会比较短,VM 上的应用是重部署,docker 则是销毁重建,对监控系统可能会有一些新的影响。
在监控领域还关注那些方面?
吴其敏:
在监控领域我倒是比较关注 Visibility,我经常打跟人比方,系统是你开发的,就像你养的小孩,并不意味着你就了解它,随时掌握它的情况。这其中有太多的可变因素可以影响系统的各种架构特性。比如环境配置问题、网络连通问题(这也是背锅侠之一)、脏数据问题、服务依赖问题、应用负载问题、机器性能问题、甚至是 JVM 和 OS 问题,这些你都是不知道的,也很难事先预测准确。这就需要将这些问题指标通过一种方式展现出来,让你很清楚它的状态。没有度量就没有改进,没有监控你就是瞎子,无的放矢。然而提升系统的 Visibility 是很难的,因为它是给人看的,人的要求是多变的,现在这个阶段是这样,等过了这个阶段就有更高的需求了,所以伺候好人是很难的。CAT 在易用性方面是有待提高的,但现阶段 CAT 主要还是在打造更多的问题场景,先解决基本的温饱问题,体验好不好可以留给社区解决。
为什么要使用cat实时监控
代码语言:javascript复制# 1.线上发布了服务,怎么知道它一切正常,比如发布5台服务器,如何直观了解是否有请求进来,访问一切正常。
# 2.当年有一次将线上的库配置到了Beta,这么低级的错误,排错花了一个通宵,十几个人。
# 3.某个核心服务挂了,导致大量报错,如何确定到底是哪里出了问题。
# 4.SOA带来的问题,调用XX服务出问题,很慢,是否可以衡量?
# 5.应用程序有性能瓶颈,如何提供一些有效工具发现?
# 6.如何实时查看线上借口的性能,包括压测,借口太慢如何定位?
# 7.如何统计线上流量以及接口调用量?
# 8.线上接口可用率不到100%,如何进行告警?
# 9.线上服务器缓存,jvm,GC如何进行实时监控?
# 10.程序代码运行情况监控,监控一段代码运行情况,运行时间统计,次数,错误次数等等.
# 11.异常/错误等问题监控.
# 12.SQL执行监控.SQL执行监控可以看到每个DAO方法执行解析的SQL语句,SQL语句执行时长,
# 以及链接到那个数据库(URL)执行;如果SQL执行出现异常,还会记录异常信息,另外还可以过滤出慢SQL.
源码编译部署Cat监控
环境清单:
代码语言:javascript复制* CentOS 7.3
* jdk-8u121-linux-x64.rpm
* apache-tomcat-8.5.45.tar.gz
* apache-maven-3.3.9-bin.tar.gz
* mysql-5.7.23-1.el7.x86_64.rpm-bundle.tar
* cat-2.0.0.tar.gz
* git 1.8.3.1
IP | hostname | 软件 | 内存要求 |
---|---|---|---|
192.168.122.6 | cat-6 | Mysql,Tomcat,Maven,git,cat.tar.gz | 3G及以上 |
注意事项
代码语言:javascript复制# 网络要稳定,必要时开手机热点;
JDK,git安装
代码语言:javascript复制curl -o /etc/yum.repos.d/163.repo http://mirrors.163.com/.help/CentOS7-Base-163.repo
curl -o /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
rpm -ivh jdk-8u121-linux-x64.rpm
yum -y install git
Tomcat安装并启动
代码语言:javascript复制# tomcat官方下载地址: http://tomcat.apache.org/
# 解压部署
tar xvf apache-tomcat-9.0.12.tar.gz -C /usr/local/
mv /usr/local/apache-tomcat-9.0.12/ /usr/local/tomcat
tail -1 /etc/profile
CATALINA_HOME=/usr/local/tomcat
source /etc/profile
# 增加熵池大小,解决Tomcat在CentOS7巨慢的问题,具体原因请看Tomcat章节
yum -y install rng-tools
systemctl start rngd && systemctl enable rngd
# 测试tomcat是否安装成功
/usr/local/tomcat/bin/startup.sh
Using CATALINA_BASE: /usr/local/tomcat
Using CATALINA_HOME: /usr/local/tomcat
Using CATALINA_TMPDIR: /usr/local/tomcat/temp
Using JRE_HOME: /usr/local/jdk
Using CLASSPATH: /usr/local/tomcat/bin/bootstrap.jar:/usr/local/tomcat/bin/tomcat-juli.jar
Tomcat started.
lsof -i:8080
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
java 14054 root 49u IPv4 34484 0t0 TCP *:webcache (LISTEN)
Mvnen安装
代码语言:javascript复制# Maven官方下载地址
# http://mirror.bit.edu.cn/apache/maven/
tar xf /root/apache-maven-3.3.9-bin.tar.gz -C /usr/local/
cd /usr/local/
mv apache-maven-3.3.9/ maven
cat >> /etc/bashrc <<EOF
export M2_HOME=/usr/local/maven
export M2=$M2_HOME/bin
export PATH=$M2:$PATH:$HOME/bin:/usr/bin/git
EOF
source /etc/bashrc
mvn -version
配置数据库
代码语言:javascript复制yum -y install net-tools
rpm -e mariadb-libs --nodeps
tar xvf /root/mysql-5.7.23-1.el7.x86_64.rpm-bundle.tar -C /usr/local/
cd /usr/local/
rpm -ivh mysql-community-server-5.7.23-1.el7.x86_64.rpm mysql-community-client-5.7.23-1.el7.x86_64.rpm mysql-community-common-5.7.23-1.el7.x86_64.rpm mysql-community-libs-5.7.23-1.el7.x86_64.rpm
# 或者使用yum安装mysql
wget http://dev.mysql.com/get/mysql57-community-release-el7-8.noarch.rpm
rpm -ivh mysql57-community-release-el7-10.noarch.rpm
yum install -y mysql-community-server
systemctl start mysqld.service
# 修改Mysql密码下面有三种办法
# 1.刚安装好的mysql,可以从/var/log/mysqld.log获取临时密码
grep "password" /var/log/mysqld.log
[root@mysql ~]# mysql -uroot -p
Enter password:
mysql> ALTER USER 'root'@'localhost' IDENTIFIED BY 'ZHOUjian.22';
# 2.mysqladmin -uroot -p password "ZHOUjian.22"
Enter password:
# 3.实验环境不知道root密码操作方法如下
sed -i '/[mysqld]/ a skip-grant-tables' /etc/my.cnf
systemctl restart mysqld
mysql <<EOF
update mysql.user set authentication_string='' where user='root' and Host='localhost';
flush privileges;
EOF
sed -i '/skip-grant/d' /etc/my.cnf
systemctl restart mysqld
mysqladmin -uroot -p password "ZHOUjian.20"
Enter password: # 此处回车一下即可
CREATE DATABASE sonar CHARACTER SET utf8 COLLATE utf8_general_ci;
GRANT ALL ON sonar.* TO sonar@"%" IDENTIFIED BY "ZHOUjian.20";
flush privileges;
Cat源码包下载
代码语言:javascript复制yum -y install wget
wget -O /root/cat-2.0.0.tar.gz https://codeload.github.com/dianping/cat/tar.gz/v2.0.0
tar xvf /root/cat-2.0.0.tar.gz -C /opt/
cd /opt/cat-2.0.0/
mkdir -p /data/appdatas/cat && mkdir -p /data/applogs/cat
mvn install -Dmaven.test.skip=true # 我开热点差不多下载了十分钟,很多小jar包文件
# 如果用这种方式maven报错使用下面方法
git clone https://github.com/dianping/cat.git
cd cat
mvn clean install -DskipTests
# 再用maven构建项目,提示100%
mvn cat:install # 不到十秒钟,会出现三串提示,输入MysqlIP:Port
格式: jdbc:mysql://127.0.0.1:3306
Mysql用户名: root
Mysql密码: XUANji.19
cd /opt/cat-2.0.0/cat-home/
mvn jetty:run # 稍等一分钟,启动要下载一点jar包;
ss -antp | grep 2281 # 出来端口就可以浏览器访问了
# 如果需要tomcat部署将cat-home/target下有一个cat-alpha的war包,
# 放到tomcat的webapps目录下,重命名为cat.war包启动服务即可