系统设计原则
0.1:以繁为全,尽可能收集过去的经验
0.5:精炼描述,收敛条目,以能意会为目标
0.7:提供一份对应的指南或参考实现
1.0:多数人认同的版本
这是一个强制性规范
概述
本原则采用定性的方式描述,尽量将实现的自由度开放给使用者
名词说明
平台
位于一套系统的逻辑中心,提供API和Web供其他服务或者人员调用,用于控制系统的行为
系统软件
特指对性能有极致要求,在CPU、内存、IO等方面有极低开销要求,极高并发性能要求的软件,一般都是生产软件
辅助组件
一般是围绕生产软件服务的一些组件,小到某个计费脚本,大到配置服务、调度服务等
命名
推荐使用具有明确定义的名称
应该同时具有中英文,且能够互相意译对应上
使用代码和软件命名可以使用英文缩写,例如边缘云网关,使用Edge Gateway,缩写EG
不建议使用代号直接作为软件正式名称
例如泰山、天柱等,这种命名容易导致使用方的混乱,以及对未来软件的用途和定位产生歧义
代号比较适合短期项目阶段的名称,或者某一个版本的名称,给枯燥的工作带来一些愉悦或调侃,但不适合作为正式名称
核心原则
设计原则
系统、平台、软件、配置、操作人等任何地方的bug都是预期一定存在的
不存在100%SLA指标
不信任代码、服务器、网络的复用
组件之间互相不信任对方可靠性
软件内部不同模块之间不信任对方可靠性
不信任配置是可靠的
不信任操作者是可靠的
不信任API调用方是可靠的
没有故障是最大的风险
墨菲定律
不信任任何输入
任何相对于系统、平台、软件、组件以外的输入都是不可信任的
软件自身配置
外部api调用
服务的请求
运行期间不应该因为非预期输入而停止服务
非运行期间不应该因为非预期输入而崩溃
非预期输入应该有明确的错误原因输出和定位信息
任何操作人的输入都是不可信任的
生产数据库不应该由人直接操作写入
具备分级别故障处理
重大客户和域名要保持全系统所有组件的冗余设计
所有组成部分都要考虑自持能力
系统任何组件,在外部故障时必须保持具备连续服务的能力
数据一致性必须考虑故障的状态如何维持或明确定义SLA
日志、配置等优先考虑服务人,必须考虑服务其他机器人
必须假定故障状态人工介入处理
必须考虑日志、配置等可以由软件管理
日志应该作为可以全网布控的对象,不同类型的日志有明确的标识来分类处理
服务竭尽全力保持服务连续性
故障状态确保服务有备份服务状态
业务配置生效不应该影响服务连续性,有限影响服务质量
非业务配置生效尽可能不影响服务连续性,有限影响服务质量
影响服务连续性的组件应该在系统设计中降低影响,并有明确的指标
软件升级和降级不应该影响服务连续性
确保监控由外向内建立
每个系统组成部分都需要搭配监控,将监控作为软件的一部分
监控是立体网络
最外层监控确保黑盒监控服务的有效性
最内层监控确保能够及时定位并处理故障
部署原则
软件和功能支持可灰度
软件部署
软件升级和降级必须支持业务不中断
软件对外部的依赖必须是显示声明的,可以由自动化部署工具感知并自动处理
*云原生支持
业务指标
必须考虑适应现代网络环境
ipv6支持
适应云环境的内外网IP分离架构
支持一个环境中多个ip,并作为不同用途的环境
必须考虑支持复杂的多租户环境
必须支持同域名多渠道的情况
必须支持业务配置的灰度
必须支持没有只有80、443等少数几个端口的场景
技术架构原则
系统软件
基础设计原则
能力与策略必须分离
例如上游多种分配方式与回上游策略应该分离,实现灵活的策略组合
业务配置与规则分离
例如安全策略与某个域名使用的安全策略应该是分离的,不能放在同一份配置中
例如IP规则池与IP屏蔽规则应该分离,不应该绑定IP规则池与IP屏蔽规则混合在一个配置中
例如WAF规则与具体域名配置应该分离,不应该耦合在一起
必须能够合理解释对每一点系统资源的占用
每一字节每一份CPU每一次IO都应该能够解释对系统资源占用的状态
如果无法解释,应该配有明确的单点性能测量来辅助
遵守Less is More理念
核心应该尽可能简单可依赖,只保留最重要的特性,能够在胶水代码中最好的事情不迁移到核心
外围胶水应该分层次,区分重要业务逻辑,还是定制化逻辑
不过分封装
不明确有一致性的需求都尽可能不添加到核心中
需求应该拆解为核心功能和胶水逻辑
遵循大于取巧
尽可能遵循软件的设计理念和特性
取巧的技术路线必须配套未来重构的路线图
配置与实现解耦合
配置聚焦于描述需要什么功能
实现翻译功能描述来达成目标
配置和实现解耦合是未来进一步迭代软件的必备条件
性能基准
必须有典型负载的基准性能指标,用于评估性能降级和提升的参考指标
基准性能分为性能和质量两种
典型负载由线上数据等效而来
性能指标必须在典型负载下完成,典型负载由线上数据等效
质量指标必须由最差质量水平和p99指标、平均值构成
复杂的情况下,应该评估最轻量和最复杂场景的性能指标,用于评价最好与最坏的水平
基准测试应该尽可能模拟线上环境,包括编译参数、功能启用等都应该同线上,最好直接使用即将发布的软件安装包
每一项功能都应该完成对比基准的性能测试
功能的重大变更应该重新更新基准数据
功能的每一个特性都应该评估性能
除了评估直接影响性能,还应该评估辅助特性对质量的影响,例如大批量更新配置等
性能基准测试水平在一定参考系中,尽量再理论上能给出合理的解释,解释为何更好或更差,避免盲目
辅助组件
资源占用严格限制
有突发资源需求应该削峰为平均需求
平台
以轻资产无状态为最优设计
定制化部分与通用部分应该从代码层面隔离
资源冗余明确估算并监控
生产数据库(需要基础平台添砖加瓦)
权限
不允许人肉在线修改数据库
必要时,人肉在线操作数据库必须两个以上的人同时确认操作,并有离线数据库验证操作动作
生产数据库不允许远程直联
人肉在线连接数据库通常只允许只读
性能
容灾
故障处理
代码部署(需要基础平台和产品研发添砖加瓦)
权限
不允许未经测试用例的在线代码更新
容灾
故障处理
人工驾驶模式(需要运维添砖加瓦)
考虑应对突发故障等状态,涉及核心业务处理的平台、系统、软件等都应该具备人工驾驶的能力
人工驾驶的模式值得设计
平台和误操作故障冗余设计(需要运维和产品研发添砖加瓦)
平台存在bug可能或人工误操作,应该在核心流程中添加二次验证,并应该直接固化这些逻辑,避免任何时候的意外放行
账号体系(需要产品研发和安全添砖加瓦)
内部权限应该区分等级,每个等级区分只读和可写
应该关联OA等系统,实现离职等异常状态的自动权限处理
关键操作都必须有记录和审计能力