Google SRE 生存指南笔记

《SRE 生存指南》- Nat Welch

系统中断响应与正常运行时间最大化

  • SRE 简介

SRE 是指 Site Reliability Engineer (网站可靠性工程师)。他是软件工程师和系统管理员的结合,一个 SRE 工程师基本上需要掌握很多知识:算法,数据结构,编程能力,网络编程,分布式系统,可扩展架构,故障排除。 - 百度百科

  • Site: 一个网站
  • Reliability: 被定义为”值得信赖的质量或一贯可靠的质量”
  • Engineering: 被定义为”熟练地运用技巧以达到某种目的的行动”

  • 语录

  • 故障是常态,正常才是异常

  • 个人不应该害怕事故,而是要确信如果事故发生,团队将会响应和改进系统,而不是关注发生事故带来的耻辱和愤怒。事故是我们可以从中学习的东西,而不是让人害怕和羞耻的事情!

1. 简介

  • SRE 的目标是提高服务可靠性,帮助业务实现并改善用户的服务体验
  • SRE 定义: 一个专注于熟练地维护一个网站以使其持续可靠的领域

互联网上的软件永远做不到完全可靠,这里有两个原因

  1. 互联网是一个分布式系统,各部分经常出现故障,这会影响服务可用性。
  2. 软件是人编写的,所以 Bug 不可避免,而 Bug 会导致系统宕机。
  • 可靠性层次结构 Mikey Pyramid

image-20200909223259992

  1. 用户体验
  2. 开发
  3. 容量规划
  4. 测试与发布
  5. 事后回顾
  6. 事故响应
  7. 监控

以上七点都被沟通所包围,因为每一层都需要沟通才能成功。

  • 在加入或新项目评估新服务时,请遵循下面的一系列步骤

    1. 弄清楚团队结构。团队里谁负责什么?谁说了算?
    2. 查找团队为其服务或项目编写的任何文档。
    3. 让某人绘制出系统架构图。让他们向你展示什么连接到哪个服务、什么依赖于这个项目、数据如何流经服务,以及项目如何部署。
  • 进行每个环节时提出以下问题

    • 服务有监控机制吗?
    • 团队有事故响应的计划吗?
    • 团队有事故回顾报告吗?它们存放在哪里?
    • 服务是怎么被测试的?项目有发布计划吗?
    • 有人曾经做过扩展计划吗?
    • 能使用什么工具来改进服务?
    • 当前的可靠性水平是否提供了令人满意的用户体验?

人的时间和精力都是有限的,因此你总是需要与更多的人共同协作,所以一定要慢慢来。 走慢点意味着事情不那么容易会被遗漏。你也不希望每个服务的基础还没来得及打好就崩塌了。

2. 监控

首先需要确定质量标准是什么,并确保系统持续逼近或保持在质量标准极限范围内。其次需要系统地关注这项工作而不是随机地查看一下系统。

监控的类型

  1. 指标

即性能数字,例如磁盘空间使用率、接收的数据包数量、CPU 负载等等

  1. 日志

日志用来记录事故,通常也包含一些数字与数据,但往往结构松散。有些是完整的json数据块,有些是人工格式的文本字符串

对于 Web 程序最常见的指标是错误数、请求数和请求持续时间,最常见的日志是错误堆栈跟踪。

简称

  • ERD (Error Counts, Request Counts, Request Duration)RED

  • REL (Requests, Errors, Latency)

我比较喜欢第二种称呼,容易理解

监控应用三连:

  1. 怎么知道服务处于正常状态?
  2. 怎么知道它不正常?
  3. 如何定义它是正常的?

**从基础开始

如果你的服务是 Web 服务器,那么首先要确保能够收集错误数、请求数和请求持续时间ERD

对于后台服务使用IDS (Instrusion Detection Systems) 入侵检测系统

有了基础才能开始扩展

用户通过上传服务器上传图片,后上传服务器写入本地磁盘并检查这些图片,将元数据存储到数据库中,然后将图片上传到云存储服务

上传图像服务的实例图

哪些指标可以告诉你此服务器正在执行工作?

  • 请求错误数、请求持续时间和请求总数(ERD): 因为这是 Web 服务器,也是监控的底线
  • 上传的字节数: 这将说明所使用的网络带宽。因为一些请求可能非常大,但因为并非每个请求都是一样的,我们想知道进入服务器的数据量是否开始出现峰值。
  • 图像大小(以字节为单位): 这从不同的角度提供了相同的信息。在接收到字节并对其进行处理之后,最终的图像有多大?例如,通过这种途径,如果上传客户端发生变化(例如新的 iPhone 使用更高像素的镜头,或者在图像发送前使用压缩算法对图像进行压缩),那么我们可以看到与调整网络带宽对比的效果。
  • 上传的图片: 此指标仅在看到重大变化时才有用。如果遇到了与之前差异非常大的图片,这或许可以解释是什么导致了系统服务中断。
  • 数据库中的图像元数据记录数: 将其记录数与上传的图像数量进行比较,以确保在数据库关闭时不会丢弃图像数据
  • 存储中的图像数量: 这可以确保图像最终被正确保存。如果没有正确保持,则可能云存储已关闭或存在网络问题

