乐趣区

关于高可用:架构师日记软件高可用实践那些事儿

作者:京东批发 刘慧卿

一 前言

关于软件的高可用,是一个陈词滥调的话题。“高可用性”(High Availability)通常来形容一个零碎通过专门的设计,从而缩小复工工夫,而放弃其服务的高度可用性。其计算公式是:可用率 =(总工夫 - 不可用工夫)/ 总工夫。

本文重点从落地实际的视角作为切入点,率领大家从合作效率,技术落地和经营标准几个方面来展示高可用的施行步骤和落地细节。为了不便了解,先来对立语言话术,看一下软件交付过程中的各个阶段,如下图:

为什么说软件的高可用会面临着诸多挑战呢?

◦ 从需要交付链路来看,要实现指标交付,须要产品,研发,测试,运维,经营等多方利益相关者的密切配合。有些我的项目需要,合作者有时可能达到上百人,每个人职责分工各不相同,但却相互配合依赖,任何一个环节呈现纰漏,可用率就有可能受到影响;

◦ 从工夫角度来看,如果要达到全年 99.99% 的可用率,就意味着一年当中,容许有故障的工夫为:365*24*60*(100%-99.99%)=52 分钟,如果要达到 5 个 9 的可用率,容许故障的工夫仅为 5 分钟,这差不多是咱们发现问题后,重启利用的耗时;

◦ 从迭代效率来看,不迭代,不上线,问题呈现的概率肯定会小很多。软件的迭代效率和可用率之间存在着负相关的关系,均衡好两者之间的关系,也会面临着不小的挑战。

总结一下,咱们具体面临的问题如下:

◦ 如何解决需要交付相干协作者多,链路长的问题?

◦ 如何应答故障工夫容忍度低的问题?

◦ 如何在频繁需要迭代的现状下,放弃可用率不受到大的冲击问题?

二 合作效率保障

认知误区

从整个需要交付链路咱们能够发现,随着链路的逐级递增,信息的传递链路分支就会越多,传递层级就会越深。这会导致两个问题:

  1. 信息传递效率升高;
  2. 信息准确性变差。

这两个问题最终导致的后果,就是合作效率的升高。

一个没有实战经验的同学往往会认为减少人数,就会进步需要交付效率。其实这种想法不完全正确,具体关系参考下图:

这就像盖楼房,如果一个人循序渐进的建设,须要 100 天实现。如果请了 100 集体来帮忙,是否用 1 天的工夫实现房子建设呢?答案是否定的。

这外面有合作的老本,比方:团队默契(设计师,瓦工,泥工,水电工),岗位匹配,危险管制;

这外面有流程的依赖,比方:施工依赖于设计,软装总在硬装之后;

这外面有老本估算,比方:整个组织的人才梯度,规模大小(承建方,代理商,承包商);

以上这些,都不是简略的通过人力铺设来解决的。

流程标准

进步合作效率的底层逻辑是通过缩小交付链路层级,缩短信息传递链路,进而保障信息的准确性和传递效率。(组织建设层面的内容这里不做开展)

这就要求具备今日事,今日毕的口头力。组织层面这叫流程标准,集体层面这叫做事办法,责任心。

尽量避免将当下的事件迁延到下一个环节,否则就会影响后续链路的排期打算和交付效率,极其状况甚至会呈现返工的情景。简言之,思考分明,不埋坑。产品需要对研发,研发设计对测试,测试用例对产品等各个交付节点都是如此,交付物肯定是靠谱的。

三 技术落地保障

在需要响应周期中,高质量的落实架构设计,编码实现,平安上线,部署经营等生产阶段,是软件高可用落地保障的前提和根底。

架构设计

架构设计往往影响着零碎的后期实现老本(即 ROI)和后续运维难度,属于软件的顶层设计,这外面既蕴含宏观的设计方案,也蕴含落地细节里的范式束缚。

• 流程保障

邀请架构师参加:外围交易节点、重大需要改变邀请架构师参加,这是闭坑最间接无效的形式;

器重设计文档:计划形容分明了,并获得相干利益者的认可,是走在正确路线上的前提。

• 设计保障

容灾设计:要预留后路,提前想分明,做好容灾设计。可回滚,可熔断,可重试,可降级。

鲁棒性设计:无状态设计,防重设计,幂等设计,数据一致性设计

编码实现

如果说架构设计是骨架,那么编码实现就是神经,血管和肌肉。前者决定了能走多稳,走多久,后者决定着走多快,走多远。落实到编码层面,就是代码的苍老糜烂水平。

• 流程标准

代码评审机制:代码评审不仅仅是发现零碎中存在的问题这么简略。它是一种长期行为,是进行组织文化贯彻和传承的一种模式和载体。评审的过程中,明确了业务职责边界,设计与编码共识,优良的规范导向等研发共识。相当于通过具象化的案例,给出针对性的领导,这些都是保障团队战斗力的基石。

