系统稳定性建设的一些感想

背景

我目前主要负责供应链系统: 支持公司重资产业务持续精细化运营.
系统之前是一个外采系统: B2P自闭环业务流程, 资产管理以及业财一致等业务功能集一身的单体应用系统.
随着业务发展,系统不断运维迭代,逐渐暴露出很多痛点,比如:

  1. 资产规模超出数据处理引擎原设计能力,性能不足严重影响业务数据处理,月结.
  2. 技术架构过时(Struts,Ext,EJB等),不稳定,经常出现安全漏洞等问题
  3. 不能集成公司基础服务,出现问题,依赖原厂远程配合修复,维护性差

基于以上主要痛点等因素,促使我们决定重构系统;目的就是系统稳定性建设.

思考

在准备重构之前,做了一些思考:我们的系统特性是什么? 怎样是系统稳定性? 围绕稳定性建设我要注意哪些?

系统特性方面:

1) 批处理系统(大数据处理时效),
2) 财务核算系统(数据清晰明确),
3) B2P系统(大表单业务逻辑),
4) 资产库存管理系统(数据严格准确).

稳定建设方面: 

  • 系统可靠性: 高可靠系统,故障次数少,频率低,在较长的时间内无故障地持续运行。
  • 系统可用性: 高可用系统,故障时间少,止损快,在任何给定的时刻都可以及时地工作。
  • 系统稳定性: 在系统可靠性和可用性基础上,即降低故障频次和提升止损速度的情况下,要求系统的性能稳定,不能时快时慢。

总结,不仅需要系统尽可能随时提供服务,并且系统能提供有质量保障的服务。

细节

系统可靠性: 减少故障次数

1. 系统故障复盘

老系统(过往系统)的运营数据, 故障Case是一笔难得的财富, 对于今后系统重构提供有利依据. 所以充分的分析复盘是很值得的.

1)  从点到面, 必须要深挖问题本质, 复盘过程中, 切记不可出现“忘了”, “好像”, “没仔细”, “没及时”,“时间不够”等敷衍, 太形式的字眼.
2)  根据“重要紧急”, “重要不紧急”两个维度, 作出短期及中期, 且必须可真正落实的计划, 并且要明确责任人, 计划方案及DeadLine; 并持续跟进, 直到完成所有的todo.
3)  必要事故, 明确故障责任人. 有错要认, 出了问题不能逃避要勇敢承担, 不要有“做多错多”的顾虑.制定合理“奖惩制度”, 做好奖惩平衡.

2. 上线流程规范

1)  主流程服务,必须经过CodeReview,才能上线.
2)  主流程服务,必须经过测试回归, 准出确认,才能上线.
3)  主流程服务,代码改动量大,影响范围大,必须选择不影响业务或低峰期时间上线, 且必须梳理并告知上下游可能影响范围.
4)  上线流程,  严格按照流程计划中各个里程碑严格执行,并确认结果.

3. 开发代码规范

相信每个开发团队都有一套项目结构规范,  代码规范及CheckStyle措施,按照执行应该没有什么问题。但根据多年的踩坑经验及原有系统特性,要根据自身系统特性明确几条红线规范,如:
1)  select语句,必须加limit;不可能需要把所有上百万,上千万的数据都查出来,容易把网卡打满.
2)  select语句,where后面条件项,必须有一列是必选项,且该列是有索引的;千万级, 亿级数据的大表,因没走索引而导致全表扫描,很可能把数据库直接干挂。
3)  update语句,要写单场景SQL,避免出现动态拼接的公用SQL,且where后面的条件项,必须有一列走索引,且该索引的区分度要高;update、delete为动态拼接SQL时,若漏传条件项,不仅IO效率很低, 并且会导致全表被修改或删除.
4)  循环语句中,不允许进行rpc和db的IO操作,并且尽可能优化CPU的IO计算; 过多的循环,耗时长, 且可能把下游和db直接干挂。

4. 请求防刷控制

1)  外部,防止DDoS攻击;
2) 内部,防止上下游服务,客户端等由于错误代码而频发刷新访问等情况.
3) 具体实现策略相对成熟, 如:

MQ幂等校验; 通过用户IP及方法设置防刷阈值; 服务间做鉴权验签访问等.

