之前有在文章中介绍过云原生的十二要素,今天来介绍下云原生架构以及其架构设计中需要考虑的关键因素(后续逐步完善)。
概要
还是先通过一张图简单介绍云原生架构的组成,具体见下图:
- 敏捷基础设施
- 基础设施及代码(公有云、私有云)
- 公共基础服务
- 中间件服务
- 监控、告警反馈
- 微服务架构
- Spring Cloud
- Dubbo
- DevOps
- 持续交付流水线
- 自动化工具链
- 团队文化
- 康威定律
- 工程师文化
- 敏捷迭代
- 架构设计
- 高可用、高可靠
- 可扩展性
- 性能
- 一致性
接下来重点讲解其架构设计中的四个要素。
架构设计
主要包括:高可用、可扩展性、性能、一致性这四个方面。
可用性设计
可能影响系统可用性的因素主要有三方面:发布、故障和压力。下面就分析基于这三方面的应对方案。
发布
- 影子测试
除了使用log或者tcpcopy来复制影子环境以外,如果系统使用了MQ,可以直接为MQ添加消费者,将流量复制到影子系统; - 蓝绿发布
蓝绿部署的问题是: 需要一套独立的闲置资源; - 灰度发布
过程:内部员工
>1%的外部友好用户
>5%的友好用户
>10%的友好用户
>全网发布
故障(容错设计)
- 消除单点
飞行员总是要将飞机上升到执行两次失误的高度才开始做动作,也启发我们为什么负载均衡后的节点都推荐是n+2
而不是n+1
; - 特征开关
代码分支管理,如果是基于master开发,需要提供特征开关,从而避免相互影响的时候能够快速切换; - 服务分级
在高流量期,可以考虑牺牲部分功能,通过降级服务来达到整体系统的高可用; - 超时重试策略
- 熔断器
- 故障隔离
压力(流控设计)
- 限流算法
窗口、漏桶、令牌桶 - 限流策略
GW入口、微服务入口、中间件 - 容量预估
全链路压测 - 故障演练
各种monkey
扩展性设计
- AFK扩展立方
X
: 横向扩展(数据库、磁盘压力)Y
: 微服务拆分(数据库压力)Z
: 分库分表 - 数据库扩展
- 数据库的三坐标
X
: master+slave,扩展多个slave用于读;Y
: 分库(微服务拆分);Z
: SATA盘,单表十个字段,数据量达到1千万会出现瓶颈,需要分片 - 数据库分片方法
- 区间法(按照ID范围), 容易导致数据热点;
- 轮转法(hash(key)mod node_number ),不容易排序,拓扑变化需要重新分配
- 扩容
- 停服扩容;
- 0中断扩容(先将新加节点设为slave,然后提升为master,再修改数据库中间件配置,注意:需要支持去重)
- 应该让单次请求在一个数据中心处理完
- 数据库的三坐标
- 两地三中心、同城多活、异地多活
性能设计
性能指标
- 响应时间
- 吞吐量
单位时间的响应次数 - 负载敏感度
用户增加、系统响应时间的衰减度(系统数据量、数据增长速度) - 可伸缩性
使吞吐量增加一倍,需要扩展的节点数(资源限制)
优化方法
- 通信优化
序列化消息(grpc protobuf 等) - 通过中间件提高吞吐量
- MQ解决写的性能瓶颈
- 缓存解决读的性能瓶颈(cache aside, cache as sor)
一致性设计
由于微服务拆分后,各个微服务使用独立数据库,可能导致数据不一致。
CAP
- 一致性(Consistence)
分布式系统中的所有数据备份,在同一时刻是否同样的值。(等同于所有节点访问同一份最新的数据副本) - 可用性(Availability)
集群出现故障节点后,是否还能响应客户端的读写请求。(对数据更新具备高可用性) - 分区容忍性(Partition tolerance)
实际中通信产生延时。系统如果不能在时限内达成数据一致性,就意味着发生了分区的情况,必须就当前操作在C点和A点之间做出选择。
BASE
- 基本可用(Basically Available)
基本可用是指分布式系统在出现故障的时候,允许损失部分可用性,即保证核心可用。 - 软状态( Soft State)
软状态是指允许系统存在中间状态,而该中间状态不会影响系统整体可用性。分布式存储中一般一份数据至少会有三个副本,允许不同节点间副本同步的延时就是软状态的体现。mysql replication的异步复制也是一种体现。 - 最终一致性( Eventual Consistency)
最终一致性是指系统中的所有数据副本经过一定时间后,最终能够达到一致的状态。弱一致性和强一致性相反,最终一致性是弱一致性的一种特殊情况。
Quorum机制(NWR原理)
思想
:一致性不取决于写时进行全同步,只要保障读的时候能够读到最新的数据就解决问题了。
只需要满足 R + W > N
, 其中N为副本数, R和W分别为读写的节点数。
实现强一致性
两阶段提交的问题
- 可能第二阶段出异常(某个参与者网断了),无法处理;
- 协调者的可用性无法保障,可能导致第一阶段后资源被锁死;
- 两个阶段之间需要锁定资源,可能导致阻塞
三阶段提交
- 流程和思想
- 将两阶段的第一阶段分为两个阶段,先请求,得到同意字后再锁定资源;
- 另外引入超时机制;
- 问题
- 可能第三阶段出异常(某个参与者网断了),无法处理;
- 流程和思想
如何实现最终一致性
- 重试
- 记录操作状态(对失败的操作做重试)
悲观锁与乐观锁
分布式锁
- zookeeper
- Redis
基于setnx
问题在于Redis是异步复制的,如何保障主节点挂了之后,不影响分布式锁?
幂等性
- 幂等令牌(redis)用token作为key,value-1代表正在处理,value-2代表处理成功;