研发过程中的很多问题,通过代码评审机制能够被发现和解决,比方:

◦ 如何看待长期需要的设计与实现?

◦ 如何对待“Hello World!”的 N 中写法?

◦ 如何了解设计模式和适度设计的边界?

◦ 如何评估以后阶段的交付物?

◦ 是否有必要引入单元测试?

• 编码标准

◦ 有没有对谬误进行解决?对于调用的内部服务,是否查看了返回值或解决了异样?

◦ 设计是否听从已知的设计模式或我的项目中罕用的模式?

◦ 开发者新写的代码是否用已有的 SDK/Framework 中的性能实现?在本我的项目中是否存在相似的性能能够调用而不必全副从新实现?

◦ 工程中是否引入了无用的,性能反复的,不同版本的 jar 包依赖?(json 类库,各种 utils)

◦ 有没有无用的代码能够革除?

◦ 代码可读性如何?有没有足够的正文?

◦ 参数传递有无谬误,有没有应用断言(Assert)或判断来保障咱们认为不变的条件真的失去满足?

◦ 边界条件是如何解决的?switch 语句的 default 分支是如何解决的?循环有没有可能呈现死循环?

◦ 对资源的利用,是在哪里申请,在哪里开释的?有无可能存在资源透露(包含超时工夫,内存、文件、对象援用,大对象,线程数等)?有没有优化的空间?

◦ 代码的效力如何?最坏的状况是怎么的?

◦ 代码中,特地是循环中是否有显著可优化的局部(string 的操作是否能用 StringBuilder 来优化)?

◦ 对于零碎和网络的调用是否会超时?如何解决?

◦ 代码是否易于测试(办法行数,圈复杂度,出入参定义是否正当)?

◦ 改变是否影响到旧版本、历史数据、上游是否兼容?

◦ 接口设计是否有思考幂等、并发、越权,降级等问题?

◦ 是否存在缓存、数据库性能问题以及多数据源数据一致性的问题?

◦ 上线计划是否思考了灰度计划,数据状态不统一问题?

平安上线

线上 70% 的故障都是由某种变更而触发的,其中相当一部分占比是不标准的上线引起的。所以平安上线这一环节至关重要。

• 流程标准

◦ 严禁频繁上线:比方,每周不大于 2 次;

◦ 严禁高峰期上线:升高问题影响范畴;

◦ 严禁擅自上线:有改变,必须通过测试验证,产品回归确认;

• 过程标准

◦ 摘流量:抉择第一批机器 jsf 下线 /np 摘流量 (选为冷备);

◦ 看日志:察看日志确认摘除机器无流量;

◦ 服务预热:确认机器启动胜利,外围业务接口须要接口预热;

◦ 挂流量:挂载上线机器流量;

◦ 看指标:察看上线机器 mdc 指标是否异样 (cpu、内存、负载)、日志是否有异样

部署经营

实现高可用的一个很重要的伎俩就是能力冗余。上面给出方向和思路,具体落地细节和策略,能够依据具体情况各自延展。

网络

◦ 运营商层面,联通,电信,挪动等;

◦ 链路节点方面,VIP,CDN,路由器 / 交换机,反向代理,客户端,浏览器等;

存储

◦ 无论是数据库主从架构,还是 ES 的正本架构,都是实现存储高可用的伎俩,重要数据要利用好相干个性;

◦ 在进行数据结构设计时,同样也须要做好分流策略,容量布局,数据拆分或异构。比方:防止缓存热 key,数据库表吞吐量瓶颈,数据库连接数限度等各种影响高可用的问题呈现。

服务

◦ 横向扩容:服务要保障能够通过增加资源的形式进行能力扩容,这一点十分重要;

◦ 服务分组:依照业务方或应用场景,对服务进行不同粒度的隔离,避免极其状况导致服务相互影响;

◦ 极限策略:次要是一些极其异常情况下的进攻策略,目标是意外产生后,尽量放弃服务的可靠性。比方:限流,熔断,重试,疾速失败等;

◦ 灰度策略:新性能上线,往往是最容易呈现问题的时候,领有成熟的流量灰度能力,是管制问题影响范畴的要害;

四 经营标准保障

经营标准

  1. 可监控 :零碎运行状况
  2. 可报警 :异常情况可能告诉到零碎相干人员
  3. 可定位 :呈现问题后,可能疾速定位问题起因
  4. 可修复 :出现异常状况,可能在第一工夫进行问题修复;

应急预案

高可用意味着对故障工夫的容忍性差,意味着没有工夫进行故障排查和修复,更没有工夫关上代码进行破绽排查。这就要求咱们有一套齐备的应急预案,这套预案可能解决大部分可预感的故障问题。

• 流程标准