黑盒监控与白盒监控

在考虑要监控的内容时,通常有两个考虑的方向 - 黑盒监控和白盒监控。

黑盒监控假设监控工具对应用程序一无所知或知之甚少。通常它是一个探测或一系列常规请求,以检查事情是否按预期方式工作。

白盒监控是对代码的监测。它知道程序是如何工作的,因为它来自程序内部。如果以飞机的电子设备进行类比,那么白盒监控就是驾驶仓内的仪表,黑盒监控则是飞机飞过无线电塔是发送和接收的更新。

SLI、SLO 和错误预算简介

  • SLI Service Level Indicator 服务水平指标

对于业务来说可能是最重要的指标。对网站来说,一个常见的 SLI 是请求得到正常响应的百分比;对于其他类型服务来说,SLI 可以是性能指标,例如在 100ms 内返回搜索结果的百分比。

  • SLO Service Level Objective 服务水平目标

是围绕 SLI 构建的目标。它通常是一个百分比,并与一个时间范围挂钩。例如,时间段是最后 30 天、最后 24 小时、当前财务季度等等。它通常以一个带有一连串 9 的数字来度量。如果有人用 99.999 来形容连续运行时间,通常他们是在说服务持续运行时间的百分比。脱离了时间的度量,SLO 的意义就不是那么大了,所以我们通常假设人们所说的是之过去 30 天内滚动累计平均值。

以下是 SLO 的一些示例

  • 90% (1 个 9 的正常运行时间): 这意味着 10%的停机时间,也就是说在过去 30 天里停机了 3 天。
  • 99% (2 个 9 的正常运行时间): 这意味着过去 30 天中有 1%,或者说 7.2 小时的停机时间。
  • 99.9% (3 个 9 的正常运行时间):意味着 0.1%,或者说 43.2 分钟的停机时间。
  • 99.95% (3.5 个 9 的正常运行时间): 意味着 0.05%,或者说 21.6 分钟的停机时间。
  • 99.99% (4 个 9 的正常运行时间): 意味着 0.01%,或者说 4.32 分钟的停机时间。
  • 99.999% (5 个 9 的正常运行时间): 意味着 0.001%,或者说 26 秒的停机时间

数量级通常是 10 的倍数。我们通常把事情看成几个数量级,因为只有这样才能发现问题。例如,如果你可以做 10 件事,那么可能也可以做 40 件事,但并不意味着你能做 100 或 1000 件这样的事情。

  • SLA Service Level Agreement 服务水平协议

是企业围绕 SLO 发布的协议。通常它要求在不满足 SLO 时向客户提供货币补偿。这在软件即服务(Software as a Service, SaaS)的公司中最为常见,其他公司也会有这种情况。

发布 SLA 的公司通常也拥有比发布的 SLA 更严格的内部 SLO,这样做公司可以在一定程度上规避向客户赔付的风险。

  • 错误预算

并非每个服务都需要 SLO 和错误预算,但它们可以成为非常有用的工具,以确定何时可以安全地承担风险。有时,人们会说”信任但要验证”或”请以数据来支持你的说法”。在承担可能影响业务的风险时,这很重要。就像你想知道人力资源团队是否及为何要改变你的健康保险一样,你的同事希望知道,你只是以一种企业可以处理的方式来承担风险。

如果你走进一间没有数据的房间说”是的,一切都会好的”,这并不能令人信服。如果你能展示数据并说”你可以信任我们,因为我们在过去一个月内完成了 100 次部署而没有导致停机,并且如果这次确实失败了,也可以回滚并保证仍然在我们商定的 SLO 范围内。如果由于故障的发生,本月没有满足 SLO,那么我们将停止部署,直到事情稳定下来并重新达到我们的共识”,这就好多了。

SLO 绝不是工作被优先考虑的唯一原因。如果只追求 SLO,那么你的团队可能会发现自己与业务需求非常脱节。如果发生这种情况,请先退后一步,通过团队合作和与管理层沟通来更好地找准自己在组织中的定位。

收集和保存监控数据

  • 轮询应用程序

轮询(也称为 Pull 拉取)程序从服务器中抓取数据,然后存储并显示数据。轮询应用程序的缺点是,需要保留一些关于所有服务的记录,以备不时之需。这不是这类程序的问题,但需要考虑的问题是: 如何知道服务器上正在运行哪些服务?轮询应用非常广泛,从谷歌这样的公司到想监视自己家 Wi-Fi 路由器的人都在使用这类程序。

  • 推送应用程序