此外, 如果对于可靠性要求很高的核心服务, 要尽可能保证两个原则:

1)  最小链路闭环, 尽量少依赖其他服务, 尽量少依赖中间件.
2)  最大限度隔离, 不相干非核心服务, 尽量隔离部署.

5. 压测限流控制

评估系统峰值流量, 预估未来可预见的发展情况; 通过数据回流方式进行压测以保证业务处理能力的同时, 再通过QA对系统服务能力进行专业压测.
根据压测出的阈值, 做出必要的限流,告警等措施; 避免系统服务过载而挂掉.

系统可用性: 缩短故障时间, 及时响应止损  (故障时长=发现问题时长+定位问题时长+解决问题时长)

1. 上线流程规范

此处再提上线规范的出发点不同: 基于系统可用性的上线规范, 主要从问题的发现, 定位, 解决来思考.

指标检查: 在预发环境(有条件的话尽可能用灰度环境: 最接近于生产环境)测试过程中, 除了正常的业务功能测试, 要从三个方面来着重持续观察:

1)  基础指标: 服务器CPU, 内存, IO, 网络, JVM, GC等是否正常
2) 应用指标: 服务接口QPS, TPS, RT等, 考虑是否有明显异常需要优化
3) 业务指标: 必要核心主流程Case(支付相关等)走一遍, 是否正常使用, 后台是否会暴露异常日志等

回滚方案: 如果在上线后, 发现仍有未知指标异常, 且不能及时处理的情况下, 针对本次上线要做合理可行的回滚方案.
常见的回滚方案考虑方面有: 代码回滚, 表结构回滚, 数据回滚, 以及程序流量开关切换等.

2. 系统监控告警

监控告警主要解决发现问题的时长.

针对上面所说的三个指标做监控, 进行日常巡查, 保证发现问题时, 一定是先收到系统自身监控告警, 而不是通过用户先来反馈.
此外, 报警也需要有标准: 告警要做到数据精准, 级别明确; 不能存在过多的报警, 尤其是误报; 过多的告警等于没有告警, 误报等于“狼来了”, 反而会让大家忽视掉有用的告警: 对问题发现,处理不及时. (每天成白上千个邮件告警没有人会仔细看)

3. 系统应急预案

应急预案主要解决定位问题及解决问题.

通过经验及过往Case的案例, 及时总结沉淀文档, 明确处理步骤; 尽可能做到发生同类问题, 任何一个人都可以“无脑”按步骤进行处理.
此外, 预案肯定不是“死的”(plan is nothing, planning is everything.) 是要随着技术架构, 运维迭代, 业务发展来不断更新, 必须做好“断舍离“;不能把预案做的越来越重, 越来越难懂.

4. 系统故障演练

故障演练主要从已知,半知,未知三个方面来准备

已知: 已经发生过的故障Case, 按照应急预案演练去做, 熟能生巧
半知: 从已知中, 思考发现未知因素, 进而补充预案
未知: 若发生未知故障, 需要有临时决策方案, 安排人员有序排查定位; 采用系统版本回滚等方案尝试解决问题; 或确定问题原因及解决方案后, 采用应急临时解决方案等. 尽可能缩短故障时间.

5. 系统自动防御

这方面经验比较少, 可想到的是需要我们在开发过程中多思考, 每个环节都要有安全意识, 逆向思维; 比如:
1) 当下游依赖核心服务不可用, 失败重试及失败时间阈值, 可服务降级方案等
2) 当下游依赖基础服务不可用, 上有流量激增而导致不可用时, 可服务熔断,补偿机制等

总结

我认为对于系统可靠性及可用性建设肯定是重要且紧急的事情, 但系统稳定性建设属于重要, 但没那么紧急的事情. 因为保证系统稳定是需要坚持的长期工作.

我一直认为再牛逼的技术也要作用在合适的业务上; 没有最好技术, 只有适合技术. 在做系统稳定建设的过程中, 要随着业务迭代发展, 技术方案跟着演进: 服务拆分,水平拆分,垂直拆分,冷热分离,技术选型等等; 且尽可能不自己造车, 复用现有且成熟技术经验; 没有一粒银弹能解决所有问题, 站在巨人的肩膀上强大起来.

系统稳定性建设,我们依然在路上.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值