[db:标题]
摘要:高并发架构设计无外乎“拆、缓、防”三板斧:先通过业务分治、数据分片、集群化部署把系统横向扩展到极致;再以多级缓存与消息队列将瞬时峰值削平成可线性增长的消息流;最后用限流、熔断、降级以及异地多活等多维防护手段,为系统守住最后的容量边界。
前言
如何能让系统抗住高并发流量,要考虑的因素有很多,但是真的让你讲一下都有哪些,很多人肯定就会说,用Redis缓存啦,用MQ做解耦啦,总之就是想起来这一块儿就说一嘴,想起来那一块儿也说一嘴,总之就是说的不能成体系一些。
一般面试官问这种问题的时候,是想看你怎么回答,有没有从架构的思想去思考这个问题,就算有一些具体技术你记得可能不是很熟练了,面试官也会相信你是能够解决问题的。
这一次就整体来说一下如何让你的系统抗住高并发流量。
第一步“拆”
在面对高并发的时候,第一步永远是拆核心,思想就是分而治之。
那具体怎么样拆呢?
服务的拆分与治理
服务拆分
我们可以把庞大的单体架构,根据业务拆分成多个不同的服务,这样哪个服务遇到瓶颈了,可以单独拎出来进行扩容和优化,也不会因为某一个阶段出问题导致整个系统都瘫了。
例如:一个电商系统按照业务领域拆分成用户、订单、支付、库存这些独立的服务。
这样拆分主要是使用分布式架构来降低单点故障的风险,提高系统的可伸缩性和性能。
服务集群部署
虽然说,将单体系统拆分成多个系统,来分摊了单体架构下容易出现的故障风险,但实际上这样的操作只是将单点故障风险分摊到了各个子系统上,这样还是存在单点故障风险的。因此需要进行集群部署:将一个服务通过集群进行部署,来提升系统整体的吞吐量及响应速度,并使用负载均衡技术将请求均衡分配给多个服务器,以提高系统的性能和可用性。
这样集群部署后,让每个服务器都承担一部分的并发和流量,提升整体系统的并发能力。
服务治理
拆服务和集群部署后,原先的单体系统变成了多服务多节点的分布式架构了,那么如果服务A想调用服务B,怎么找到服务B呢?当有几十个服务,上百个节点,并且每个节点的IP变来变去的,该怎么治理这些服务呢?这就需要一个通讯录,用来专门记录,每个服务的地址信息,也就是注册中心。
下面是一些常见的注册中心的对比
注册中心
CAP 模型
健康检查方式
多数据中心
Spring Cloud 集成
典型特点
Eureka
AP(可用性优先)
客户端心跳(30s)
不支持
原生支持
轻量、与 Spring Cloud 无缝集成,适合入门和中小型项目
Consul
CP(一致性优先)
TCP/HTTP/gRPC 主动探测
原生支持
支持
功能最全,支持 KV 存储、ACL、DNS 服务等,适合多语言、多数据中心场景
Zookeeper
CP
临时节点存活监听
需额外配置
支持
成熟稳定,强一致性,适合与 Dubbo 等框架配合使用
Nacos
AP/CP 可切换
TCP/HTTP/MySQL/自定义
支持
原生支持
阿里开源,集成注册中心+配置中心 + 动态 DNS,适合云原生和 Spring Cloud 项目
那么它们是怎么工作的呢?
这里可以以Nacos为例:服务启动时,后端服务自动把自己的 ip、端口注册到 Nacos。调用方通过 Nacos 获取健康实例列表,再配合 Ribbon 或者 Loadbalancer 做负载均衡。提到 Nacos 时,可以说一下的动态配置管理。高并发下,需要动态调整线程参数或者日志级别,不用重启服务。Nacos 配置一改,全量下发。
Nacos 的“动态配置”指的是:在应用运行期,无需重启服务,即可实时推送并生效配置变更的能力。它把“配置”从代码/包内解耦出来,集中存储在 Nacos Server,并通过 长轮询(Long-Polling)+ 版本号对比 机制,让客户端在毫秒级感知到变化,进而触发本地回调或 Bean 重新绑定,实现“热更新”。
数据的拆分(读写分离、分片)
读写分离
服务进行了拆分,如果数据库还是用一个,那么瓶颈肯定很容易出现在数据库,所以我们可以根据业务场景(读多写少/读少写多)将数据库进行读写分离,这样当读流量大了的时候,也不会影响写的效率。
读场景(商品详情、评论)走只读副本,写场景(下单、支付)走主库。 但是要做好监控,当主从延迟过高时,要及时处理。
垂直拆分
服务进行了拆分,如果数据库还是用一个,那么瓶颈肯定很容易出现在数据库,所以垂直分库是必须的,要做到专库专用,这样可以解决服务太多,数据库连接数太多的问题,减少数据库的压力。
水平拆分
但是如果有的表一年产生上亿条数据,并且保持持续增加。数据量真的太大了,就不要再总纠结什么索引优化、事务优化这种小打小闹的了,这个时候就得上水平分表了,落地工具现在首选是 shardingsphere,再加上一些自己的实现细节。比如我们利用 shardingjdbc 配置好分片键,再通过一致性哈希算法把一张大表拆成一千零二十四张小表,均匀分布在不同的物理磁盘上,这样就把集中的I/O 压力分散了。