推送应用程序与轮询应用程序刚好相反。它不是从服务上主动抓取指标数据,而是被动地由服务向它传送指标数据。通常这里会存在一个中间服务,它负责把指标数据转换和聚合,然后将它们传给中央监控程序。推送应用程序常被吐槽的一点是,如果许多服务同时向它传送数据,则可能会出现问题。但推送应用程序本身没有任何问题,它们只是具有不同的架构。与轮询应用程序一样,有很多大大小小的公司使用推送应用程序,并且行之有效。

展示监控信息

收集数据并将其保存到数据存储中之后,就可以向用户展示这些数据了。许多监控工具都提供了自己的可视化系统。有些其他工具则建议你构建自己的可视化系统。一个流行的开源可视化工具是 Grafana。

无论你使用什么来实现可视化和访问指标,人们通常会使用 4 类工具来获取和共享数据。

  • 任意查询

每个人都需要能够自己创建查询来访问自己构建的指标和日志,原因很简单:如果人们无法访问他们,指标就毫无用处。虽然你可以为大家创建图标和仪表盘,但是工作时通常会遇到一些新的问题,需要针对指标数据存储创建新的查询以解决问题。你当然想让同事能够在没有你的情况下也能完成他们的工作。但如果你是唯一可以查询的人,那么你将很快成为”查询执行者”,或者没有人会关注指标。这两种结果对你来说都不算明智。

  • 图表

图表主要用作随时间变化的数据的可视化展示。米勒定律指出,一般人头脑中只能容纳不到 10 个对象(因此很难记住具有很长一串数字的表格),但是你却可以使用一个图表一次显示数千个数字。

图表的典型使用规则如下

  • X 轴(图形的下边缘)包含时间。
  • 无论绘制什么,都必须有一个键。
  • 所有的轴都必须标记。
  • 所有的数字都必须有单位。
  • 仪表板

构建仪表板的最佳规则是让用户看到他们需要的数据。如果你是为你自己或你的团队设计仪表板,请记住以下建议和注意事项

  • 如果打算在电视机上展示仪表板,请确保它只有几个图表,并且可以从很远的地方看清楚。如果必须跑过整个房间来到电视机旁边才能看清楚,那它可能没有达到应有的效果。
  • 如果可以的话,让仪表板支持移动设备。越来越多的工程师首先在手机上检查故障和图表,然后才打开笔记本电脑进行深入排查。
  • 有人建议在仪表板上一次最多展示 5 个图表,保留前 3 个图表以显示关于服务的最重要的内容。这样当页面首次加载时,最上面的内容就是你应该首要关注的地方。一个好办法是设置到其他仪表板的链接。如果你有一个关于网络流量的图表,那么下面要有指向仪表板的链接,其中包含有关网络的详细信息,以防图表显示出问题。
  • 聊天机器人

一个非常有用的工具是能够让图表出现在聊天中,或者能够从聊天中请求图表。Github 在其博客中写道,他们只需要在 Slack 中输入 /graphme 20150517..20150523 @github.deploys.total,就可以获取github.deploys.total2015年5月17日至2015年5月23日的带有指标数据的图表。

管理和维护监控数据

  1. 经典的、经过验证的且真实的方法 - 付钱请别人去做。自己不用去操心监控服务器是否故障、磁盘空间是否满了
  2. 自己构建监控系统的问题
    1. 磁盘空间
      1. 计算收集的数据量大小以及消耗存储空间的速度。如果空间有限则需要在某个时刻开始删除历史数据。解决这个问题的两种常见方法是抽样和归档。
      2. 投入更多的存储空间,因为硬盘价格一年比一年低。

他们知道有监控吗

他们可以是你的老板、产品团队、工程团队或者你认为应该关心监控服务的任何其他人。首先要告诉他们有新的监控系统,一个包含示例图标、文档链接和仪表板的精心编写的电子邮件是第一步,这是远远不够的。下一步是以正经的语气发送消息,展示有用的图表或仪表板。例如一个令人兴奋的宣告”你看到网站上个月有多少请求了吗?”

第一步只是告知监控存在。

第二部是将其与你的生活融为一体,并不断向其他人展示其实用性。

3. 事故响应

事故响应属于Mikey Pyramid中监控的下一个层次。事故响应建立在使用监控系统构建的数据之上,并借助反馈循环,来帮助我们加强对服务的监控。

这向我们展示了什么是重要的。因为如果没有警报,而是有人告诉我们服务没有正常工作,那么我们的监控就是不到位的。

什么是事故响应

事故响应通常包含以下几个动作

  1. 关注,注意到有些东西不对劲

关注是通过警报来实现的。警报就像一个 110 呼叫 - 来自一个在软件中看到错误的人的求救信息

人工上报可能很有用,但通常最好从自动化系统接收警报。

自动化系统与人类不同,它们是一致的。

  1. 交流,告诉别人哪些东西不对劲

  2. 恢复,纠正不对劲的东西

警报

警报最好以多种方式发送同一个警报避免单个服务故障,警报发送失败的后果可能会非常严重

