随着数字化的兴起,越来越多的企业开始拥抱数字化转型,中台概念兴起,微服务架构的逐渐流行,越来越多的系统从单体切换到了微服务,可以选择的技术也遍地开花,同时也面临到了前所未有的挑战。
我们该如何控制这数十甚至数百台不断相互通信的小型应用服务器呢?
我们如何清晰的知道它们之中的任何一个模块是正确工作的呢?
我们会担心web服务的性能导致用户体验的下降,数据库服务器的性能让我们夜不能寐,应用服务器时好时坏,一旦恢复了又不知到底发生了什么,于是我们像个侦探一样寻觅着,查找着证据,来试图复原案发现场,来证明自己的猜想是正确的,我们渴望着一旦出现问题,就有一个“它”立刻告诉我系统到底发生了什么,而不是每天像侦探一样“加班”破案,陷入了无尽的恶性循环。而“它”就是监控。
监控到底是什么
有时候走在路上我就在想,路边的监控摄像头,行车记录仪这些东西的诞生是基于什么原因呢?
“秩序”这是第一个浮现在我脑海中的答案。
我每天穿梭在现实世界,经过了太多的摄像头,而车上的行车记录仪一直都是开启的,但是它们并没有影响到我想做的任何事情,相反一旦出现了异常情况,这些基于时间记录的摄像头便派上了非常重要的作用,它可以取证留痕,让你在上帝视角查看异常情况的的全过程。
当然它们也可以基于大量的数据来改善现实社会的“用户体验”,例如:红绿灯摄像头它可以通过不同时间段的人流量智能的改善行人道路的等待时间,天眼摄像头可以快速定位捕捉到违法者等等,而软件系统这个虚拟世界何尝不是这样呢,如果软件系统没有这些可以辅助的摄像头,我们将会在慢慢长夜里苦苦挣扎。
那么软件系统的的监控是指什么呢?2016年 格雷格·波里尔 在Monitorama讨论会上提出:
监控是观察并检查系统及其组件随着时间的推移而产生的行为和输出。
翻译一下就是通过技术手段发现服务异常,持续优化业务可用性与用户体验。
监控的种类
如果你和我一样也想改善糟糕的系统现状,首先必须要清楚我们正在监控的是什么,只有知道你要监控的是什么,在这个上下文中就可以得到你想要的监控指标,业务是第一要考虑标准。业务不会关心你后面有多少台服务器,有多少个节点,业务只关心某个业务功能是否是正常的。
KPI 是公司衡量业务健康发展非常重要的指标,这些指标看起来可能非常模凌两可,但可以很清楚的总结出他们的关注点。
- 用户能不能正常使用应用程序?
- 用户满意吗?
- 公司在盈利吗?
- 用户量是在增加还是在流失?
例如:某汽车销售公司,他们的使命是为车主提供优质的服务,用户来使用他们的APP或者网页,通过行驶证,身份证绑定自己的爱车,绑定成功后通过APP控制他们的车辆,并且还会定期和用户互动,来增加用户的粘性,会给用户发放卡券,用户还可以通过不同的活动获得积分,积分可以在APP商城购买心仪的商品,同时还会定期为不同的客户定制不同的活动页面来增加用户的体验。
通过上面的例子我们可以评估我们的监控指标,首先我们从业务指标开始,我们可以得到一些基本的业务KPI:
业务KPI |
---|
当前在线用户 |
用户登录 |
用户绑车 |
操控车辆 |
卡券的使用量 |
积分够买商品 |
这些指标可以衡量这个APP的一些核心功能,而且这些功能在系统架构一定存在着的不同映射,比如有APP前端,后端服务,第三方系统,数据库服务等等。这些指标可以很好的预示某个地方可能会出现问题。
例如绑车依赖的第三方服务不可用,或者服务比正常速度慢,那么用户绑车功能一定会受到影响,绑车量可能会下降。随着时间推移这些指标应该是稳定的,通过直觉就能判断对错。虽然这些指标可能无法告诉别人出现了什么具体问题,但是它们在表达业务的整体健康状况非常有用。
跟踪这些指标的另一个好处是,你可以快速看到应用程序问题对用户产生的影响。
那么如何实现上述业务KPI的监控呢?我们可以把业务KPI和技术指标绑定起来,达到最终业务KPI的监控,而技术指标是更细粒度的业务KPI的表现,他们不假设知道问题是什么,只是给你更多的参考,暗示你程序可能会出现问题。
业务KPI | 技术指标 |
---|---|
当前在线用户 | 当前在线的用户 |
用户登录 | 登录失败,登录延迟 |
用户绑车 | 系统原因导致的绑车失败,绑车延迟 |
操控车辆 | 系统原因导致的指令不及时,车辆数据是否有延迟 |
卡券发放 | 核销失败,核销延迟 |
积分够买商品 | 购买失败,购买延迟 |
通过上述技术指标可以得到类似如下的监控策略
- 前端监控
- 应用程序和服务器监控
- 安全监控
- 告警
前端监控
拿用户绑车这个KPI来说,我们可以在前端功能点收集一些技术指标,比如绑车从打开到加载完毕所用的时间,从选择证件照片到最终绑车完成所用的时间,这些技术指标不单单是技术,它是和业务紧密相关的。
作为软件工程师我们都知道应用卡顿一定对业务不利,但是站在客户的角度如何让他相信将时间花在前端性能上是值得的?
Aberdeen Research 2010年的一项研究,页面加载时间每延迟一秒,平均会导致页面浏览量下降11%,转换率下降7%,客户满意度下降16%。该研究发现,当页面加载时间每缩短100毫秒,收入就会增加1%.
世界上最大的图片社交分享网站Pinterest 在2017年3月展开一个有关前端性能的项目,同样得到一个令人震惊的结果:在感知等待时间缩短40%的情况下,SEO流量增加了15%,注册人数增加了15%。
这深刻体现了前端性能调优的重要性,所以前端监控是不可忽视的一环。
应用程序和服务器监控
假设例子中汽车销售公司的基础架构如下图
可以得到一些技术指标样例如下:
- 用户绑车的是执行时间
- 用户绑车失败的次数
- 用户绑车失败的原因
- Database的每秒事务数
- Database的查询延迟
- Redis的查询延迟
- 负载均衡的每秒请求数
- 错误的异常堆栈追踪
- 我们使用的这些组件的守护进程的服务日志
- 等等
实现上述KPI的工具业界已经太多了,比如Elatic APM ,Cat、Pinpoint、SkyWalking、Kamon等等,这里不讨论具体的工具的使用。
以下是一些APM的基本功能
统计出用户绑车过去一段时间失败的次数,以及具体失败原因,最主要可以根据这个KPI去追溯具体导致失败的具体原因,而你的代码里并没有日志成山。
如图我模拟了单次绑车时间高达了11秒
当你收集到这些指标,就可以非常轻松的优化系统,因为你非常清晰知道造成该现象的具体原因他都记录在你的监控系统里。不再需要盲人摸象,像侦探一样窥探你自己的系统。
同样的当你给客户提供足够多的数据和证据,就可以根据这些数据来反哺业务,优化业务流程,改善系统,从而提升用户体验。
安全监控
不同的行业对数据都拥有不同的合规的要求,例如金融行业的财务数据,用户个人隐私数据,信用卡数据等等而为了保证数据是合规的,无论如何这些数据不能通过系统的任何方式泄露或者被窃取出去,这样就要考虑到安全这个维度。
安全监控的常见指标样例如下:
- 用户绑车的证件信息加密
- 应用服务器白名单
- 日志聚合服务是否有被泄露的风险
- 服务器漏洞扫描
- 应用程序是否遭到相同IP的不停攻击等等
- 数据库漏洞扫描
告警
告警是监控中最关键的一环,因为上面的监控机制做的再完美,可能也需要人工值守的方式去查看那些监控的指标,
而告警是一种通知的方式,它不需要人工轮询的方式去查看监控指标,但是如果这一环做的不够好反而会事半功倍。
比如可能半夜会把你叫醒,被叫醒后发现好像只是一个警告,但是并不太影响应用程序,随着时间的增加,这种类型的告警可能变得非常多,而到那时候你就又变得夜不能寐了,其实我们常讨论的告警其实分为两类:
- 第一种需要你立刻处理,否则系统无法运行,它可能是发短信,或者打电话的方式来通知你
- 第二种不需要你立刻处理,它可能只是一个警告,但并不影响系统的运行,例如同步某系统一段时间的数据失败,但是并不影响业务,你可以第二天再来处理
如果告警的分类是需要你紧急处理的,一定不要使用电子邮件,因为大量的电子邮件会造成告警疲劳而且很难及时响应,要使用电话或者其他及时通信系统。
无论你使用什么手段发送告警通知,一定要优化告警,尝试告警的自动修复机制,例如数据同步失败告警发生了,可以尝试优化系统的重试机制,成功了就简单系统记录一下,减少人为介入的这种警告。
告警的终极目标是消除告警,而不是增加更多的告警来体现告警的KPI
监控反模式
既然软件系统的监控就是查看系统的行为,那么我相信任何一个项目都拥有监控。
我见过太多这种系统,他们拥有非常多漂亮的工具,虽然记录了系统负载,CPU使用率,内存使用率这样的指标,但是服务还是在你不知情的原因停止运行,习惯性的忽略警告信息,因为他们好像并不重要的。
造成这种局面的大部分原因是配置监控的成员没有完全理解系统的业务,所以他们只能配置最简单和最容易的检查项。但是系统一旦出现问题开发人员又要去日志系统中查找日志,查找错误的根本原因,更可怕的是,你的日志系统里没有你想要的日志,那么只能添加更多的日志来从新部署上线,周而复始系统磁盘空间也在疯狂增长,但是又没有人敢轻易删除日志,因为这就是项目的监控呀。
为了避免监控形式化,有几点想要分享
- 避免船货崇拜,不要什么工具都尝试用,适合自己的项目的就是最好的
- 避免银弹思维,不要奢望一个工具解决你所有问题,我们手中应该个有工具箱,而我们就是那个知道如何使用它们的工程师
- 避免重复发明轮子,不要总想着自己去做,因为成本真的很高,尤其是要避免遇事不决,日志裁决这中方式解决问题,有时候知道太多对系统也是一种灾难
- 一定要从业务角度出发
总结
监控是软件系统的摄像头,它可以帮你维护虚拟世界“秩序”,而秩序也就是现实世界的业务,在正常情况下业务正常运转,一旦出现异常时它又可以提供足够的证据告诉你发生了什么。
就像自动化测试默默守护代码一样,而监控是在默默守护着它所信仰的秩序。