Open WangShuXian6 opened 3 years ago
将讨论反模式、设计模式、告警以及其他内容。这一部分会为监控生涯奠定基础。
沉迷工具不会带来更好的监控;
监控是所有人的任务,而不是团队或部门中单独一个人的;
杰出的监控远远不止在“嗯,我们有监控”的方框中打钩那么简单;
监控无法修复故障;
缺乏自动化,你就一定会错过重要事情。
可组合监控是现代监控设计的第一种模式。 原则很简单:使用多个专门的工具并且将它们松散地组合在一起以形成一个监控“平台”。 这种模式和很多一体化工具(特别是其中的代表 Nagios)正好相反。 可组合监控可以视为 UNIX 理念的一种实践。
编写专注于一件事并能将其做好的程序;编写互相协作的程序。
可组合监控最大的好处是不用长期坚守一种特定的工具或工作方法。 如果工具不再满足你的需求,你就可以移除它并用另一个工具来替换,而不用替换整个平台。 这种灵活性虽然会让架构变得更加复杂,但所带来的好处远远超过所付出的成本。
数据采集
数据存储
可视化
分析和报告
告警
数据采集组件用于采集数据,它有两种主要的实现方式:推送或拉取。
在拉取模型中,会有一个服务请求远端的节点来发送其数据。中心服务负责在这些请求发生时进行调度。
一个用例是应用程序监控中的 /health 端点模式,该模式向一个 HTTP 端点展示应用程序的指标及健康信息,这可以通过一个监控服务、服务发现工具(比如 Consul 或 etcd),或一个负载均衡器来轮询。
当涉及指标时,基于拉取的机制有一个恼人的缺点:拉取模型很难横向扩展,因为它需要中央系统不断跟踪所有已知客户端,处理调度,并解析返回的数据。
推送模型是一个客户端(服务端、应用程序等)推送数据至另一个位置。客户端可以基于定时任务或随事件触发的方式来推送数据。
syslog 转发是一个基于不规则事件推送模型的好例子,而受欢迎的指标收集代理工具 collectd 则是一个基于定时任务推送模型的例子。
由于没有中央轮询器(横跨多个轮询器协调轮询调度很棘手,而且你仍然要维护需要轮询的所有节点的主干清单),因此在分布式架构中的推送模型(例如在云环境中的系统)更容易实施横向扩展。 推送数据的节点只需要知道往哪儿发送数据,而不需要知道接收端的底层实现。因此,推送模型拥有更好的冗余性和高可用性。
使用基于推送的工具更易于操作和推理
对于可能收集的数据内容,主要关注两种类型:指标和日志
指标有两种不同的表现形式。
计数器是一个不断增长的指标。 计数器是有上限值的。一旦达到了上限值,计数器就会“覆盖”(或“翻转”)并重新从零开始计数。
关于这个现象的一个技术实例是 32 位的网络接口计数器。在 100% 的负载下,一个 1 GB 的网络接口上的 32 位计数器会在 32 秒内翻转。
车上的里程表就是计数器的一个例子。 指标非常适用于记录网站累计访问用户数这类事情。 网络接口上的流量也是计数器的一个例子
仪表是时间点值。
车上的速度表就是仪表的一个例子
仪表的特性有一个大的缺陷,即它无法显示任何过去的值,也无法预测将来的值。 但是,通过将仪表的值存储在一个时间序列数据库(TSDB)中,你可以随后提取它们,并将这些数据以图表的形式绘制出来。 你所使用的大多数指标是仪表类数据。
日志本质上是带有(但愿有)关联的时间戳的文本字符串在事件发生时用以指代事件的记录。 日志中包含的数据要比指标多得多,且经常需要经过某些解析来获取信息,而不能直接读取。
日志有两种类型:非结构化日志和结构化日志。
大多数日志应该进行结构化并发送到一个能够解析它们的系统中。
日志收集可以通过多种不同的途径完成,但是最常见的(也是最容易的)方法是在系统上设置日志转发。
将日志转发到一个远端的日志服务能够让你在一个地方分析所有的服务器日志,并为你提供一个更完整的 Web 服务器的概况。
收集完数据后,你需要空间来存储它。
作为时间序列数据,指标通常存储于 TSDB 中。 TSDB 是一种专门用于存储时间序列数据的数据库,这些数据基本上是由时间戳(测量值被获取的时间)以及值组成的键值对。 这种键值对称为数据点(datapoint)。 两款常见的 TSDB:Round Robin Database(RRD)和来自 Graphite 的 Whisper。
许多 TSDB 会在一个特定的时间周期后“归纳”或者“老化移出”数据。这意味着随着数据的老化,多个数据点会压缩至一个数据点。>一种常见的归纳方法是平均法,而有些工具支持其他类似数据点求和的方法。
指标汇总是妥协的结果:存储原生状态的指标会消耗大量的磁盘资源,无论是在存储上,还是在从磁盘读出所有数据点以便在图中使用的所需时间上。
对于运行数据,你更关注的是近期的事件,而对于久远的事件,你只会关注概况。
日志存储有两个不同的特点。有些系统将数据存储为普通的平面文件。 高级的解决方案是将日志文件存储于搜索引擎(例如 Elasticsearch)中。
指标的存储是廉价的,日志的存储却是昂贵的。每天产生 TB 级的日志很常见。 对日志进行压缩并设置合理的保留策略会有所帮助
市面上有大量的仪表板产品和框架,例如 Grafana 和 Smashing。
时间序列数据的最常见的可视化表现形式是线状图(也叫带状图), 以表格格式、条形图、单数甚至纯文本来显示数据都有它们的价值。 大多数时候,在运维/软件工程领域使用线状图。
不要用饼状图 饼状图主要用于实时快照的可视化。它不包含任何有关历史或趋势的上下文,所以最适合用于表现不经常变化的数据。 饼状图最常见的用途是显示数据在总体中的比例,但即使如此,在这方面往往也是条形图的表现形式更好。
最好的仪表板会专注于显示某个单独服务(例如内部邮件系统或企业网络路由拓扑)或单个产品(例如一个单独的应用程序)的状态。
对于某些类型的监控数据,超越简单的可视化并进入分析和报告领域可能会有用。
最常见的用例之一是对应用程序和服务在服务层可用性(SLA)上进行确定和报告。SLA 是你和你的客户(无论是外部付费客户还是另一个内部团队)就应用程序/服务的预期可用性达成的协定,通常逐月确定。2 根据这个协定,可能会有关于不符合 SLA 的合同性惩罚。没有惩罚条款的 SLA 通常被认为是为了更多的“命中目标”。不管惩罚与否,重要的是保证你的监控数据是完整和精确的,以便能够有效地报告可用性。
建议将组件作为一个整体来计算其可用性,并且忽略底层冗余组件的可用性。这样计算过程就会变得更简单,而且直接回答了你真正关心的问题。
可用性 = 正常运行时间 / 总时间
,总时间是该组件正常运行时间和停机时间的总和。计算得出的结果是一个衡量可用性的百分数。AWS EC2 对于单一云区域只提供 99.95% 的 SLA,这就意味着每年差不多有 4 个小时的停机时间
监控是为了提问。
监控不是为了生成告警而存在的,告警只是其中一种可能的结果。 考虑到这一点,记住你收集的每个指标以及图表不需要有一个对应的告警。
应用程序以及基础设施是复杂的,它们带有大量运转的零件,所以哪里都有可能出现问题。 有太多的地方需要部署监控,但是有一个最适合开始的地方:用户
尽可能地贴近用户开始监控
添加监控的最佳地点首先是用户和应用程序交互的点。 用户不会关心应用程序实现的细节,而会关心应用程序是否可用。因此,首先要从他们的角度看问题。
运行监控的最有效的事情之一就是 HTTP 响应码(尤其是 HTTP 5xx 这一类),在那之后来监控请求时间(也叫延迟)也很有帮助。这些监控不会告诉你出了什么问题,只会告诉你问题出现了并且正在影响用户。
从用户的角度开始考虑,但也需要迅速把精力放在测量组件(例如那些 Web 节点以及工作者节点)上。 你可以随心所欲地将其进行深入和扩展,但每次都要首先问自己,这些指标将如何展示对用户的影响。
监控的定义:监控是长期观察并检查一个系统及其组件的行为和输出的活动。
告警仅仅是实现这个目标的一种途径。
系统指标倾向于尖峰型,所以在原始数据点上创建告警往往会产生大量的误报。 为了解决这个问题,需要经常应用滚动平均数来平滑数据(例如,把 5 分钟数据点的值平均到一个数据点上)。 很不幸,这又会导致我们丢失粒度,并且偶尔会错过重要事件。
虽然做好告警很困难,但是一些关键的技巧会让你走在正确的道路上。
不要用邮件发送告警。 撰写运行手册。 并非所有的告警都可以归结为一个简单的阈值。 要经常重新评估告警。 使用维护周期。 在发送告警之前先尝试自动修复。
通过一些调整来改善待命值班的体验也不是很难。
应该优先为公司构建一个简化的、可用的事件管理流程。
当人们谈起告警时,根据语境,他们说的其实是两回事。
1.告警意味着把某人叫醒 这类告警要求人们立即采取行动,否则系统就会停机或一直处于停机状态。
2.告警意味着仅供参考 这类告警不要求人们立即采取行动,但是当其发生时应该通知某人。例如:一个夜间备份任务失败。
第二种类型的告警并非真正的告警,它是一条信息。
告警应唤起紧迫感,并要求接收者立即采取行动。其他所有事情最终都可以归结为一个日志条目、一条发送到你们内部聊天室的消息或一个自动生成的凭据。
停止使用电子邮件发送告警; 撰写运行手册; 任意的静态阈值不是唯一的方法; 删除告警和优化告警; 使用维护周期; 优先尝试自动修复。
通过电子邮件发送告警会干扰所有人,并导致告警疲劳。
只要对告警所要求的目标和响应给予适当的关注,就可以轻松减少所有告警的干扰。
告警类型
要求立即采取响应/行动
把这类告警发送到你的随身通信设备(不管是手机、PagerDuty 还是手头的其他此类工具)上。 这是真实的告警。
把这类告警发送到内部聊天室中。 有的团队创建了用于接收和存储这类告警的小型 Web 程序以便后期回顾,并取得了很大的成绩。
把这类信息记录到日志中。
在日志中保留告警很重要,因为这样你可以随后对它们进行报告。
并非团队中的所有人都了解每套系统,而运行手册则是帮助我们了解这些知识的极好途径。
这是什么服务,这个服务做什么? 谁负责这个服务? 这个服务有什么依赖关系? 它的基础设施什么样? 它会产生什么样的指标以及日志,这些指标和日志的含义是什么? 应该为它设置哪些告警,为什么要设置这些告警?
每条告警都包含一条指向该服务的运行手册的链接。当有人响应对应的告警时,翻开运行手册就会了解发生了什么、告警的含义以及潜在的恢复步骤。
运行手册容易被滥用。如果告警的恢复步骤就像复制粘贴命令那样简单,那么你就会开始滥用运行手册了。 应该把那种修复操作自动化,或剖析出真正的问题,然后完全删除这个告警。 只有当需要人类的判断和诊断能力来解决某些问题时,才需要运行手册。
Rails 演示应用程序是一个简单的 Rails 博客应用程序,展示了一个基本的 Rails 应用程序是什么样的。 主要组件是一个数据库支持的用户管理系统和一个发布/评论系统。
代码库位于内部源代码系统中,名为 demo-app。服务所有者是 John Doe。
如果需要帮助以解决此服务的问题,服务所有者已请求成为下一个升级点。联系方式见公司联系表。
无外部依赖关系。
PostgreSQL 数据库,运行在位于 rds-123.foo.com 的一个 RDS 实例上。
Rails 4.x PostgreSQL (AWS RDS)
该应用程序发出以下指标: 用户登录(计数) 用户登出(计数) 文章创建(计数) 文章删除(计数) 评论创建(计数) 评论删除(计数) 文章创建时间(计时) 文章删除时间(计时) 用户注册时间(计时) 用户登录时间(计时) 用户登出时间(计时)
该应用程序发出以下日志:
用户通过用户 ID 登录、状态(成功/失败),以及 IP 地址 通过用户 ID 创建帖子、状态(成功/失败),以及 IP 地址 通过用户 ID 创建评论、状态(成功/失败),以及 IP 地址
用户登录失败率 当用户登录失败率在 5 分钟内超过 5% 时,将触发此告警。潜在的原因是错误的部署(检查最近的部署)或暴力攻击(检查用户登录日志以查看攻击的迹象)。
用户登录时间过长 当用户登录所需时间超过 1 秒时,将触发此告警。检查最近的错误部署或 Postgres 性能问题。
文章创建时间过长 当用户创建一篇文章的时间超过 1 秒时,将触发此告警。检查最近的错误部署或 Postgres 性能问题。
评论创建时间过长 当用户创建评论的时间超过 1 秒时,将触发此告警。检查最近的错误部署或 Postgres 性能问题。
并非每种情况都有(大多数情况没有)一个有意义的警告或紧急状态。 此外,在很多情况下,对“数据点跨过了 X 值”之类的事情设置告警毫无用处。 例如,磁盘使用率就是一个典型的例子:如果将一个静态阈值设置为“空闲空间低于 10%”,那我就看不到一块磁盘的使用率一夜之间从 11% 快速增长到 80% 的情况了。
其实还有很多其他的选择。例如,百分比变化/导数会向我们显示“一夜之间磁盘使用率增长了 50%”的情况,利用它们可以很好地处理磁盘使用率的问题。
如果使用的基础设施(例如 Graphite)拥有更强大的指标,那我们甚至可以使用移动平均数、置信带以及标准差等各种方法对问题进行一些统计。
告警带来的干扰太糟糕了,使人们不再相信监控系统,从而也导致告警被完全忽略。
长期暴露在告警中以至于对它们不再敏感时,就会出现告警疲劳。
如果一周有 10 次这样的反应,连续几个月就会导致长期的告警疲劳以及员工的倦怠
回到第一种告警类型上:是不是所有的告警都需要有人响应?
回顾过去为期一个月的告警历史。它们是什么?响应是什么?每个告警的影响是什么?有没有可以直接删除的告警?可否修改阈值?可否修改底层的检查以使告警更加精确?
可以创建哪些自动化以便彻底弃用某个告警?
如果需要对一个服务进行维护,并且预料到会触发一个告警(例如,因为它停止服务了),那么将这个告警设置到维护周期中。大多数监控工具支持这个简单的概念
注意不要屏蔽过多的告警。 发出大范围、无差别的静默所引发的问题可能比操作本身解决的问题还要多。
如果一个告警所需的最常见响应通常是执行一系列已知和记载的步骤来修复该问题,那为什么不让计算机运行这些操作呢? 自动修复是一种避免告警疲劳的极好方式,特别是当你管理一个大型的环境时,必须选择自动修复,因为雇佣更多的员工会带来高昂的成本。
有几种途径可以实现自动修复,但是最常见且最直接的方法是将所有的标准化修复操作实现到代码中,让监控系统执行对应的脚本,而不是通知某个人。如果尝试自动修复没有解决问题,这时候就再发送一个告警。
自动修复的嵌入式设备 首先设置一个检查,用于监测 SNMP 是否失效(通过抓取任意的 OID 并观察是否超时,同时确定该设备可以通过 ICMP 访问)。如果 SNMP 失效了,但是该设备仍然在网络上,那么一个脚本就会登录到传感器设备上并将它重启。要是这个方法运行完美,那传感器在几秒之内就会重新上线并且恢复所有工作。
有过待命值班经验的人都知道待命值班有多糟糕。1 假警报、含糊不清的告警以及持续的救火信息全都困扰着你。几个月之后,你就会体会到待命值班会让你筋疲力尽,从而导致一系列负面影响:易怒、睡眠不足、焦虑,等等。
作为待命值班人员工作的一部分,编辑一个前一天触发的所有告警的清单,把它们都看一遍,并思考该如何改进这些告警的触发以及某个告警是否可以被完全删掉。如果每次待命值班时都这么做,很快你的状态就会比刚开始好很多。
你必须修复好垃圾问题。
监控不会修复任何东西。出现问题以后需要你来修复它们。要跳出救火模式,你必须花费时间和精力构建更好的底层系统。系统越有弹性,令人印象深刻的故障就越少,但是要达到这种效果只能通过向底层问题投入更多的精力来实现。
1.在人们待命值班期间,只要不是在救火,就尝试把提高系统的弹性和稳定性作为他们的职责。
2.根据在上一周待命值班工作中收集的信息,在接下来的每周迭代计划会/小组会议(你们有这些会议,对吧?)上制定关于提高系统弹性和稳定性的明确计划。
以下是一个可实施的简单的轮值表。假设你的团队中有 Sarah、Kelly、Jack 和 Rich 这 4 个人。你安排了一个为期 4 周的轮值表,每个人有一周的时间处于待命值班状态,从周三上午 10 点开始一直到下一周的同一时间。这个轮值按照一个指定的顺序进行,直到每个人都有 1 周的待命值班时间和 3 周的非待命值班时间,之后不断循环。
强烈建议让软件工程师也加入待命轮值,其背后的用意是避免出现“互相踢皮球”版本的软件工程。如果软件工程师意识到了待命值班带来的烦恼,并且他们自己也是轮值的一员,就会激励他们开发出更好的软件。这里也有更微妙的原因:共鸣。把软件工程师和运维工程师放在一起会在某种程度上产生共鸣,而且他们也不愿意让真正理解和喜欢的人失望。
使用 PagerDuty、VictorOps、OpsGenie 这样的软件来改善你的待命值班。这些工具可以帮助你构建和维护升级路径和计划,并自动记录事件以供后期回顾。
在待命轮值结束时立即给予员工一天的带薪假期。待命值班非常伤脑筋,一天的恢复时间是员工应得的。
对于团队的待命轮值工作要给予额外的薪水。在医疗行业待命轮值会收到额外的薪水是标准惯例,金额范围从护士每小时额外两美元到神经外科医生每天额外2000美元不等。
待命值班会对生活产生很多消极影响,包括睡眠质量变差、陪伴家人的时间减少,等等。对行业中最糟糕的部分给予额外的补偿是基本的公平。
事件管理是对发生的问题进行处理的一种正式方式。技术界有多种框架用于事件管理, 其中最受欢迎的是 ITIL:意外中断 IT 服务或降低 IT 服务质量。
事件定义 事件记录 事件归类 事件优先级 初步诊断 如有必要,升级到 2 级支持 事件解决 事件结束 在整个事件发生期间与用户社区进行沟通
事件定义(监控识别一个问题) 事件记录(监控自动为该事件打开一个工单) 事件诊断、分类、解决,以及关闭(待命值班人员排查故障,解决问题,通过注释和其他数据解决该工单) 根据需要,在整个事件中进行沟通 在事件解决后,想出补救计划以便增强系统弹性
对于大多数能够很快被解决的事件,这个流程运行良好。那么那些在实践中造成中断并持续不止几分钟的事件该怎么办呢?因此一组明确定义的角色就变得至关重要。每个角色都具有单一的功能,他们不应该执行双重任务。
事件指挥官的工作就是做决定。他们既不会参与任何调查和修复工作,也不会与客户或内部进行沟通,只会监督中断调查。通常待命值班人员在事件开始时就会充当事件指挥官的角色,有时候事件指挥官的角色会移交给别人,尤其是当待命值班人更适合其他角色时。
记录员的工作就是记下发生的一切。什么人在什么时候说了什么,做出了哪些决定,后续事项有哪些被确定下来了。同样,这个角色也不应该参与任何调查和修复工作。
通信联络人的工作就是向干系人(不管是内部人员还是外部人员)传达情况更新。在某种意义上,他们是处理事件的人与想要了解事态进展的人之间的唯一联络人。这个角色的一个作用是防止干系人(例如经理)直接向努力解决问题的人询问情况更新,进而干扰事件调查。
这些人才是真正在处理事件的人。
关于事件管理的角色,一个常见的反模式是遵照公司或团队的日常层级架构来组织。例如,团队经理经常充当事件指挥官。但是,事件管理的角色其实没有必要按照日常的团队角色来分配,相对于让团队经理充当事件指挥官,我更鼓励让他充当通信联络人,而让团队中的一名工程师扮演事件指挥官。这样做往往更合适,因为经理可以保护团队不受外界干扰,并将决定权交给最适合评估风险和权衡利弊的人。
事件发生后,就事件本身进行一次讨论是明智的做法(发生了什么、为什么会发生、如何修复,等等)。对于某些事件,尤其是关于业务中断的事件,适当的事后分析是个好主意。
事后分析过程中有一个很不好的习惯:责备文化。如果你曾经工作过的团队,人们因为失误受到惩罚或感觉自己被迫对问题域负责,那么你可能处于一种责备文化中。
统计学的基本课程简单易懂,对监控工作也非常有用。
Nagios 的流行和影响阻碍了许多团队对监控的改进。使用 Nagios 设置告警非常简单,但常常没用。 并不是要指责 Nagios,只是 Nagios 因其影响力,成了许多工具的预期标准。还有很多其他的工具也有同样的问题。 像震荡检测这样的机制只是用来掩盖糟糕的告警机制
现代监控栈的核心原则之一是不要丢弃监控服务提供的指标。 过去,Nagios 不会记录它从检查中获取的值,所以你不知道趋势是什么 在 TSDB 中记录这些数据已经很常见了
不要让监控系统在收集数据的同时还要根据设置的阈值去执行检查(这是典型的 Nagios 行为),而是将它们解耦为两个单独的功能。
需要某些组件收集数据并定期将其写入 TSDB 中。 不要让 Nagios 直接针对主机去运行平均负载检查,而是针对存储在 TSDB 中的指标来运行。 此方法的新功能之一是不必再仅仅针对最后一次报告的值运行检查,而是可以针对更多的值。因此你可以利用基本的算术和统计函数来更准确地检测问题。
统计方面的大部分工作是找出哪种方法对数据最有效,并且不会导致错误答案。
平均值,通常称为平均数(技术上称为算术平均值),用于在不检查数据集中的每个单一条目的情况下确定数据集大体是什么样子。计算平均值很容易:将数据集中所有的数字相加,然后除以它的条目数量。
时间序列中一个常用的平均法是移动平均法。它不是获取整个数据集并计算平均值,而是在新数据点到达时计算平均值。这个处理过程附带产生的效果是它让尖峰图形变得平滑。TSDB 中也使用此处理过程来存储汇总的数据,而且每个时间序列图形工具在查看大量指标时也会用到它。
从磁盘加载几千个数据点来显示一个图形需要很长时间,而且在查看长达 4 个星期的数据时,你可能并不会关心粒度。
通过在数据集中隐藏极端情况,我们可以创建一个更容易识别规律的数据集,但同时也失去了可能有价值的数据点。更加平滑的曲线以牺牲准确性为代价来实现更好的可视化效果。
当平均值不准确时,中位数就有了用武之地。本质上,中位数是数据集的“中间”值,在实际中经常被用来精确地分析整个人口的收入水平。
当处理个别数据变动较大的数据集时,中位数通常比平均值更能代表数据集。
要计算中位数,首先必须按升序对数据集进行排序,然后使用公式 (n+1)/2,其中 n 是数据集中的条目数。3 如果数据集包含奇数个条目,则中位数就是中间项。但是,如果数据集包含偶数个条目,那么中间的两个数字将被取平均值,结果得出的中位数值就不是原始数据集中的数字了。
数据的季节效应是指数据点采用一种重复的模式。例如,如果要记录一个月里每天的通勤时间,你会注意到它有一个特定的模式。可能每天的时间不同,但模式每天都一样。你可以每天用这类知识来帮助你计划和预测未来:因为你知道自己的通勤时间通常需要多久,知道需要什么时候出发以便准时到达办公室。没有这种季节效应,你就不可能规划自己的一天
7 天时间的 Web 服务器请求的季节效应
根据以前的数据,如果知道 Web 服务器在给定的工作日中每秒大约处理 100 个请求,那么也可以假设这个数字的一半或两倍可能是值得研究的事情,因为有些工具允许你以滚动周期的方式应用此方法,从而比较现在的数据点与以前某个时间段的数据点,例如将当前的每秒请求数与一周前、一天前甚至一小时前同一时间的每秒请求数进行比较。那么,对于具有高度季节性的工作负载,你就可以对未来的情况进行假设。
但并非所有的工作负载都具有季节性。事实上,有些工作负载根本就没有明显的季节性。
分位数是描述数据集中一个特定数据点的一种统计学方法。例如,第 50 个分位数是数据的中间点(也叫中位数)。运维中最常见的一种分位数是百分位,即以百分比的形式描述数据集中的一个点(从 0 到 100)。
百分位数通常出现在计量带宽计费和延迟报告中,在两者中的计算方式也是相同的。首先,数据集按升序排序,然后删除前 n 个百分比的值。接下来最大的数字是第 n 个百分位数。4 例如,带宽计量通常以第 95 个百分点为基础计费。为了计算这个值,我们会去掉前 5% 的值。这样做是因为带宽计量中的利用率具有突发性,所以按照 95% 的百分位数为带宽付费是比较公平的。类似地,使用百分位数进行延迟报告可以让你很好地了解大多数用户的体验,而忽略少数异常的情况。
这是一个粗略的定义,掩盖了基础数学的一些微妙之处。关于百分位数的更详细的处理方式,可以在“Statistics For Engineers”(Heinrich Hartmann,美国计算机学会通讯,ACM 第 59 卷,7 号议题)一文中找到。
不能平均一个百分位数 由于百分位数计算的特性,你需要删除一些数据。因此,不能将百分位数放在一起取平均值,因为这样会丢失其中一些数据,进而导致结果不准确。换句话说,算出每天的第 95 个百分位数,然后将 7 个这样的百分位数取平均值,并不能得出一周的第 95 个百分位数的准确值,你需要根据整个星期的所有值来计算周百分位数。
虽然使用百分位数可以让你了解大多数值是什么(例如,当涉及延迟时,大多数用户的体验),但是不要忘记你丢弃了大量的数据点。当使用百分位数来判断延迟时,计算最大延迟也是有用的,它可以用来查看用户体验到的最坏情况。
标准差是一种描述数值离均值远近程度的方法。虽然这乍一听起来很好,但是存在一个问题:虽然可以为任何数据集计算标准差,但是只有正态分布的数据集才会产生期望的结果。在非正态分布的数据集中使用标准差可能会导致意外的结果。
分布只是描述数据集模型的统计术语。 非正态分布通常具有偏态,也就是说,数据集可能有多个峰值、长导入和长尾等。
正态分布和标准差(维基百科,CC BY 2.5 协议)
要处理的大多数数据不符合标准差适用的模型。最好直接跳过使用标准差,而不是浪费时间思考为什么计算结果不是所期望的。
平均值是你会用到的最常见和最有用的函数,因为它广泛适用于各种不同的数据集。对于某些数据集,中位数也非常方便。 季节效应只不过是讨论基于时间的数据模式的一种特殊方式。看看你的交通日志,保证你会看到季节效应。 百分位数有助于理解你的大部分数据是什么样子的,但是要小心,它们在本质上忽略了极端的数据点。 虽然标准差是一个有用的工具,但对于你经常处理的数据类型来说不是很有用。
它在两个方向上都有很大的偏态吗?也就是说,数据点是否聚集在图的两端 ? 极端异常的值常见吗? 数据点有上界和下界吗?例如,理论上延迟的衡量在正方向上实际是可以无限大的(低端到 0 即为界限),而 CPU 利用率的百分比在两端都有界限(0% 和 100%)。
探讨监控什么以及如何监控。
从外部开始监控的方法比像大多数人那样从基础设施深处开始监控的方法好,因为它能让你立即知晓人们提出的实际问题(“站点启动了吗?”“用户受到影响了吗?”),并为不断深入研究打好基础。
关键绩效指标(KPI)是一种衡量公司认为对业务健康发展非常重要的各个方面的整体表现如何的指标。像应用程序和基础设施的性能指标那样,KPI 会告诉你业务的表现如何。
客户能不能正常使用应用程序/服务? 公司是在盈利么? 公司是在壮大、萎缩还是停滞不前? 利润有多少?是在提高、降低还是维持现状? 客户满意吗?
衡量来自客户的月度经常性收入。这最常被 SaaS 或托管服务公司使用。
衡量每位客户的总收入,通常以年度为基础。这对于大多数类型的公司来说是一个很好的衡量标准。
不言而喻,你可能想让这个数字不断增长。
衡量用户/客户满意度。净推荐值(NPS)要求用户从 1 到 10 打分,10 分是最好的(也称为李克特量表),说明他们向其他人推荐服务/应用程序的可能性有多大。有了足够多的回复,就可以知道用户对服务/应用程序的满意程度。净推荐值还可以在更细粒度的级别上使用,例如,在含有最近解析的服务台票据的跟进电子邮件中。
衡量客户在整个生命周期内的总价值。如果与客户进行交叉销售,那么这个数字就会上升。虽然这种衡量与每位客户的收入密切相关,但是以生命周期为基础的。
衡量服务客户的成本。你自然希望这个数字随着时间的推移而减少,因为这意味着你在提供服务/应用程序方面变得更有效率,因此利润也更高。如果你正在运行一个 SaaS 应用程序,那么确定运行每个用户需要多少基础设施成本是一个很好的起点。
衡量获得一位客户/用户的成本。这通常关乎营销团队的生死存亡。
衡量有多少用户离开了应用程序/服务。一定程度的用户流失是不可避免的,这是做生意的自然规律,但是高用户流失率可能表明应用程序出现了问题,无论是从产品角度(应用程序不是很好)、性能角度(应用程序太慢)还是成本角度(应用程序太贵)来考虑。流失率很大程度上取决于业务性质,所以最好是和自己过去的服务比较,而不是和其他公司的服务比较。
衡量应用程序/服务的活跃用户。活跃用户可能很难定义,而且这种衡量在很大程度上取决于业务性质。此指标通常是对多个指标,比如日活跃用户(DAU)、周活跃用户(WAU)和月活跃用户(MAU),进行跟踪。理想情况下,你希望这个数字不断增加。
一个衡量公司整体开销的标准。这个数字包括从工资到办公地点的一切开销。如果是一家创收公司(例如初创公司或企业),那么通常不使用这个数字。
运转率通常与资金消耗率联系在一起,用于衡量一家公司在当前支出水平下资金耗尽的时间,通常按月计算。如果是一家创收公司(例如初创公司或企业),那么通常不使用这个数字。
衡量一个特定市场有多大。它基本上是一个估计值,通过确定将某个产品卖给市场上的所有人所能产生的总价值(以美元计)来得出。这取决于公司如何定义其市场。
去除销售成本(COGS)后利润的衡量方法。如果是一家 SaaS 公司,那这个数字通常大于 80%,在 90% 左右。对于 SaaS 公司来说,销售成本基本上就是运行应用程序/服务的成本。如果是一家实体商品公司,那销售成本就是生产这些商品的成本,不包括工资或办公场地费用。你可以进一步用这个数字除以用户的数量,以确定当前每位用户的成本。
每个指标都用于回答不同的问题(或者从不同的角度回答相同的问题)。根据业务的不同,有时很难获得这些数据。虽然这些指标有时很敏感,你自己可能也无法访问这些数据,但是它们仍然有助于你理解从高管的角度来看,应该衡量哪些内容,以及为什么这样衡量。
下面的示例将展示首先从外部进行监控的确切含义以及它为何如此有用。接下来看看一些知名公司是如何采用这种方法的。
Yelp 是一个将人们与当地商家联系起来的在线平台,其用户有两种类型:搜索本地商家的用户(可能提供评论)和管理商家页面的企业主(可能提供对评论的回应)。企业主可以免费“申请”他们的商家页面,Yelp 则通过向企业主收取广告费用获得收益。
执行的检索数 发布的评论 注册用户 申请的商家页面 活跃用户 活跃商家 已购买的广告 发布的评论回应
所有这些指标都可以衡量 Yelp 应用程序的核心功能,并且根据架构的不同,它们可能都有一个到后端服务的强映射或松散映射。 这些指标可以很好地预示某个地方可能会出现问题,因为如果搜索功能中断或比正常速度慢,那么执行的搜索数量可能就会下降。>随着时间的推移,这些指标应该是相对稳定的,你很容易了解它们,凭直觉就能判断对错。 想象一下,如果把它们都放在办公室的电视上让所有人观看,那么任何路过的人都能立刻感觉到事情是好是坏。 虽然这些指标无法告诉任何人可能出现了什么具体问题,但是它们在指示业务的整体健康状况方面非常有用。
跟踪这些指标的另一个连带作用是你将快速看到后端问题对用户产生的影响。 有多少次当你看到某些后端服务速度变慢时,想知道这对用户会产生哪些影响? 如果有了这些指标,那么回答这个问题就像打开仪表板一样简单。
Reddit 是一个社交网站。用户可以在没有账号的情况下阅读 Reddit,但是发布帖子、评论、投票或私信都需要账号。Reddit 通过广告和 Reddit Gold(一种为用户准备的高级账号)获得收入。Subreddit 是无限制的,可以自由创建,但也需要一个账号。
当前在线的用户 用户登录 提交的评论 提交的帖子 发起的投票 发送的私信 已售 Gold 账号 已售广告
Reddit 的指标与 Yelp 也没有相差太多
现在,你已经开始了解自己能为公司做些什么了。这些指标本身并不完美,但它们确实衡量了用户 / 客户的交互和参与度。如果继续按照这种思路深入研究,会发生什么呢
回到上面 Reddit 的例子。就其本身而言,跟踪用户登录很好,但是有没有办法可以获取到关于用户登录性能的更具体的指标呢?我认为跟踪用户登录失败就可以做到。
跟踪用户登录将同时显示成功和失败的登录。这很好,但是如果负责处理用户登录的后端服务出现了问题,那这个指标就不会显示出来。单独跟踪用户登录成功和失败则更好,因为它有助于我们了解应用程序是否在工作。
接下来看看 Reddit 的指标,它有更多的粒度 业务KPI与技术指标绑定
业务KPI | 技术指标 |
---|---|
当前在线的用户 | 当前在线的用户 |
用户登录 | 用户登录失败,登录延迟 |
提交的评论 | 提交评论失败,提交延迟 |
提交的帖子 | 提交帖子失败,提交延迟 |
发起的投票 | 投票失败,投票延迟 |
发送的私信 | 私信发送失败,发送延迟 |
已购 Gold 账号 | 购买失败,购买延迟 |
已购广告 | 购买失败,购买延迟 |
虽然我们已经忽略了当前用户,但这个指标仍然非常有用,因为它提供了关于站点流量水平的线索。
新的指标都是关于故障率和延迟的。如果你愿意,可以跟踪成功率,但是失败率更能直接适用于我们的目标。延迟是极好的跟踪对象,因为它可以很好地预示即将出现的问题。
这些新指标在比以前更细粒度的层面上回答了应用程序是否工作的问题。它们并不假设知道问题是什么,只是暗示可能会出现问题。
监控并不是可以事后再附加的东西。要了解应用程序和基础设施的性能,必须事前就对其进行设计。
你能想象如果福特公司制造了一辆无法测量油箱有多少燃料或者无法知道车速的汽车会怎样吗?这些问题显然不是在车辆制造完成后再去考虑的,而是在车辆设计时就要考虑到。事实上,现代汽车与现代软件非常相似:ECU(发动机控制单元,又称作“计算机”)是一套完整的软件,负责分析大量来自传感器的输入,并调整向汽车其他部件的输出。ECU 的核心功能完全依赖于向它反馈测量数据的传感器,这允许 ECU 调整其对各种关键组件的控制。从计算机时代开始,车辆在设计时就在其中安装了监控系统。
我们有能力修改应用程序和基础设施以添加更好的监控,随着时间的推移,我们会不断对其进行改进。如果应用程序没有公开所需要的指标,请亲自动手修改应用程序。
即与人交谈,它能确保你理解应用程序是如何工作的,以及衡量什么是重要的
与工程领域以外的人进行交谈可以让你走出工程领域的泡沫,即使时间很短。理解工程之外的观点总是有价值的。
产品经理往往对高层次的问题有最深入的理解。 与产品经理交谈之后,再与软件工程团队的经理交谈,然后是一些高级软件工程师。 最后,你应该清楚地知道什么是监控的重点以及如何找到重点了。
假设我是新来的,我怎么知道应用程序在工作?该检查什么?它应该如何表现? 应用程序的 KPI 是什么?为什么这些是 KPI ?这些 KPI 会告诉我们什么?
另一种确定在这个阶段应该监控什么内容的方法是在一个非常高的层次上勾画出应用程序的功能。不管是使用 MySQL 还是 PostgreSQL,或者其他什么数据库,只要知道某个组件与数据库进行交互,就足以知道你可能想要测量该组件到数据库的延迟。规划出功能点(比如登录、搜索以及加载地图等)是确定从哪里开始监控的好方法。
由于每个业务都是不同的,因此没有每个人都应该跟踪的通用指标。你的目标是找到预示应用程序是否真实地按原计划工作的高级指标。
业务 KPI 是最重要的指标之一,可以有效地预示应用程序和基础设施的健康状况和性能。 如何识别公司中的这些重要指标并跟踪它们。 如何将业务指标与技术指标联系起来。
很多公司常常忽视前端监控,这是一个相当大的盲区。
前端:
所有通过浏览器或原生移动应用程序在客户端解析和执行的东西。 当你加载一个网页时,所有的 HTML、CSS、JavaScript 以及图片就构成了前端。
后端:
一个 Web 应用程序做的所有工作——从数据库取数据、执行后端代码(例如 Python、PHP),或为数据调用 API——就是后端。>>随着越来越多的工作从后端应用程序转移到前端,这个描述可能不那么准确了。
随着单页面应用程序(SPA)的大量出现,JavaScript 错误激增而 HTTP 错误没有相应变化的情况并不少见。 传统的监控方法根本不适合客户端浏览器应用程序
监控前端性能的目标不是保持运行状态,而是快速加载。 随着时间的推移,当你为应用程序中开发新功能时,前端性能会因为静态资产(也就是你所有的图像、JavaScript 和 CSS)的大小而受到影响。
如何以一种有形的、以金钱为中心的方式来传达前端性能的重要性? 你如何让人们相信将时间花在前端性能上是值得的? 你如何衡量结果?
根据 Aberdeen Research 2010 年的一项研究,页面加载时间每延迟一秒,平均会导致页面浏览量下降 11%,转换率下降 7%,客户满意度下降 16%。该研究发现,当页面加载时间达到 5.1 秒时,业务开始受到影响,而加载时间的最有效点是在 2 秒以内。
Shopzilla 和亚马逊公司也有类似的发现。Shopzilla 的页面加载时间从 6 秒降至 1.2 秒,结果收入增长 12%,页面浏览量增长 25%。 与此同时,亚马逊发现,页面加载时间每缩短 100 毫秒,收入就会增加 1%。
以 4 秒以内为目标
出色的网站性能是在线销售业务盈利的必要条件。
真实用户监控(RUM)和合成监控。
它们之间的区别与你用于监控的流量类型有关。 从技术上讲,这两种方法适用于所有监控,而不仅仅是前端监控。你也可以称它们为白盒监控和黑盒监控。
Google Analytics,就是一种真实用户监控。 从本质上讲,真实用户监控使用实际的用户流量作为监控数据。它通过在你的每个页面上放一小段 JavaScript 来做到这一点。当有人加载该页面时,脚本会把一些指标发送给监控服务。
而像 WebpageTest 这样的工具是合成监控, 它们在各种测试条件下创建假请求来生成数据。 许多软件供应商试图吹捧他们的真实用户监控和合成监控工具是独一无二的,但是它们唯一特别的地方是实现方式。
真实用户监控将是前端监控工作的核心,因为它监控的是真实用户在真实条件下所体验到的性能。
文档对象模型,通常称为 DOM。
DOM 是 Web 页面的逻辑表示。DOM 大致类似于树,每个 HTML 标签构成 DOM 中的一个节点。当请求页面时,浏览器解析 DOM 并将其渲染为可见、可读的页面
Web 页面性能很重要的原因是 JavaScript 会以各种方式影响性能。默认情况下,脚本是同步加载的。也就是说,如果正在解析 DOM 并遇到了 Githubissues.
Githubissues is a development platform for aggregating issues.
监控运维