警报服务

  • PagerDuty
  • VictorOps
  • 睿象云
  • OpsGenie

image-20200913113915619

警报内容

  • 主题应该小于 50 个字符。这可以让接收警报的人快速了解情况。

  • 使用祈使句。这尤其重要,因为当错误发生时人们常常希望给出有关如何操作的说明。例如”转到 AWS 控制台并终止实例i-1234567890

_祈使句_(Imperative Sentence)是英语中的一个句式,也是用于表达命令、请求、劝告、警告、禁止等的句子。*祈使句*最常用于表达命令,因此在学校文法中也常称为命令句。

  • 在主题后面提供额外的注解。如果警报服务允许,警报内容应该包括实时细节,如图表或指标的评估。此外还应该包括对响应警报的人有用的文档链接。

沟通

一旦有人接收警报并确认,他们就需要开始通报消息。无论如何你都应该每 30 分钟向所有相关人员发送一条消息。即使没有任何变化,也要告诉他们。要了解你的听众,如果没有强制要求可以不用太技术化;但如果你的听众是懂技术的,那么分享你能分享的,但要保持简明扼要。如果是内部交流,当人们需要了解更多信息时,一定要告诉他们去哪里才能找到。

如果在处理一个问题 10 分钟后仍然毫无头绪,那么就应该去寻求帮助。如果 TA 也不知道,那就引进其他人。慢慢地培养那些参与其中的人,直到你了解什么不起作用,以及如何使系统良好运行为止。

事故指挥系统

国家事故管理系统(National Incident Management System) 简称 NIMS

事故指挥系统(Incident Command System) 简称 ICS

ICS 的第一条规则是谁先到场负责。先到场的几乎总是值班的那个人,那么就由他来负责。如果有其他人出现,不论他的资历或所从属的组织如何,那么直到角色被授权,第一个到场的就是负责人。这样做的目的是规范化应对事故的结构,以确保不会出现多头领导的局面。你可以想象在野火场景下的这样一个结果: 一队消防队员赶到现场,他们正在处理火灾;然后,一个警察局长和消防局长出现了,一群警察也随之赶到;一场火灾,所以人们可能认为最好听从消费队长的指挥,但是正常的结构规定他们必须听从警察局长。

遵循 ICS,警官们在处理事故期间不必思考,因为有一个人在负责。那个第一出现在现场的人就是事故指挥官,在这种情况下,他可能是现场第一批消费对于中资历最深的人。然而,不要忘记授权。作为事故指挥官,有些任务需要去授权。上述示例中,可以让警察局长负责沟通,让消防队长负责人员调配和物资管理,请警官开展疏散工作,并指定一名警官来负责。

image-20200913133953712

恢复系统

平均恢复时间(Mean Time to Recovery, 简称 MTTR)

追踪一个挂掉的系统

  1. 首先,深呼吸。逼自己慢下来。吸气的时候数到 6,屏息的时候再数到 6,呼气的时候再数到 6,最后在再次开始这个循环之前再数到 6。这样做几次就会让你放松一点,慢慢呼吸会迫使我们在崩溃之前先检查一下自己。

这种呼吸方法叫做盒式呼吸。它来自美国海军海豹突击队。如何冷静下来并不重要,关键是找到让自己冷静下来的方法,这样你就可以清楚地进行思考了。

  1. 检查最近是否有部署。如果是,那么代码可能是最近才部署的。可以尝试将看到的错误与出现的新版本进行匹配。如果问题出现在这里,那么应该恢复部署并回滚到以前的版本。
  2. 如果回滚没有解决问题,下一个要查看的方面就是环境是否发生了变化。输入改变了吗?是否开始接收大量流量?收到的是一堆无意义或损坏的流量吗?当想出如何更改应用程序以更好地处理这种类型的错误流量时,是否开始阻止某个 IP 地址或用户代理?这是有效的流量吗?

删除或停止响应与某种过滤器匹配的 Web 服务器的流量称为负载释放。它通常被认为是一种激进的策略,但是当某种类型的流量导致应用程序崩溃时,它就非常有用。

  1. 如果用户输入没有改变,那么一个依赖项可能发生改变。数据库准备好了吗?我们依赖的服务是否正在运行?是否有人在没有告诉我们的情况下以应用程序不兼容的方式做了修改?
  2. 如果你找不到东西,那么这就是求助其他同事开始深入挖掘的好时机。这并不是永久性修复,而是将系统带回到大多数客户可以使用的状态的方法。然后,你可以让客户继续使用服务,同时与你的团队合作,制定一个长期计划,以防止再次发生这种情况。

警报解除

宣布警报解除的第一步是确保应用程序能够完成它该做的事,然后就可以开始解决根本问题了。请注意,第一目标始终是启动系统,而不是解决问题或找出根本原因。

请注意两个单独的警报解除消息: 第一个说事情应该恢复正常;第二个说警报解除,并说明何时进一步通信

