Alexu
发布于 2025-09-03 / 0 阅读
0
0

如何设计高并发和高可用的系统

好的,处理高并发和高可用的问题是后端架构设计的核心挑战,也是衡量架构师能力的关键指标。两者相辅相成,但又各有侧重。

下面我将它们拆开,再结合起来讲解如何系统性地处理。

---

### 高并发 (High Concurrency)

高并发的核心在于:**系统如何高效地处理大量同时到来的请求**。目标是提高**吞吐量(Throughput)** 和降低**延迟(Latency)**。

#### 核心思路:分而治之,层层缓冲

1. 流量层:卸载与分发

* 负载均衡 (Load Balancing):这是高并发架构的**入口和基石**。所有流量都应先经过负载均衡器再到达后端服务。

* 硬件:F5, A10(性能强,成本高)。

* 软件:Nginx (HTTP/HTTPS层,第7层)、LVS (网络层,第4层)、HAProxy。

* 策略:轮询、加权轮询、最少连接数、IP哈希等。

* DNS轮询:在更上层通过DNS将域名解析到多个IP地址,实现初步的流量分发,通常用于异地多机房。

2. 应用层:异步化与水平扩展

* 无状态服务 (Stateless Service):这是**水平扩展的前提**。服务实例本身不保存用户会话(Session)等状态信息。所有状态都存储到外部的集中式存储(如Redis、数据库)中。这样,任何请求都可以被任何实例处理,扩缩容变得非常简单。

* 池化技术 (Pooling):使用数据库连接池、HTTP连接池等,避免频繁创建和销毁连接的开销,复用连接,极大提升性能。

* 异步处理 (Asynchronous Processing)

* 线程模型:使用多线程、事件驱动(如NIO)模型处理请求,避免阻塞。例如,Netty框架。

* 业务解耦:对于耗时操作(如发送邮件、生成报表、处理视频),不要阻塞主请求流程。采用**消息队列(MQ)**,将请求异步化。用户请求立刻返回,后台工作进程从MQ中消费消息并慢慢处理。这实现了**削峰填谷**,将流量高峰稀释成一段时间内的平稳流量。

* 示例:Kafka, RabbitMQ, RocketMQ。

3. 数据层:缓存与分库分表

* 缓存 (Caching):这是应对高并发读操作的**银弹**。

* 缓存策略

* Cache-Aside (旁路缓存):最常用。应用先读缓存,命中则返回;未命中则读数据库,写入缓存后再返回。

* Read/Write Through:缓存代理所有读写操作。

* 缓存位置

* 客户端缓存:浏览器、APP。

* CDN缓存:静态资源(图片、视频、HTML/CSS/JS)。

* 反向代理缓存:Nginx缓存页面片段。

* 分布式缓存:**Redis**、Memcached,集群化部署以承载大量请求。

* 缓存问题:必须处理**缓存穿透**、**缓存击穿**、**缓存雪崩**。

* 数据库优化

* 读写分离:主库负责写,多个从库负责读,通过binlog同步。显著提升读能力。

* 分库分表 (Sharding):当单表数据量巨大时,将数据分散到多个数据库或表中。分为**水平分片**(按行,如按用户ID哈希)和**垂直分片**(按列,将不常用字段拆分出去)。常用中间件:ShardingSphere, MyCat。

* 数据库选型:在合适场景使用NoSQL。例如,海量日志、埋点数据用时序数据库(InfluxDB);社交关系用图数据库(Neo4j)。

---

### 高可用 (High Availability)

高可用的核心在于:**系统如何保证持续可用的服务时间,避免单点故障(SPOF)**。目标是提高**SLA(Service Level Agreement)**,如达到99.99%(年停机时间约52分钟)或99.999%(年停机时间约5分钟)。

#### 核心思路:冗余 + 自动故障转移

1. 冗余 (Redundancy) - 消除单点故障

* 多实例部署:任何核心服务、数据库、缓存、中间件都不能是单点的,必须至少以集群方式部署。

* 多机房部署 (Multi-Zone/Region):在同城或异地建立多个数据中心,防止因机房断电、网络光缆被挖断等导致服务完全不可用。

2. 故障转移 (Failover) - 快速发现与切换

* 健康检查 (Health Check):负载均衡器或服务注册中心(如Nacos, Consul, Eureka)会定期向服务实例发送心跳包,检查其是否存活。

* 自动切换:当健康检查失败,判断某个实例不可用时,自动将其从服务列表中剔除,并将流量路由到其他健康的实例。这个过程对用户应无感知。

3. 数据可靠性 - 冗余的基石

* 数据备份:定期对数据库进行全量和增量备份,并最好在异地保存一份。

* 数据复制

* 主从复制 (Master-Slave Replication):如MySQL主从,数据从主库异步/半同步复制到从库。从库可读,主库宕机后可提升一个从库为主库。

* 多主复制 (Multi-Master Replication):如Galera Cluster for MySQL。

* 分布式共识算法:使用Raft、Paxos等算法的分布式数据库/配置中心,能自动处理主节点选举和数据一致性,如Etcd, Consul。

4. 容错与自愈 (Resilience & Self-Healing)

* 服务熔断 (Circuit Breaker):当调用某个服务频繁失败时,熔断器会打开,后续调用直接快速失败,不再发起真实调用。保护系统不被拖垮。例如Hystrix, Sentinel, Resilience4j。

* 服务降级 (Degradation):在系统压力过大时,暂时关闭一些非核心功能(如推荐、积分),释放资源保证核心流程(如下单、支付)可用。

* 限流 (Rate Limiting):控制单位时间内处理的请求数量,防止系统被突发流量冲垮。常用算法:计数器、漏桶、令牌桶。可在网关(如Spring Cloud Gateway)层面实现。

* 弹性伸缩 (Auto Scaling):在云平台上,根据CPU、内存、QPS等指标,自动增加或减少服务实例数量,以应对流量波动。

---

### 高并发 + 高可用:综合架构示例

一个典型的应对高并发和高可用的后端架构可能如下所示(微服务模式):

1. 用户请求首先到达 DNS,解析到**负载均衡器 SLB**(软件或硬件)。

2. SLB 将流量分发给**API网关集群**。网关负责限流、鉴权、路由。

3. API网关将请求路由到后端的**微服务集群**(如用户服务、订单服务、商品服务)。

4. 所有微服务都是无状态的,并注册到**服务注册与发现中心**(如Nacos)。服务间通过RPC或HTTP调用,客户端负载均衡器(如Ribbon)会从注册中心获取健康实例列表进行调用。

5. 服务间调用时,使用**熔断降级组件**(如Sentinel)防止雪崩。

6. 对于**读请求**,服务优先查询**Redis分布式缓存集群**。

7. 对于**写请求**,服务操作**MySQL数据库集群**(主从架构,读写分离)。如果数据量巨大,已进行分库分表。

8. 对于耗时操作,服务将消息发送到**Kafka/RocketMQ消息队列集群**,由后台Worker异步消费,实现削峰填谷。

9. 所有组件的**日志**被收集到**ELK**,**指标**被**Prometheus**采集并由**Grafana**展示,**调用链**由**SkyWalking/Jaeger**追踪,形成完整的可观测性体系。

总结一下关键心法:

* 高并发靠**缓存、异步、分片**。

* 高可用靠**冗余、自动故障转移、熔断降级**。

* 两者共同的基础是:**负载均衡**、**无状态服务**、**全面的监控告警**。

最终,所有的技术方案都是权衡(Trade-off)的结果,需要在**性能、一致性、可用性、成本**和**开发复杂度**之间做出最适合当前业务阶段的选择。


评论