概念
生产就绪:如果一个应用程序或服务被证实可以处理生产环境的业务流量,那么它就被认为是生产就绪的。
混沌测试:在生产环境验证(安排好的或随机的)各种故障场景。(参考资料:微服务的混沌测试)
staging环境:近似生产环境,要反映真实生产环境的状态,只不过没有真实的业务流量。
canary环境:先部署到生产环境的一小部分服务器上(大概5%到10%),如果没有问题,再部署剩余的服务器。(源自于旷工使用金丝雀来探测矿井中的空气质量)
防御性缓存:将微服务下游依赖项的数据缓存起来,当下游依赖项不可用时,避免稳定性和可靠性受到影响。
生产就绪路线图:一份文档,作为生产就绪流程的一部分,描述了把微服务带向生产就绪状态的步骤。
水平伸缩:通过增加更多的服务器(或其他硬件资源)对应用或系统进行伸缩。
垂直伸缩:通过增加资源(CPU、内存)对应用或系统进行伸缩。
8个原则(生产就绪标准)
-
- 稳定性
构建稳定的微服务要求:
- 稳定的开发周期
- 稳定的开发流程
- 稳定的更新换代流程
- 稳定性
-
- 可靠性
构建可靠的微服务要求:
- 可靠的部署流程
- 对依赖项可能出现的故障准备应对措施
- 可靠的路由和服务发现
- 可靠性
-
- 伸缩性
构建可伸缩的微服务要求:
- 定义好质和量两方面的增长规模
- 定位资源瓶颈和需求
- 准确的容量规划
- 可伸缩的流量处理能力
- 依赖项的伸缩
- 可伸缩的数据存储
- 伸缩性
-
4&5. 容错和灾备
构建具备容错能力和灾备能力的微服务要求:- 识别潜在的故障场景,并做好应对准备
- 识别并解决单点故障问题
- 应用故障探测和补救策略
- 通过代码测试、负载测试和混沌测试验证系统的弹性
- 管理好业务流量
- 快速处理故障
-
- 高性能
构建高性能的微服务要求:
- 恰当的可用性SLA
- 恰当的任务处理方式
- 对资源的合理利用
- 高性能
-
- 监控
构建可监控的微服务要求
- 适当的日志和堆栈跟踪信息
- 设计良好且易于理解的仪表盘,可以准确地反映服务的健康状况
- 有效且具有可操作的告警操作手册
- 开发人员轮班待命
- 监控
-
- 文档化
构建文档化的微服务要求:
- 详细的、最新的、集中式的文档,它包含了微服务所有的相关信息
- 在开发人员、团队、整个生态系统层面了解微服务
- 文档化
开发周期
部署管道
稳定可靠的部署管道的几个阶段:
staging
staging阶段测试:
- 触发模拟的(或录制的)业务流量
- 手动发送请求
- 自动化测试、单元测试、集成测试及组合
full staging
partial staging
full staging | partial staging | |
---|---|---|
生产环境的完全镜像 | 是 | 否 |
单点的端口 | 是 | 是 |
访问生产服务 | 否 | 是 |
读取生产数据库 | 否 | 是 |
写入生产数据库 | 否 | 是 |
要求自动回滚 | 否 | 是 |
full staging和partial staging环境的对比
full staging | partial staging | |
---|---|---|
生产环境的完全镜像 | 是 | 否 |
单点的端口 | 是 | 是 |
访问生产服务 | 否 | 是 |
读取生产数据库 | 否 | 是 |
写入生产数据库 | 否 | 是 |
要求自动回滚 | 否 | 是 |
canary
- 处理生产流量,是生产环境的一部分
- 有对生产环境的所有权限
- 监控可以区分canary
- 在完成一个完整的业务流量周期之前,新发布的版本不应该离开canary环境
生产
- 一步到位部署
- 循序渐进的部署
伸缩性和高性能
一个生产就绪的微服务是可伸缩且高性能的:
- 明确的质的增长规模和量的增长规模
- 高效地使用硬件资源
- 已识别出资源的瓶颈和需求
- 容量规划自动化,并通过调度作业来执行
- 依赖项也会随之伸缩
- 可以随着客户端的伸缩而伸缩
- 业务流量模式有章可循
- 在发生故障时业务流量可以被重新路由
- 使用支持伸缩性和高性能的编程语言来实现
- 以高性能的方式处理任务
- 以可伸缩和高性能的方式存储数据
了解增长规模
- 质的增长
- 量的增长
描述微服务增长规模的指标:
- RPS(每秒请求数)
- QPS(每秒查询数)
容错和灾备
一个具备容错和灾备能力的生产就绪的微服务:
- 没有故障点
- 所有可能的故障场景都已被识别出来
- 已经通过代码测试、负载测试和混沌测试保证了它的弹性
- 自动化的故障检测和挽救措施
- 微服务开发团队和整个组织具有标准化的事故和中断处理流程
故障场景
常见的生态系统故障:
- 不充分的系统和服务架构评审
- 不完善的代码审查
- 糟糕的开发流程
- 不稳的的部署过程
常见的硬件故障场景:
- 主机故障
- 机架故障
- 数据中心故障
- 云服务故障
- 服务器配置故障
- 资源隔离或抽象技术故障
- 糟糕的配置管理
- 配置变更引起的故障
- 主机级别的监控故障
- 主机级别的日志故障
- 网路故障
- 停机运维
- 缺乏基础设施冗余
常见的通信层和应用平台层故障:
- 网路故障
- DNS错误
- RPC故障
- 对请求或响应不恰当的处理
- 消息系统故障
- 服务发现和服务注册故障
- 不恰当的负载均衡
- 开发工具和开发环境故障
- 测试、打包、构建和发布故障
- 部署管道故障
- 微服务级别日志的故障
- 微服务级别监控的故障
常见的依赖项故障场景:
- 下游微服务(依赖项)的故障
- 内部服务中断
- 外部(第三方)服务中断
- 内部软件包故障
- 外部(第三方)软件包故障
- 依赖项未能达到它的SLA指标
- API端点弃用
- API端点移除
- 微服务弃用
- 微服务移除
- 接口或端点弃用
- 对下游服务调用超时
- 对外部依赖项调用超时
常见的微服务故障场景:
- 不完善的代码审查
- 糟糕的架构设计
- 缺乏适当的单元测试和集成测试
- 糟糕的部署
- 缺乏恰当的监控
- 不恰当的异常处理
- 数据库故障
- 伸缩性极限
弹性测试
-
- 代码测试
- lint测试
- 单元测试
- 集成测试
- 端到端测试
-
- 负载测试
- 负载测试使用特定的流量负载,这个负载使用RPS、QPS或TPS来表示,并通过质量增长规模和数量增长规模计算得出
- 部署管道的每个阶段都会运行负载测试
- 负载测试会涉及所有的依赖项
- 负载测试是完全自动化的,会定期运行,并被记录下来
-
- 混沌测试
开源解决方案Simian Army
示例:
- 禁用依赖项的API端点
- 停止所有发送给依赖项的请求
- 在生态系统的组件间引入延迟,以便模拟网络故障:在客户端和依赖项之间,在微服务和数据库之间,在微服务和分布式任务处理系统之间,等等
- 停止所有发送到数据中心或区域的流量
- 随机地关闭主机
- 混沌测试
故障检测和修复
事故和中断的分类:
- 严重程度(0至4,0级最重,4级最轻)
- 影响范围(高,中,低)
处理事故的5个步骤:
分诊(triage)、缓解(mitigate)和解决(resolve)
监控
生产就绪的微服务的监控的4个工具:
- 日志
- 仪表盘
- 告警
- 轮班待命机制
一个得到恰当监控的生产就绪的微服务:
- 它的关键性度量指标在主机级别、基础设施级别和微服务级别得到识别和监控
- 它有能够反映微服务过去状态的日志
- 它的仪表盘包含了所有的关键性度量指标,而且很容易读懂
- 它的告警具有可操作性,并且定义了阈值
- 有一个专门的轮班待命机制负责监控微服务,并对事故和中断做出响应
- 有一个清晰的、良好定义的标准待命流程,用于处理事故和中断
度量指标 | 主机和基础设施 | 微服务 |
---|---|---|
CPU | 开发语言相关的度量指标 | |
内存 | 可用性 | |
线程 | SLA | |
文件描述符 | 延迟 | |
数据库连接 | 调用成功的端点 | |
端点响应结果 | ||
端点响应时间 | ||
客户端 | ||
错误和异常 | ||
依赖项 |
关键性度量指标总结:
度量指标 | 主机和基础设施 | 微服务 |
---|---|---|
CPU | 开发语言相关的度量指标 | |
内存 | 可用性 | |
线程 | SLA | |
文件描述符 | 延迟 | |
数据库连接 | 调用成功的端点 | |
端点响应结果 | ||
端点响应时间 | ||
客户端 | ||
错误和异常 | ||
依赖项 |
文档化和理解
一个生产就绪的微服务具有良好的文档并且为人所理解:
- 它有详尽的文档
- 它的文档会定期更新
- 它的文档包含如下内容:微服务描述、架构图、待命人员的信息、重要信息的链接、开发上手指南、微服务请求消息流、端点的信息、依赖项的信息、运行手册、以及常见问题答疑
- 它为开发人员、团队和组织所理解
- 它符合生产就绪标准并且满足相关要求
- 它的架构经过了反复的评审
微服务文档包含内容:
生产就绪微服务的文档需要包含的内容:
- 关于微服务以及微服务在整个生态系统中所扮演角色的描述
- 一个能够详细描述微服务架构及其客户端和依赖项的架构图
- 微服务开发团队的待命信息
- 代码库链接、仪表盘链接、RFC文档链接、架构评审文档链接,以及其他任何有用的相关信息的链接
- 开发上手指南,包含开发流程、部署管道,以及任何能够帮助开发人员开发上手的有用信息
- 微服务请求流程、SLA指标、生产就绪状态、API端点、客户端和依赖项的详细信息
- 运行手册,包含一般性的事故处理流程和用于诊断、缓解、解决告警问题的分步操作指南,以及如何排查和调试问题
- 问答章节
评估列表
开发周期
- 是否有一个可以存放所有代码的中心代码仓库?
- 开发人员所在的开发环境是否准确反映了产品状态(例如,是否准确的反映了实际情况)?
- 是否有代码检查、单元测试、集成测试和端到端的测试?
- 是否有代码审查流程和策略?
- 是否具有自动化的测试、打包、构建和发布流程?
部署管道
- 微服务生态系统是否有一个标准化的部署管道?
- 部署管道里是否有full staging或partial staging阶段?
- staging环境对生产环境有怎样的访问权限?
- 部署管道里是否有canary阶段?
- canary阶段是否有足够的时间来捕捉所有的缺陷?
- canary阶段是否准确地模拟了生产环境的业务流量?
- canary和生产环境的服务端口是一样的吗?
- 生产环境的部署是一步到位还是循序渐进的?
- 对于紧急情况,是否存在直接跳过staging和canary阶段的情况?
服务依赖
- 微服务的依赖项都有哪些?
- 微服务的客户端都有哪些?
- 微服务如何缓解依赖失效所带来的影响?
- 对于每个依赖项,是否都有备份、替代服务、回退方案或防御性缓存?
路由和服务发现
- 微服务的健康检测可靠吗?
- 健康检测是否准确地反映微服务的健康状态?
- 健康检测是否运行在独立的通道上?
- 是否使用了回路断路器来防止不健康的微服务发出请求?
- 是否使用了回路断路器来防止生产环境的业务流量被发送到不健康的主机或服务上?
服务和端点的解除
- 是否有解除微服务的相关流程?
- 是否有解除微服务API端点的相关流程?
增长规模
- 微服务的质的增长规模是怎样的?
- 微服务的量的增长规模是怎样的?
资源的有效利用
- 微服务是运行在专门的硬件上还是共享的硬件上?
- 是否使用了资源隔离技术?
资源感知
- 微服务的资源需求是怎样的(CPU、内存等)?
- 每个微服务实例能够处理多少流量?
- 每个微服务实例需要多少CPU?
- 每个微服务实例需要多少内存?
- 微服务还需要其他的资源吗?
- 微服务的资源瓶颈在哪里?
- 微服务是否需要被横向或纵向扩展,或者两者兼顾?
容量规划
- 容量规划是否基于调度就行?
- 新硬件多久能够到位?
- 申请硬件的频度是怎样的?
- 是否根据优先级为微服务分配硬件?
- 容量规划是自动化还是手工操作的?
依赖项的伸缩
- 微服务的依赖项有哪些?
- 这些依赖项是否具备了伸缩性和高性能?
- 依赖项能否随着微服务就行伸缩?
- 依赖项的所有者是否做好随微服务就行伸缩的准备?
流量管理
- 是否很好地了解微服务的流量模式?
- 是否根据流量模式来安排服务的变更?
- 流量模式的急剧变化(特别是流量爆发)是否被小心的处理了?
- 在服务失效以后,流量是否能够被恰当地重新路由到其他数据中心?
任务处理
- 微服务所使用的编程语言是否具备伸缩性和高性能?
- 微服务在处理请求时是否存在伸缩性和性能方面的限制?
- 微服务在处理任务时是否存在伸缩性和性能方面的限制?
- 微服务团队的开发人员是否了解他们的服务是如何处理任务的,处理任务的效率是怎样的,以及当任务和请求数量增加时他们的服务将会如何应对?
可伸缩的数据存储
- 微服务是否以可伸缩和高性能的方式处理数据?
- 微服务需要存储什么类型的数据?
- 微服务的数据需要怎样的schema?
- 每秒需要处理多少事务?
- 微服务需要更高的读写性能吗?
- 微服务是读密集、写密集还是两者兼顾?
- 微服务的数据库可以横向或纵向扩展吗?它是可复制或可分区的吗?
- 微服务使用的专门的还是共享的数据库?
- 微服务是如何存储和处理测试数据的?
避免故障点
- 是否存在单点故障?
- 是否存在多点故障?
- 故障点是否能够被移除,或者需要对它们进行缓解?
故障场景
- 是否所有可能的故障场景都已被识别出来?
- 有哪些横跨整个生态系统的常见故障?
- 硬件层有哪些故障会影响到这个微服务?
- 通信层和应用平台有哪些故障会影响到这个微服务?
- 哪些依赖项故障会影响到这个微服务?
- 哪些内部故障会拖垮这个微服务?
弹性测试
- 这个微服务是否通过了适当的lint测试、单元测试、集成测试和端到端的测试?
- 这个微服务是否经过合格的负载测试?
- 是否通过混沌测试对所有可能的故障场景进行了测试?
故障检测和修复
- 在组织里是否有标准化的事故处理流程?
- 这个微服务的故障是如何影响业务的?
- 是否对故障进行了清晰的分级?
- 当发生事故时,团队是否遵循了事故处理的5个步骤?
关键性度量指标
- 这个微服务有哪些关键性的度量指标?
- 有哪些主机级别和基础设施级别的度量指标?
- 有哪些微服务级别的度量指标?
- 这些关键性度量指标都被监控起来了吗?
日志
- 这个微服务需要把哪些信息记录到日志里?
- 这个微服务是否记录了重要的请求信息?
- 日志是否准确反映了微服务在各个时间点的状态?
- 这个日志方案是否具有伸缩性和高性价比?
仪表盘
- 这个微服务是否有仪表盘?
- 仪表盘是否简单易懂?是否所有的关键性度量指标都展示在了仪表盘上了?
- 是否能够从仪表盘上看出这个微服务是否运行正常?
告警
- 是否每个度量指标都设有告警?
- 是否所有告警都设置了合适的阈值?
- 告警阈值设置是否恰当,以便在发生中断之前触发告警?
- 告警是否具有可操作性?
- 运行手册是否包含了用于诊断、缓解和解决问题的排查步骤?
轮班待命
- 是否有一个专门的轮班待命机制用于微服务的监控?
- 每次待命轮班是否有至少两个开发人员参与?
- 这个待命流程是否在整个工程组织内进行了标准化?
微服务文档
- 微服务的文档是否被集中存放在一个公开的、人们容易访问到的地方?
- 文档是否方便搜索?
- 微服务发生重要变更时,文档是否也得到相应的更新?
- 文档是否包含了微服务的描述?
- 文档是包含了架构图?
- 文档是否包含了待命信息?
- 文档是否包含了重要信息的链接?
- 文档是否包含了开发上手指南?
- 文档是否包含了微服务请求信息流、端点和依赖项的信息?
- 文档是否包含了运行手册?
- 文档是否包含了问答章节?
微服务理解
- 团队里的每个开发人员是否都能回答与他们的微服务的生产就绪相关的问题?
- 微服务是否遵循了一系列原则和标准?
- 对于新的微服务,是否有RFC流程?
- 已有的微服务是否经常得到评审和审计?
- 是否每个微服务团队都举行架构评审?
- 是否有生产就绪的审计流程?
- 是否有生产就绪路线图用于把微服务带向生产就绪的状态?
- 生产就绪标准是否推动了组织的OKR?
- 生产就绪流程是自动化的吗?