谷歌云生产事件记录截图

4. 事后回顾

什么是事后回顾

事后回顾是发生生产事故后进行的回顾。根据组织的不同,事后回顾有许多不同的名称 - 回顾会、根本原因分析(Root Cause Analysis, 简称 RCA)、事故回顾等。大致的做法是创建一个文档,记录为什么会发生事故,并讨论涉及哪些方面,究竟发生了什么。

术语事后回顾(postmortem)将其定义为”检查尸体以确定死因”。有些人把软件运作过程看成具有生命的事物,因此,当一个运作过程停止时,它被描述为”死了”。

撰写时候回顾报告正是找出根本原因的好时机。进程是如何”死亡”的?系统的哪部分引起了不稳定?事故发生后多久我们才注意到?为什么其他系统也失败了?

透明文化有助于增进信任。

何时写事后回顾报告

如果有人索要事后回顾报告,那么就应该写一个。

“昨晚的事故到底是怎么回事?”或”上周的服务中断会不会有回顾?”这些都是应该创建事后回顾文档的提示。

  1. 如果几天内发生了两次相同的事故,则应该写一篇事后回顾报告。

一次包含错误代码的提交导致生产事故,然后触发了对应的回滚操作,但是包含这次回滚操作代码的发布版本却没有正确地修复最初的错误代码。或是一系列不良配置更改导致类似相关的服务中断。

  1. 如果服务中断超过 30 分钟,则应该写一篇事后回顾报告。

应用程序中断的时间超出了 SLI 规定的 30 分钟。也可能是连续 30 分钟无法访问应用程序。

开展事故分析

事故分析是复杂的。有时你会立刻知道答案,有时则需要数小时或几天的研究。**你应该像偏执的夏洛克 · 福尔摩斯那样深究这个系统。从事故现场出发,深入挖掘各个方面。要谨防先入为主的观念,要意识到红鲱鱼,并且要验证你的假设。

红鲱鱼通常用来比喻误导或分散手头任务的东西。它通常是一个有吸引力但与实际问题无关的答案或问题。

如何写事故回顾报告

一个大概的事后回顾报告的模板如下

  • 摘要
  • 影响
  • 时间表
  • 根本原因
  • 行动项目和附录

postmortem template: https://github.com/dastergon/postmortem-templates

在文档的顶部,添加相关人员的姓名、事件发生日期,以及文档最后一次修改的时间。

**BLOB (Binary Large Object, 二进制大对象)

停止事后指责

SRE 的一个关键原则是,如果无可避免要经历失败,那么就竭力改变你的组织,让它对失败宽容,你可以从失败中快速恢复并吸取教训。另一个原则是可靠性是团队共同奋斗的方向。

每个人都需要放心地提出问题,应对停机,并努力改进系统。培养这种认知水平是非常困难的,并且需要不断强化和帮助。

如果你很难不去责备一个人,首先,检查文档,将所有名称替换为”我们”,然后开始检查时间线。不要责备人类,每一步都要充分利用工具来防止人类犯错误。可以思考自动化可以防治人们遗漏检查表中的步骤吗?有检查清单吗?

不要要求人类做某事,而要找出人类不应该做某事的地方。

核对检查清单的重要性常常以 1935 年波音飞机的坠毁作为例子,当时机组人员忘记了飞机起飞前的基本准备步骤。在实施 B-17 起飞检查清单后,在 1800 万英里内没有发生其他事故。Robert L.Helmreich 博士经常认为是检查清单得以持续受到重用的原因。他在 20 世纪 90 年代写了很多关于如何降低医院和航空事故的文章。

举行事后回顾会议

事后回顾会议是在事后回顾报告之后的进一步工作。它经常用于最后确定行动项目。讨论根本原因的发现,并使讨论始终处于安全的氛围下。

通常,邀请参加事后回顾会议的最佳人员是那些经历事故的人 - 受影响的技术主管、产品经理和任何感兴趣的工程师。

在开始会议时做出声明,要求那些没有阅读事后回顾报告的人说明不读的原因或不让他们参加会议。这里的想法是,那些没有阅读事后回顾报告的人提出的一些问题或观点,而这些问题或观点可能已经在文档中有所陈述。会议不应该迎合那些为了更广泛的学习而无法花时间了解事故的人。

小结

作为一名 SRE 工程师,或者作为渴望建立可靠性的组织的一部分,事后回顾报告是从处理现在到未来的过度。在Mikey Pyramid中,在事后回顾报告以上的所有层级都是关于未来的 - 规划和改进过程。而下层(监控和事故响应)的一切都是关于处理当前事故的。在开始思考未来之前,事后回顾报告允许我们回顾过去。

5. 测试与发布

测试表明缺陷存在,而不是不存在

无论测试什么,都不需要验证其反面

