系统质量治理
一、前言
架构分为三种:
- 企业架构
- 业务架构
- 应用架构
每一层架构都在flow上一层架构,为上一层架构提供支持,并为下一层的架构提供指导。
举个例子,应用架构的服务拆分,一定flow业务架构。由业务架构的职责领域,划分子域(常说的二级域等),从而进行服务拆分。
另外,越接近底层,则越具有通用性,也越常见,掌握的难度也越低。毕竟通用,就意味着很容易进行知识传播。
我们日常见到的技术公众号,推送的内容大部分都是应用架构的东东。因为这些东东才是多数人需要掌握的,并且也是具有普适意义的。
而在应用架构中,质量治理还是非常重要的一块儿。无论是日常工作,还是面试,亦或者是同行沟通,应用架构的质量治理都是常客。举个例子,日常开发中,我们经常需要评估程序的性能,并为性能优化做出努力。面试中,性能优化是常客,系统可用性也是常常被提及。同行沟通,往往都是在一起diss接手项目的性能多么糟糕,扩展性是多么差。囧
原本想好好打磨打磨,但是由于最近组织关系调整,暂时无心整理这个。所以,先放出来啦。对部分细节感兴趣的小伙伴,可以私聊或者艾特我。
二、属性
系统质量属性,代表着架构的核心维度,各个维度的取舍体现了架构师的tradeoff能力。
系统质量属性有很多,划分&组织方式也有很多(如运行时&编译时),这里只是谈一谈日常较为常见的内容。
1.性能
a.刻画方式
- 交易业务:QPS、TPS、RT、出错率
- 流业务:吞吐量、处理窗口、滞后时间
- 系统:CPU、内存、存储、网络
b.解决方案
- 思想:
- 简化:
- 业务:精简流程
- 架构:减少不必要的服务调用与依赖、减少不必要的架构层次抽象
- 编码:减少代码块内容,如循环体、try块等
- 数据:减少不必要的数据处理、传输、存储。如数据清洗
- 时空转换:缓存、索引、副本、bitMap等
- Map_Reduce:dts的合理拆分(这涉及dts的整体设计优化,后详)、本地fork-join框架
- 并行:分布式、多线程
- 调优:Mysql调优、HashMap调优(初始容器大小)、Nginx调优等
- 简化:
- 架构级:
- 缓存为王(《缓存架构》。Mysql的cache&buffer等。可以借鉴缓存中间件-缓存架构的实现(上)与缓存中间件-缓存架构的实现(下))
- 异步为帅(如异步编程&MQ。削峰填谷,局部异步并发有效降低RT(校验场景下,带来少许额外请求量))
- 分布式为将(X轴扩展:提升吞吐量&QPS等;Y轴扩展:出错率降低;Z轴扩展:RT降低,TPS/QPS提升)
- 妥协方案(出于成本考量,可以通过限流(排队)、降级、熔断,在性能不可提升下,保证系统可用)
- 编码级:
- 数据结构:如跳表、COW
- 算法:如折半查找
- 池化:如线程池、连接池
- 局部化:如多线程的一种优化(ThreadLocal)
- 批量:如批量请求合并
c.流程
- 容量规划(负载测试&压力测试)-> 确定水位
- APM监控
- 弹性扩缩容
优化注意:首先得确定性能瓶颈在哪里
但仍然需要思考,这些方法的定位。需要涵盖服务端问题排查与系统优化涉及的性能优化手段
高性能编码,可以借鉴:高性能编程论述
2.可用性
a.刻画方式
- IBM:MTBF、MTTR、HA
- SAP:ATP
- 串联架构&并联架构的可用性评估
b.解决方案
-
本地高可用:服务器、磁盘、适配器卡、网络等
-
业务逻辑保护:操作系统、数据库、应用、服务、
-
容灾多活:HA方案失效、主站点(基础架构)失效、自然灾害
-
本地高可用:
- 集群架构(CA):应用集群、中间件集群、数据集群(包括RAID)
- 分布式架构(AP):分布式应用、分布式中间件、分布式数据库。引申出一致性(Base理论)、脑裂(Lease机制->合理的time设置)等问题
-
业务逻辑保护:
- 预防:数据备份(热冷备份、全增量备份)、严谨的应用与架构设计、N与N-1版本共存、变更审核
- 发现:监控工具、自动化脚本、应用与系统的正常行为描述、应用与系统的异常行为侦测(告警)
- 修复:应用与系统回滚、一键恢复(回复初始状态)、自动恢复、快速数据恢复
-
异地容灾:
- 容灾级别:应用、数据、SAN网络、存储
- DRP规划:流程、演练、BCP
- 容灾方案:成本随数据中心的数量增加而降低。企业Set单元化
逻辑保护技术:备份、快照、CDP连续数据保护、事件溯源(架构)
架构设计方案:限流、降级、熔断、超时&重试、限制(限流、超时等)&隔离(线程池隔离、信号量隔离)
c.流程
- SRE文化(谷歌):SLI、SLO、SLA、错误预算
- 混沌工程:Chaos Monkey、故障注入测试、故障演练等
PS:
美团CAT应用监控:
3.可伸缩性
a.刻画方式
可伸缩性的刻画在与伸缩速率(多久达到目标伸缩数)、伸缩成本(ROI曲线)、伸缩限制(伸缩上限)三个方面。
b.解决方案
- 无状态应用伸缩:无脑复制(注意路由,避免热点(一致性哈希空间)等问题)
- 有状态应用伸缩:
- 共享磁盘模式:向无状态应用转移(将应用的状态,剥离到对应数据存储)
- 结构化数据->共享数据库
- 非结构数据->共享缓存(Redis)、对象存储(OSS)、搜索引擎(ES)等
- 减少文件系统依赖(如CDN直接对接对象存储)
- Share Nothing模式:
- CAP-优化可用性和分区性,弱化一致性:如Kafka的消费级别调整
- 集群管理-优化选举、仲裁、阶段提交、副本、分片管理:脑裂问题(Lease机制)
- 资源预配置(预热):缓存预热
- 共享磁盘模式:向无状态应用转移(将应用的状态,剥离到对应数据存储)
PS:
由于存储本身自带状态,所以伸缩性较弱。如分布式数据库,往往都需要有计划的,进行扩缩容(扩缩容、切换计划、精卫同步等)。
但由于Redis有一致性哈希空间的分片方案,所以Redis是具备伸缩性的。不过,需要进行合理的槽点分配(避免请求不均->热点。注意,槽点变动带来的事件风暴,控制风暴大小(保留安全量,确定IO阈值等))
PS:
- 伸缩前:容量计算&规划、动态感知->扩缩容(参照K8s)
- 伸缩中:路由规则。合理&有效的路由规则
- 伸缩后:各个节点负载的检测。尤其是热点数据问题
PS:
扩展!=伸缩。伸缩是运行时质量属性
c.流程(思路)
场景:秒杀&抢购->热点业务、热点数据
思路:微服务伸缩->网络引流、系统资源、基础设施
4.安全性
a.架构
- 物理安全:
- 访问控制
- 入侵检测
- 人员安全
- 数据安全
- 访问权限:
- 责任分层
- 最小特权
- 数据较密:
- 对称加密
- 非对称加密:无需反向解析(如密码)(哈希->彩虹表->加盐)
- 数字签名:通过哈希获取
- 数据保护:
- 数据逻辑保护(Mysql部分有所涉及)
- 数据高可用
- 访问权限:
- 通信安全
- 网络攻击:
- DDoS拒绝服务攻击:验证所占用资源(SYN Flood -> SYN Cookie回发)、提前阻止(Nginx的OpenResty,进行解析,配合威胁库,进行阻拦)、WAF
- HTTP劫持:(运营商劫持。加料)(工信部投诉、转HTTPS)
- DNS劫持:
- 重放攻击:随机数、时间戳、通信流水号、一次性口令机制(修改密码)
- ARP地址解析欺骗(类比DNS劫持):
- 网络防御:
- WAF应用防火墙
- IDS/IPS入侵检测和防御
- VPN/IPSEC安全通道加密(集团)
- PGP邮件加密
- TLS HTTP隧道加密
- 网络攻击:
- 身份安全
- Authentication认证
- 目录管理
- 用户认证
- Authorization授权
- RBAC(基于角色的访问控制。还有其他访问控制方式,《系统架构设计师》有提及)
- OAuth第三方认证
- Audit审计
- 审计管理控制
- 审计技术控制
- Authentication认证
- 软件安全
- 操作系统安全:
- 病毒
- 蠕虫
- 特洛伊木马
- 零日攻击(即黑客的0day攻击)
- 补丁(参考之前腾讯玄武工作室发现的fastJson漏、或者乌云网的一些case)
- 数据库安全:
- SQL注入
- 推理攻击(对在线教育网站用户的手机号猜测,应该算是推理攻击的一种)
- Web应用安全:
- XSS跨站点脚本攻击:严格区分用书提交的数据&网页代码(编码&过滤)
- 重放攻击:随机数、时间戳、通信流水号、一次性口令机制(修改密码)
PS:有关安全这部分,可以参考《系统架构设计师》安全部分(有涉及多个安全协议)。还可以参考之前黑客相关的资料
- 操作系统安全:
b.解决方案:
- SQL注入预防:
- XSS跨站点攻击防治:
- 加密:
- 签名:
- WAF应用防火墙:
- RBAC访问控制
- PKI基础架构
- .etc
c.流程:
安全基本原则CIA:
- 机密性Confidentiality
- 完整性Integrity
- 可用性Availability
安全评估方法:
- 安全测试:
- SAST静态测试:静态源码扫描
- IAST交互式测试:在业务流量中把参数替换成攻击向量,然后发送给被测服务器,通过服务器的回报对测试结果进行判断
- 安全扫描:对系统/应用进行安全漏洞(已有)扫描
- 威胁模型:
- 攻击树分析:用树型结构来表示系统面临的攻击,其中根节点代表被攻击的目标,叶节点表示达成攻击目标的方法。
- DREAD风险评估:漏洞等级评估,稳定性较差
- 渗透模型:
- 红蓝对抗:
- 白帽黑帽:
PS:
安全框架:
- ITIL:
- 自适应安全
- 网络韧性:
- .etc
网络韧性,在数学的简单定义是,要使一个网络分崩离析、丧失原有功能,需要被除掉的节点数占节点总数的比例。
PS:
AiR-ViBeR: Exfiltrating Data from Air-Gapped Computers via Covert Surface ViBrAtIoNs
Mordechai Guri教授提出了许多诸如此类的物理安全漏洞问题。
ATT&CK向安全白银时代进军:统一语言,重装上阵【open-ata】
自身对黑客行为的了解:渗透-提权-后门...
ATT&CK
5.可扩展性
方法论:
架构扩展立方体:X轴:水平复制(无脑复制;可用性);Y轴:功能拆分(分割责任、功能、数据;隔离;与领域划分相关);Z轴:特征分割(对业务透明;提供诸如优先级、就近等服务)
- 应用:
- X轴:水平复制(无状态应用、状态剥离(如Session);涉及性能规划、弹性扩缩容等);
- Y轴:服务拆分(参考微服务拆分。个人理解DDD+业务主链路;资源迭代分配;服务隔离)
- Z轴:客户分割(地域等;加速查询等)
- 数据:
- X轴:水平复制(SQL CDC:Change Data Capture,如canal、精卫等);
- Y轴:库表拆分(这里的表拆分,不是同一功能的逻辑表拆分为多个物理表,具体拆分可以参考微服务拆分);
- Z轴:分库分表(同一个逻辑库表,拆分出多个物理库表。往往路由规则采用某字段进行哈希)
架构扩展立方体的不同维度,往往是共存的,即套娃
组织扩展性:沟通链路计算、六个披萨理论、
个人理解,组织扩展性提高了沟通效率,进而提高了内聚主题(团队目标等)下,团队思考的有效连接,从而迸发出许多创意。可能这也是spotify为什么会成功。
流程扩展性:CMMI软件成熟度模型
个人理解,CMMI软件成熟度模型,实质一种精细化的过程。这也是我们业务的发展过程。
- 初始-拍脑袋
- 管理-方法论
- 定性-流程化、制度化
- 定量-SMART原则
- 自动-信息同步&自我优化
百度百科:
CMMI共有5个级别,代表软件团队能力成熟度的5个等级,数字越大,成熟度越高,高成熟度等级表示有比较强的软件综合开发能力。
CMMI一级,执行级。在执行级水平上,软件组织对项目的目标与要做的努力很清晰,项目的目标可以实现。但是由于任务的完成带有很大的偶然性,软件组织无法保证在实施同类项目时仍然能够完成任务。项目实施能否成功主要取决于实施人员。
CMMI二级,管理级。在管理级水平上,所有第一级的要求都已经达到,另外,软件组织在项目实施上能够遵守既定的计划与流程,有资源准备,权责到人,对项目相关的实施人员进行了相应的培训,对整个流程进行监测与控制,并联合上级单位对项目与流程进行审查。二级水平的软件组织对项目有一系列管理程序,避免了软件组织完成任务的随机性,保证了软件组织实施项目的成功率。
CMMl三级,明确级。在明确级水平上,所有第二级的要求都已经达到,另外,软件组织能够根据自身的特殊情况及自己的标准流程,将这套管理体系与流程予以制度化。这样,软件组织不仅能够在同类项目上成功,也可以在其他项目上成功。科学管理成为软件组织的一种文化,成为软件组织的财富。
CMMI四级,量化级。在量化管理级水平上,所有第三级的要求都已经达到,另外,软件组织的项目管理实现了数字化。通过数字化技术来实现流程的稳定性,实现管理的精度,降低项目实施在质量上的波动。
CMMI五级,优化级。在优化级水平上,所有第四级的要求都已经达到,另外,软件组织能够充分利用信息资料,对软件组织在项目实施的过程中可能出现的次品予以预防。能够主动地改善流程,运用新技术,实现流程的优化。
解决方案:
架构扩展立方体:
- X轴(水平复制):
- 应用:无状态、容器化、Serverless
- 数据:多副本、读写分离、冷热隔离。SQL CDC技术
- Y轴(功能拆分):
- 应用:
- 设计:服务拆分、界限上下文交互(DDD、主链路设计)
- 运行:服务发现、服务治理、负载均衡、服务追踪(参考Spring Cloud服务治理等)
- 数据:
- 应用:
- Z轴(特征分割):
- 应用:负载均衡
- 客户端Ribbon
- 服务端Nginx
- K8s Service
- ESB:企业服务总线
- API Gateway
- 数据:
- 分布式多片架构(CA)
- 分库分表:客户端(sharding-jdbc)、中间Proxy(Mycat、TDDL)、数据库(Spanner)
- 应用:负载均衡
思考
Q:除了状态剥离外,有状态应用如何进行扩展
A:功能拆分,以及特征分割(貌似Session的剥离也可以按照这个思路)
Q:除了状态剥离外,有状态应用如何进行水平复制?
三、流程
质量治理涉及的流程,可以参照集团的安全生产(如《安全生产指南》)。
质量流程
流程:
安全生产:
核心:可监控、可灰度、可回滚
容量预估、【核心】、复盘、快速止血、
PS:不站在架构角度,而是站在编码角度,可读性是很重要的。