◦ 复原生产第一;

◦ 排查问题第二;

具体事变应急解决手册,能够参照下图:

• 过程标准

◦ 网络,服务,存储分三个维度制订对应计划,并将应急预案清单(文件名:checklist)填写到本人的代码库中,放弃内容传承和更新;

◦ 可预见性,即问题触发场景要写分明。举例:依照以后进度(1 万 / 天),随着数据库数据的减少,预计 10 个月后,数据库表(xxx 表名)会呈现慢查问;

◦ 可执行性,可能打消问题的解决方案。举例:启动历史数据归档工作(xxxWorker),将历史数据进行转移到归档数据库中;

标准达标

再好的流程和标准都须要有对应的机制来贯彻执行,否则就是镜中花,水中月,看着美妙,实则没用。可执行,能度量,是依照指标变好的前提。所以这里给出一个《高可用达标定期自查表》的工具,辅助标准落地。

| 高可用达标定期自查表 |
| 标准分类 | 指标分类 | 指标项阐明 | 达标 | 未达标起因 |
| 衰弱达标 | 动态代码扫描 | block 个数和超高圈复杂度个数为 0 | | |
| 故障诊断 | 利用已接入链路跟踪 | | |
| 各项监控指标失常 | | |
| 利用衰弱度 | 98 分以上 | | |
| 存储 | 零碎所用存储,具备主从容灾,多机房的个性 | | |
| 平安 | web 后门工具必须有权限认证 | | |
| 应急预案 | 零碎中是否存在 checklist 文件 | | |
| 中间件达标 | 日志打印 | 应用 slf4j 组件 | | |
| 日志输入须要参数化 | | |
| 存在日志级别动静调整开关 | | |
| log 配置文件,属性设置了 additivity=false | | |
| JDOS 日志配置定时清理 | | |
| worker | 配置了调用次数的 UMP 异样监控报警 | | |
| 两周内,不存在调度异样的工作 | | |
| 依赖 jar 包版本,是否最新版本 3.3.2 | | |
| 线程组和线程数配置是否正当(线程组 <=32)| | |
| JSF | JSF 版本 >=1.7.4、序列化形式 =hession | | |
| 多机房部署 | | |
| 各分组启动脚本配置统一 | | |
| 同组下 IP 流量性能平衡 | | |
| 不存在预公布和线上跨环境调用问题 | | |
| 研发工具领有 token 受权验证机制 | | |
| 外围接口配置了限流策略 | | |
| 办法调用次数 > 高峰期 * 2 报警 | | |
| consumer 生产超时,倡议值小于 2000ms | | |
| 数据库 | 连接数查看,小于最大连接数 *0.8 | | |
| cpu 使用率查看,小于 90% | | |
| 零碎负载查看,小于 cpu 核数 *2 | | |
| 慢 SQL 查看 | | |
| 索引合理性查看 | | |
| 自增 ID 是否 bigint 类型查看 | | |
| 单表数据量 <1000 万查看 | | |
| 监控预警 | 网络 | 域名多 VIP 且散布在不同机房 | | |
| 内网拜访域名绑定的 VIP 不能有外网拜访权限 | | |
| 域名绑定的服务 IP 有效性查看,不能错挂,漏挂 | | |
| 机器监控 | 域名连通性报警 | | |
| IP 维度的监控报警 | | |
| 内存使用率 >90% 报警 | | |
| 磁盘使用率 >85% 报警 | | |
| 零碎负载 >cpu 核数 * 2 报警 | | |
| TCP 重传数 >5 报警 | | |
| JVM 监控 | FullGC 报警,2 小时 <2 次 | | |
| 线程数 < 日常峰值 *1.2 报警 | | |
| CPU 使用率一分钟激增监控预警(默认 5 分钟)| | |
| MQ 监控 | 配置积压和重试报警 | | |
| 缓存监控 | QPS> 缓存分片数 * 2 万报警 | | |
| 内存使用率 >80% 报警 | | |
| 热 key 查看 | | |
| 慢日志查看 | | |
| 性能监控查看 | | |
| 数据分片平均查看 | | |
| 利用办法监控 | 所有 api 接口有调用次数和可用率监控预警 | | |
| 所有依赖的 rpc 接口要有次数和可用率监控预警 | | |
| 是否配置了零碎存活监控预警 | | |

五 总结

本文从“高可用为什么存在着很大挑战?”的问题开展探讨,强调了需要交付过程中,合作效率的重要性,并指出了为什么要听从“今日事,今日毕”的工作准则。又从架构设计,编码实现,平安上线,部署经营等几个方面,具体介绍了技术落地保障相干的领导标准和落地细节。最初又从上线后经营的角度,给出了应急预案三板斧,标准达标定期自查表等比拟实用的经营保障工具。心愿可能给读者带来帮忙。

退出移动版