本文是根据业内分享、公司规范、个人经验整理而来,希望能为您在提升系统稳定性方面提供参考。稳定性的建设有人的因素,也有技术的因素;对于人的因素,从流程和规则的角度去治标,见效快;对于技术的因素,结合具体业务,从编码和架构的角度去治本,但是周期长。

一. 熟悉系统业务

稳定性建设的前提是熟悉您负责的系统和业务,请尽用一切方法熟悉系统和业务,理清上下游依赖。

系统业务属性

您必须熟悉所负责的系统业务,明白该业务在公司技术体系中的作用和价值,是否为核心应用,即涉及公司核心业务的应用;熟悉其部署、架构和维护,并对源码有较好的掌握。以电商场景为例,涉及用户登录、搜索、浏览、购买、交易等的服务均为核心应用,对于核心应用,请保持谨慎和敬畏之心。

上下游依赖

规模越大的公司,其系统越是繁多,依赖关系越是复杂,往往环环相扣。对于您维护的系统,你应当理清上下游依赖,特别要知晓,自身服务故障对下游的可能产生的影响范围和程度。对于故障后果严重的业务,请保持审慎意识。对于上下游依赖,要明确交互方式,做好异常处理,做到合理依赖。

  • 严禁依赖闭环:服务依赖关系应当类似向无环图,禁止服务依赖闭环,严禁服务之间调用闭环。
  • 上游依赖(您依赖的应用):熟悉上游 API 的特性,如:retry 机制、timeout、幂等性、异步回调等等,采用合理的姿势调用上游的 API。对于非核心应用的上游,一般要做好熔断和降级措施,尽力避免上游的故障影响您的服务。
  • 下游依赖(依赖您的应用):让下游采用正确的姿势使用您的 API,对于流量大的服务建议做好限流措施,如果您的系统故障不会影响下游的核心功能,建议督促下游做好熔断和降级措施。

关于熔断和限流,在本文第三节会进一步讲解。

二. 变更的规范性

SRE has found that roughly 70% of outages are due to changes in a live system.

在本文中,变更指修改代码、配置、数据等操作。

变更流程规范

  1. 严格遵循本地开发环境 -> 开发环境 -> 预发环境 -> 线上环境的发布流程,严禁未经上一个环境测试的代码提交到下一个环境。
  2. 可分批次的发布务必遵循分批次灰度发布,每发布一批应观察一段时间,确保无误后再执行下一批发布,如此在故障场景下可减小故障范围。同时做好回滚措施,异常场景下可缩短故障时间。
  3. 发布的过程中,必须关注业务监控指标、告警等。
  4. 存在风险或者重大的变更必须通知受影响业务方,做好应急措施。

变更时间规定

  1. 严禁在重要活动、节假日前后发布,默认情况下,周五也不准搞事情(发布)。
  2. 严禁在业务流量高峰时间段发布,对于一般的变更,请在周一至周四中低峰时间段发布,对于重大变更,请在凌晨发布。

变更频率规定

每次发布可能会耗费较大的精力和时间,更多的发布往往会带来越多的故障次数,故需要控制变更频率。一般而言对于同一个应用,建议其发布次数控制在一周一次以内。

Coding

  1. 大特性开发、架构的设计等必须有设计文档,必须经过小伙伴们的评审。
  2. 规范编码,您的编码风格必须遵循业界或者公司规范,并养成注释习惯。
  3. 充分测试,包括单元测试,集成测试,越是动态的语言,越需要关注单元测试。
  4. 互相 Review,养成良好的提交规范。
  5. 逐步建设好 CI/CD 平台,并基于 CI/CD 平台固化开发,测试,上线流程。

告警

  1. 日常告警明确 Owner,Owner 必须关注手机短信,保持电话畅通。
  2. 太多的告警等于无效告警,优化告警配置,减少误报、漏报的概率。

三. 架构的规范性

或许因认知、或许因项目紧急,有些应用的架构设计的不够合理和规范,埋下了隐患的种子。架构的优化和建设是一个长期投入的系统工程,也是一剂治本的良药。

应用标准化

如果您的公司针对 Java 等常见语言制定了项目规范,请遵守该规范,否则请遵守开源的项目规范,良好的处理代码、文件、配置等目录结构。

大部分应用为非存储服务,请务必将其设计成无状态,即数据和业务逻辑分离,以便横向扩容和故障恢复。对于状态数据,必须存储到对应的存储服务中。

遵循基础组件的使用规范

对于各种基础组件,如数据库(MySQL,NoSQL 等)、中间件(Tesla、Kafka、Redis 等)、大数据等服务(HDFS、Spark、Storm 等),请采用严格遵循公司或者业内的良好实践进行使用。例如:

Redis

  • 严禁用于存储持久化数据。
  • 注意雪崩、缓存穿透问题。
  • 致力缩短数据不一致的时间,变量数据一定要设置 TTL。

MySQL

业务量小的应用可以直连数据库,业务量大的应用可以以中间件访问数据库,以获得更高的性能。

  • 删除、变更数据请谨慎操作,务必 double check。
  • 其它规范,如命名规范,表设计规范,外键规范,字符编码集等规范。

高可用

线上系统应该设计成高可用架构,避免单点故障影响业务。无状态应用的高可用建设相对简单,有状态的高可用会复杂许多,高可用的建设和优化应当充分分析和评审、逐步建设。

限流 & 熔断 & 降级

对于高流量的核心在线服务系统,应该有限流、熔断、降级相关方案。业内有非常多的开源项目,如 Google Guava 项目,SpringCloud 中的 Hystrix,请可以基于这些项目快速实现限流、熔断和降级。

故障演练 & 压测

对于核心系统,特别是在线系统,待高可用、熔断、降级等方面有一定基础后,可在业务低峰时期做好预案措施,进行故障演练。故障演练是一项系统性的工作,需要针对各自业务特点设计演练方案,从演练中发现薄弱点,并进行改进。

您可以使用压测系统来专门压测您的服务,分析性能瓶颈、评估容量,但是压测过程中不得影响业务。

最后

防火胜于救火,请严格遵照上述措施防范未然、尽力避免故障。当故障发生时,根据情况决定是否要第一时间通知受影响的业务方,首先恢复服务、恢复服务、恢复服务,其次恢复数据,最后才是定位问题和整改,即缩短故障时间、减少故障范围、降低故障影响面。

总而言之,我们应该降低系统复杂度、增强系统健壮度、提升对系统的熟悉程度,按规范操作。