- 系统架构并非一蹴而就,架构目标也是随着业务发展而变化,业务推送技术发展,技术反哺业务。
- 系统架构演进:单机 -->集群 -->分布式微服务
架构演进(日活用户占总用户量大概%4到%10,推测总用户量)
(1)单体应用架构(1千UV以下)
优点:易于测试,便于集成,对小型项目友好。
缺点:启动时间长,依赖庞大,单机性能瓶颈明显,资源容易出现争夺。
(2)应用数据分离架构(5千UV)
优点:易于测试,便于集成,对小型项目友好。
缺点:启动时间长,依赖庞大,单机性能瓶颈明显,资源容易出现争夺。
(3)应用集群架构(1万UV)
优点:避免应用程序单点故障,提高应用处理能力。
缺点:链路存在单点故障-网关-数据库,单机性能瓶颈明显。
(4)应用集群缓存架构(5万UV)
优点:热点数据缓存,提高性能。
缺点:增加维护成本,包括缓存穿透/击穿/雪崩等问题。
(5)应用集群+读写分离架构(10万UV)
优点:读写分离,提高数据库性能和可用性。
缺点:增加维护成本,数据量激增单库容易瓶颈。
(6)微服务化-分库分表架构(100万UV)
优点:易开发、理解和维护独立的部署和启动,数据库性能提升。
缺点:分布式系统-分布式事务问题,管理多个微服务,服务治理问题。
(7)多元化业务-数据异构架构(500万UV)
优点:数据源多样化,业务性能提升明显,系统复用性高,支撑更高并发+海量数据。
缺点:运维复杂增高,链路分析复杂和技术广度+深度大。
常规互联网项目HTTP请求响应的全链路
三高下的架构设计概述
- 对于技术人员的三高为:高并发、高可用、高性能
(1)什么是高并发?
- QPS/TPS 来衡量系统的对任务的处理能力
- TPS
- Transactions Per Second 每秒事务数, 可以是一个接口、多个接口、一个业务流程, 包括增删改操作
- QPS
- Queries Per Second, 每秒查询数, 指一台服务器每秒能够响应的查询次数
- QPS 只是一个简单查询的统计,不能描述增删改等操作
- 如果只是查询操作 TPS = QPS
- TPS
(2)什么是高可用?
- SLA 衡量一个系统可用性有多高,目标系统 7 x 24 小时不间断服务。
- 分类
- 时间维度:系统可以正常使用时间与总时间之比(全年为例子)1年 = 365天 = 8760小时
- 99.9 = 8760 * 0.1% = 8760 * 0.001 = 8.76小时
- 99.99 = 8760 * 0.0001 = 0.876小时 = 0.876 * 60 = 52.6分钟
- 99.999 = 8760 * 0.00001 = 0.0876小时 = 0.0876 * 60 = 5.26分钟
- …
- 请求次数维度:请求总次数和失败的占比 ( 1000次请求为例子,相对简单 )
- 系统可用性99%:表示1000个请求中允许1000 * (1- 99%) = 10个请求出错
- 系统可用性99.9%:表示1000个请求中允许1000 * (1- 99.9%) = 1个请求出错。
- …
- 时间维度:系统可以正常使用时间与总时间之比(全年为例子)1年 = 365天 = 8760小时
- 9越多代表全年服务可用时间越长服务更可靠,停机时间越短
- 但往往存在网络/机房问题,应用更新发版导致服务不可用
- 大厂多数业务4个9是刚需,5个9是目标,6个9是理想
(3)什么是高性能?
- RT来衡量系统的响应速度,程序处理速度非常快延迟低Latency,所占内存少,cpu占用率低
(4)如何做到高并发-高性能技术?
-
系统架构
- 无状态业务-水平扩展(Scale Out),只要增加服务器数量,就能线性扩充系统性能
- 架构的难点是难做到全链路的水平扩展
-
【负载均衡】思想
- 节点轮询、随机、加权轮询、节点固定hash
- 网络 DNS解析轮询
- 网关分发请求后端服务
- 应用服务内部RPC负载均衡
- 数据存储-分库分表-负载分发
- 节点轮询、随机、加权轮询、节点固定hash
-
【缓存】思想
- 本地缓存/分布式缓存
- 前端浏览器缓存静态资源
- 网络DNS解析缓存
- 应用程序 内存缓存/分布式缓存
- 数据存储Mysql Query Cache
- 本地缓存/分布式缓存
-
【池化复用】思想
- 线程池/对象池/连接池/内存池
- java线程池技术
- Jdbc/Redis/HttpClient连接池
- SpringIOC容器对象池
- 线程池/对象池/连接池/内存池
-
【异步】思想
- 多线程/消息队列
- 前端ajax异步请求
- RocketMQ/Kafka 同步双写-异步刷盘
- 应用程序多线程异步处理
- 多线程/消息队列
-
【预处理-惰性更新】思想
- 定时任务/懒加载
-
运营后台报表数据,定时任务提前计算好
-
Mybatis懒加载
-
- 定时任务/懒加载
-
【分而治之】思想
- Mater-worker
- Hadoop中的MapReduce
- JDK. Fork/Join Framework
- 消息队列的广播消息
- 归并排序算法
- Mater-worker
(4)如何做到高可用技术?
(冗余集群化 + 自动故障转移failover)
-
集群架构
- 将多个相同的应用程序集中起来提供同一种服务,某个节点故障不影响系统
- 可以横向扩展性增加节点提高并发处理能力
-
微服务集群
-
Redis集群/Kafka集群/Nginx集群
-
Nacos集群/Mysql集群/ZK集群
-
-
熔断降级
- 保险丝,熔断服务,为了防止整个系统故障,抛弃一些非核心的接口和数据,返回兜底数据
-
限流
-
当访问频率或者并发请求超过其承受范围的时候,考虑限流来保证接口的可用性
-
漏斗模型,不管流量多大均匀的流入容器,令牌桶算法,漏桶算法
-
-
隔离
- 服务和资源互相隔离,比如网络资源,机器资源,线程资源等,不会因为某个服务的资源不足而抢占其他服务的资源
-
多活架构
-
同城双活-双机房
- 两个机房部署在同城,物理距离较近,两个机房用「专线」网络连接,比单个机房内延迟要大一些,但整体的延迟是可以接受的
-
参考
- 同机房:0.1ms
- 同城双机房:1ms(100公里内)
- 北京到广州:55ms
-
-
异地多活-两地三中心
- 两地是指 2 个城市,三中心是指有 3 个机房,其中 2 个机房在同一个城市
- 同时提供服务,第 3 个机房部署在异地,只做数据灾备