上篇文章记录了代码评审笔记,这篇继续延伸记录项目有关内容
健壮性与鲁棒性
软件的简装性差
一个人经常生病的话那我们说他体质差。软件会有黑客的各类破解,病毒。或者在使用中因为数据错误、操作错误、设计功能问题等等导致软件的可用性差,即称为软件的健壮性差。
健壮性与鲁棒性
• 健壮性(意译)
>异常情况
>特殊环境
>超限情况
>依然能够稳定运行的能力
• 鲁棒性(音译) 形容词robust强健的、强壮的、耐用的、坚固的、富有活力的
如何构建健壮性的系统
健壮性度量
可分为如下3个维度
• 架构:负载均衡容灾能力
• 代码:参数校验、异常处理、分支覆盖
• 环境:混沌工程、异地多活
负载均衡
负载均衡是防止服务或者数据热点问题的出现,使得集群内的所有服务器的负载水位在同一个水平线上
• 轮询法 按顺序轮流地分配到各个服务器上(可以加权)
• 随机法 流量随机分发
• IP哈希法 保证IP地址请求到同一服务器上
• 最小连接数法 根据服务器的连接数来分配流量
容灾能力
• 限流 有策略地丢弃部分用户请求
• 降级 部分功能不可用或用户体验被降级
• 灾备 复制多份系统能力或解决数据核心服务单点问题
• 熔断 服务全部停止响应,以保护核心流程
数据健壮性
数据是企业生命线
• 逻辑删除 杜绝物理删除
• 定时本地冷备份 可以作为数据日志快照
• 定时云端离线备份 防地震、防水灾
• 主备准实时备份 快速切换服务能力
代码健壮性
• 所有的POJO类属性必须使用包装数据类型
• 定义DO/DTO/VO等POJO类时,不要设定任何属性默认值
• 定义数据对象DO类时,属性类型要与数据库字段类型相匹配
• geter/setter方法中,不要增加业务逻辑
• 禁止在POJO类中,同时存在对应属性XXX的isXxx()和getXxx()方法。
• 构造方法里面禁止加入任何业务逻辑,如果有初始化逻辑,请放在init方法中
封装是一种对象功能内聚的表现形式,主要是被封装的组件、类、方法的影响半径尽可能地小,这也是提升系统健壮性的一种思维方式。
面向失败的架构思维
• 网络抖动 甚至是断网,如何提示、恢复、切换
• 服务超时 任何服务都要考虑超时没有返回的可能性
• 弱电断电 多云。多地部署能力
• 洪峰流量 流量打爆服务器后的架构健壮性
面向失败设计
从面向对象角度来看,这还是面向功能或者业务视角的,是功能的性能,功能的容量,功能的稳定性。面向失败的设计,就是以“失败”为对象,天然为了失败而存在的设计思想。
软件如同人一样,在孕育及成长过程中,受先天基因及后天成长环境影响,都会遇到不同程度影响生命安全的问题
在软件生命周期中,也会出现各式各样的问题,我们需要通过面向失败的设计,防范和监控已知的确定性风险及末知的不确定性风险:
• 任何环境都是不可信赖的
• 任何外部依赖接口都有可能出错的
• 任何异常都需要响应和处理的
• 任何行为都需要日志记录的
• 任何系统的上线都需要严酷的测试
健壮性测试
• 功能性测试 想象用户的一切可能行为进行正确性验证
• 稳定性测试 确定系统长时间在正常压力情况下运行的有效性
• 性能测试 系统能够提供的最大服务级别的能力
• 混沌工程 确定线上系统故障的恢复能力
分支覆盖
• 代码覆盖率
• 条件判定覆盖
• 路径覆盖
混沌工程
混沌工程 (Chaos Engineering):是在分布式系统上进行实验的学科,是一种未雨绸缪的心态。由薄弱的环节上,做到自我发现。特点是放置一个炸弹进去,控制爆炸半径,评估损伤和自我修复能力。
Netflix提出 Chaos Monkey
混沌原则
在开发混沌工程实验时,可遵循以下原则,将有助于实验设计:
• 建立稳定状态的假设
• 多样化现实世界事件
• 在生产环境运行实验
• 持续自动化运行实验
• 最小化“爆炸半径”