不管做什么测试,它都是迭代的,应该大致遵循科学的方法。对于那些不知道这种方法的人,或者对将此方法应用到软件开发方面感到困难的人,请遵循以下步骤。

  1. 观察: 例如发现服务中断、获得一个需求,或者只是在编写软件
  2. 提问: 问你自己,当软件处理这种类型的输入,或者这个依赖不存在,或者软件进入这种状态时,会发生什么?
  3. 假设: 提出假设。在代码中,这更多的是询问你想要发生什么
  4. 测试: 行动并验证,代码是否以想要的方式做出了反应?
  5. 拒绝或通过: 如果测试失败,那么需要修改一些东西(如测试、代码、基础设施、流程等)以满足你的期望。

**lint 代码检查

lint 检查是确保代码与特定的代码规范相匹配的操作。这对于促使拥有大量开发人员的项目坚持一致的代码风格非常有用。lint 检查和测试的执行都适合使用自动化来实现。我们将对此进行简单讨论,但是在请求代码评审之前,你希望某人做的任何事情通常都是可以自动化的。

测试的种类

  • 单元测试: 用于确保函数和方法正常工作

  • 特性测试: 也称为冒烟测试和验收测试。它们验证特性是否正常工作

  • 集成测试: 这些测试用于确保特性和系统正确地协同工作

  • 负面测试

虽然不一定是一种类型的测试,但是负面测试是需要牢记的重要方法。这个方法认为,人们总是会输入你不期望的数据。这可能是带有非法的字符或代码输入,这些字符或代码会导致安全漏洞;或者用户只是纯粹的意外操作。

在测试时,尽可能多地为输入提出不正常的情况。用户经常会与你的想法不同,并且总会有一些用户有不好的意图,或者给你发送不正常的输入。

基础设施测试

混沌工程

  • Netflix Chaos Monkey

压力测试

  • Apache Bench
  • Siege
  • Wrk
  • Beeswithmachineguns
  • Hey

压力测试对于理解服务如何处理大量请求很有用,但是与正常的 Web 服务流量相比,这常常是不现实的。为了解决这个问题,人们经常测试生产访问量。最常用的两种方法

  • 影子测试

影子测试是将请求记录到服务中,然后将它们在应用程序的新版本进行重放,以此来测试它

一些工具

  • 用于 HTTP 请求的vegetagoreplay
  • 用于 TCP 连接的tcpreplay
  • 用于数据库查询的query-playbackmongoreplay

  • 金丝雀

金丝雀是引入新版本的服务实例并让其获得少量访问量的一种做法。

形象的说法: 把脚慢慢伸进水里,看看是不是太热了。

  • 特性开关

它工作起来像金丝雀,但是它使用代码。此布尔语句表示次用户是否启用该特性,然后继续。

例如只让 10%的登录用户看到一个特性,或者只让员工看到一个特性。通过监控,你可以看到某些代码的错误是否比其他代码更多。特性开关可能使调试变得更加困难,因为如果用户在使用服务时看到不正常的事情,那么你可能需要首先弄清楚启用了哪些特性,然后才能正确地对用户体验进行调试。

如果没有监控,像这样的生产测试是非常危险的,因为你很少或根本看不到变更对每个人的影响。测试的全部目的是验证假设。如果无法查看测试结果,则无法验证任何内容,因此实际上没有测试任何内容。

测试流程

除测试计算机软件外,测试流程和人也很重要。

Google 的(DiRT, Disaster Recovery Testing 灾难恢复测试),Google 计划大规模停机,看看团队如何反映。

DiRT 的例子包括使谷歌总部不可访问、关闭大量团队所依赖的系统、使数据中心离线,以及跨多个团队的统一停机计划等。

发布

如果你正在发布代码,并且你没有任何办法掌握它们,那么总是存在如果出现问题则必须回滚的风险。如果回滚很容易,这不是问题,但如果不是,这将是一个大问题。

6. 容量规划

容量规划需要和其他非技术部门沟通,因此懂得行业术语对开展工作至关重要。它设置了开始讨论的准入门槛。

这些不是法律、投资或财务建议,因为你只是个工程师。在做财务决策之前,要和你的会计师、银行出纳员、财务规划师、律师、首席财务官,或者这一类管钱的人谈谈。

  • 现金流

描述有多少钱,这些钱从哪里来,去往哪里。包括收入,即钱从哪里来;以及支出,钱从哪里去。

  • 损益表(P&L: Profits And Losses)

通常以季度为单位,描述你有多少钱,以及这些钱如何变化。这些数字来自收入减去支出。如果结果大于零,你就有利润。如果小于零,就会有亏损

  • 资产负债表

资产负债表是资产、负债和股权的列表。基本上,这包括公司所拥有的财产、债主以及股东。资产负债表的基本计算方程是资产=负债+权益。花的钱(资产)等于从银行借的钱(负债)和股票(从投资者那里得到的钱)的总和。

  • 资本支出与经营支出

资本是用来定义组织所拥有的物品或资产的价值的术语。资本可以是货币、知识产权、房地产、实物商品等。资本支出是增加你拥有的资本数量的投资。经常有人说,资本支出是与带来更多收入直接相关的资金。

经营性支出就是除资本支出外的一些支出。它是你无法收回的投资,如保险、劳动力、人力成本、基础设施等。如果你是园艺服务者,购买割草机是资本支出,而它的燃料是经营性支出。

  • 投资回报率

也叫 ROI(Return on Investment) 。在金融界,这通常是一个百分比。为了计算这个百分比,需要用赚的钱减去最初投资的本金,然后处以本金。公式就是 ROI=净货币/初始投资。常常有人问,”我们为什么这样做,我们期望得到什么回报?”答案并不总是金钱:有时是机会或者实物。

  • 成本中心与利润中心

成本中心与利润中心通常按照与资本支出的经营性支出类似的方式分开。成本中心和利润中心都是一群人所在的机构。投资利润中心就意味着投资能转化为销售的产品。反过来,成本中心是其余的一切。因此,人力资源(HR)部门通常是一个成本中心,因为它对于企业来说是必要的,但对产品的生产不是必要的。根据公司的不同,软件开发人员可以被认为是成本中心或利润中心。

为什么需要计划

童子军座右铭 - 做好准备,容量规划就是做好应对不可避免的变化的准备。其背后的理论是,在万事具备与毫无准备仅凭临场应对直接寻找平衡。你永远不可能完全准备好面对你所不知道的风险。所以,相反,你应该制定一个大概的计划,这个计划允许有临场发挥的空间,并且还能解决目前所知道的问题。你制定的计划越长远,临场发挥的空间就越大。

例如: 如果你的计划提前了两三年,那么你可能甚至不知道你的组织到那时可能支持什么产品,而如果你的计划是给之后一个月制定的,那么你可能对业务上将要发生的事情了如指掌。

定义一个规划

  1. 当前的容量是多少?
  2. 何时达到容量极限?
  3. 应该如何更改容量?
  4. 执行规划

横向扩展是为了增加服务器的实例数量;而垂直扩展则是为了提升单个服务器实例的性能。

自动扩容方程式

阀值 = (1 - 最大保留数量/正在运行的实例总数量)x100

公布

  • 按季度算,明年我需要多少预算
  • 用预算来做什么
  • 预算能花多久

架构 - 性能变化的根源

通常情况下,将缓存放在正确的位置或删除依赖项将极大地改变性能。

架构决策还可以对容量规划产生显著影响。强烈建议你尝试参与架构更改规划,其原因有两个。

  1. 你已经了解了基础设施的工作方式,以及代码如何在其上面运行。基于这些知识,你可以在规划过程中提供一个全新的角度来看待问题。
  2. 做出的决定应该且非常可能会影响其他系统可用的资源数量。一些架构决策可能会明显地且有损其他系统,或者增加基础设施的成本,超出你能够负担的水平。

一个例子是在 Web 服务器前添加Varnish(HTTP 缓存系统),并在Accept-Language头上设置Vary,不对其进行序列化。

例如用户 A 发送en-uk、en-us,用户 B 发送en-us、en-uk,用户 C 发送en-uk,那么你可能期望将它们发送为一个相同的版本给网站。但是,由于没有对 HTTP 头进行序列化,Varnish将分开存储 3 个缓存,而不是一个换成,因此这 3 个用户都将获得未缓存的内容。

本章小结

如果技术是要销售的产品,那么技术团队就处于利润中心;而如果是帮助公司成功的,那么就属于成本中心。

在评估新技术时,通常会从成本多少,如何节省人力,以及如何改善公司几个方面来评估。

例如每台服务器每月支付 20 美元以改进监控。但是如果你没有提及它有助于防止服务中断的事实,而类似的中断会导致公司在 2020 年花费 10,000 美元,或者为超过一个月的时间段进行容量规划,那么你可能永远无法为你的项目获得所需的资金。

7. 构建工具

SRE 的诞生是因为软件工程师触及了运维。目标是将 50%的时间用于编写代码,30%的时间用于与人打交道,20%的时间用于应对紧急情况。

首要任务是通过编写代码把自己和其他人从重复的工作中解放出来。

一位伟大的 SRE 工程师说过:”我会做一次,甚至会做两次,但如果你让我做第三次,我会把它全部烧掉。”

开发这一层次接近Mikey Pyramid的顶部

这需要大量的工作才能有效,并且像之前提到的层次结构的所有层一样,需要有效的沟通保障。

这并不是说,开发不能在层次结构中更早地发生,而是在其他层实现后再展开开发会最有效和有用。

编写代码或启动更大的软件项目时需要考虑的 6 个主要方面。

  • 寻找项目
  • 定义项目
  • 计划项目
  • 构建项目
  • 记录项目
  • 维护项目

构建项目

检查清单

  • 监控: 正在编写的代码有基本指标吗?它们正在被收集和存储吗?
  • 事故响应: 你正在编写关于如何对服务进行运维的文档吗?如果发生事故,有没有报警机制?任何人收到报警都知道该怎么做吗?
  • 事后回顾报告: 当代码发生故障时,你是否像对待其他发生故障的代码一样编写事后回顾报告呢?
  • 测试和发布: 是否写了单元测试和集成测试?是否有文档记录发布流程和回滚流程?
  • 容量规划: 是否记录了容量规划将如何影响系统的性能?

关于编写代码的建议

  • 使用版本控制: 这是计算机编程的必备工作。即使再小的项目也应该使用版本控制。人类会犯错误,版本控制可以让你轻松地从错误中恢复过来或查看何时引入了错误。
  • 始终对代码进行评审: 作为开发人员,你所知有限,所以让另一双眼睛来阅读你的代码有助于发现 Bug 并纠正你所做出的假设。你的代码至少应该有一位评审者来帮助你发现其缺陷。
  • 所有项目都应该有一个指定的所有者: 总会在某些时候,所有的项目会遇到外界提出的问题。因此所有项目都应该有一个指定的所有者,所有者可以回答这些问题。这对于决定优先次序也很重要。拥有所有者意味着有一个人能够对什么才是最重要的做出最终决定。
  • 人是最终问题: 正如从前面的 3 条建议所得出的,人常常才是问题所在。对于软件开发者来说,知道你写的代码最终是被人使用的是非常重要的。

8. 用户体验

标志设计标准 1. 视觉震撼 > 如果被看到,它需要非常引人注目 2. 独特且明确 > 标志不应该被重复使用。 一个例子是海盗旗 Jolly Roger, 或者称骷髅或交叉骨。虽然它曾经用来代表毒物,但它现在更多与海盗宝藏有关,并不能代表真正的危险。 3. 易于回忆和识别 > 这可以阻止人们使用常见形状或颜色作为说明符号 4. 易于模板化 > 应该容易创建并且可以应用于各种表面上 5. 旋转对称 > 不论它如何显示,人们都可以知道它是什么 6. 适用于来自不同背景的人 > 无论你身处何方,无论观众是谁,这都不应该是令人反感或困惑的

设计测试

  • 你来这里是为了响应一条请求回滚服务的警报,那么你将如何执行此操作?
  • 你会单击什么按钮来消除警报?
  • 在1到5的范围内,1是微不足道的,5是非常复杂地,你是如何发现这种体验的?
  • 你觉得成功完成了回滚吗?
  • 你需要编写一个监控配置来存储记录95%的延迟请求,那么怎么开始做这件事?

开发者体验

开发人员有关的两个个人小毛病,它们是不重视代码质量与重新造轮子。专注与开发人员的体验就像专注于机场工作人员的体验。他们不是核心客户,但提高他们的生活质量将改善客户的体验和他们的工作质量。

安全性

在为安全问题构建软件或审计技术时,试着考虑一项技术的三个方面 - 身份验证 > 指的是如何向用户提供表示可以与事物交互的令牌。例如,用户使用的用户名和密码 - 授权 > 指的是如何确定用户是否可以访问某些内容。例如,具有令牌的用户可以更改博客上的帖子。另一个例子是网络子网上的任何人都可以连接到人力资源帮助页面 - 风险概况 > 指的是你拥有什么类型的信息,谁会有兴趣获取该信息及技术能力。例如,新闻机构可能没有太多客户信息,但它会寻求保护有关来源和正在进行的文章的研究信息。话虽这么说,一个接受捐赠或出售印刷出版物的新闻机构可能会有信用卡号和出货信息。信用卡和个人信息往往会吸引大量的攻击者,而新闻来源则更能引起大型犯罪组织或国家层面的人的兴趣

身份认证

以下是编写处理身份验证的代码的一些基本建议 - 始终核实联系信息。如果用户输入了电话号码或电子邮件,则需要通过发送验证消息来确保他们真正拥有该号码或电子邮件 - 不要设置密码长度的最大值,也不要限制密码中可以包含哪些字符 - 始终使用单向哈希来存储密码,例如bcrypt。即使其他人可以访问你的数据存储区,那么他们也无权访问用户的密码 - 对于敏感账户,支持多重身份验证。这通常要求用户拥有ID、密码和某种设备,如手机 - 如果可能,请从身份验证流中删除密码。Have I Been Pwned网站跟踪数据泄露事件,在编写时拥有大约50亿个密码。鉴于地球上没有那么多人,你使用的密码很可能就在那里 - 当用户在异常情况下(如更改密码后)或新位置和浏览器组件进行身份验证时,要发送通知 - 身份验证过期一段时间后,要求用户重新进行身份验证,而不是让用户只登陆一次

ACM(Association for Computing Machinery, 计算机协会) 道德准则

  • 避免伤害他人
  • 为社会和人类福祉做出贡献

10. Linux云基础

伸缩单元

https://gist.github.com/jboner/2841832