高并发系统如何设计?

高并发系统设计是后端开发的核心技能之一。下面将从架构、技术、实践等多个维度,系统地讲解高并发系统的设计方法。

一、高并发的核心挑战

1. 什么是高并发?

高并发是指在同一时刻有大量用户同时访问系统,系统需要处理大量的请求。常见的高并发场景:

  • 电商秒杀:双11、618等大促活动
  • 社交应用:微博热搜、朋友圈点赞
  • 直播平台:百万用户同时在线观看
  • 金融交易:股票交易系统

2. 高并发带来的问题

问题类型具体表现影响
性能问题响应时间变长、吞吐量下降用户体验差
资源问题CPU、内存、网络资源耗尽系统崩溃
数据问题数据不一致、脏读、幻读业务错误
稳定性问题服务雪崩、级联故障系统不可用

二、高并发系统设计原则

1. 分层设计原则

┌─────────────────────────────────────┐
│           接入层(CDN + 负载均衡)      │
├─────────────────────────────────────┤
│           网关层(限流 + 认证)         │
├─────────────────────────────────────┤
│           应用层(业务逻辑)            │
├─────────────────────────────────────┤
│           服务层(微服务)              │
├─────────────────────────────────────┤
│           数据层(缓存 + 数据库)        │
├─────────────────────────────────────┤
│           存储层(文件 + 对象存储)       │
└─────────────────────────────────────┘

2. 核心设计原则

(1)无状态设计

  • 应用服务器不保存会话状态
  • 会话信息存储在 Redis 等外部存储
  • 便于水平扩展

(2)水平扩展

  • 通过增加服务器数量提升处理能力
  • 使用负载均衡分发请求
  • 避免单点故障

(3)读写分离

  • 读多写少的场景,分离读写操作
  • 主库负责写,从库负责读
  • 提升数据库吞吐量

(4)缓存优先

  • 热点数据放入缓存
  • 减少数据库访问
  • 提升响应速度

(5)异步处理

  • 非核心流程异步化
  • 使用消息队列削峰填谷
  • 提升系统吞吐量

三、高并发核心技术

1. 负载均衡

负载均衡算法

算法原理适用场景
轮询(Round Robin)按顺序轮流分配服务器性能相近
加权轮询根据权重分配服务器性能不同
最少连接分配给当前连接最少的服务器长连接场景
IP Hash根据客户端IP计算Hash需要会话保持
一致性Hash带虚拟节点的Hash算法缓存场景

实现方案

// Nginx 配置示例
upstream backend {
    server 192.168.1.1:8080 weight=5;
    server 192.168.1.2:8080 weight=5;
    server 192.168.1.3:8080 backup;
    
    # 一致性Hash
    hash $request_uri consistent;
}

server {
    listen 80;
    location / {
        proxy_pass http://backend;
    }
}

2. 缓存策略

多级缓存架构

┌─────────────┐
│  浏览器缓存  │  ← 缓存静态资源
├─────────────┤
│  CDN缓存    │  ← 缓存热点资源
├─────────────┤
│  应用缓存   │  ← 本地缓存(Caffeine)
├─────────────┤
│  分布式缓存 │  ← Redis集群
├─────────────┤
│  数据库     │  ← 持久化存储
└─────────────┘

缓存更新策略

策略优点缺点
Cache Aside简单、灵活可能不一致
Read/Write Through一致性高实现复杂
Write Behind性能高可能丢数据

缓存问题及解决方案

缓存穿透

  • 问题:查询不存在的数据,每次都打到数据库
  • 解决:布隆过滤器、缓存空值

缓存击穿

  • 问题:热点key过期,大量请求打到数据库
  • 解决:互斥锁、逻辑过期

缓存雪崩

  • 问题:大量key同时过期,数据库压力剧增
  • 解决:随机过期时间、多级缓存

3. 数据库优化

读写分离

@Configuration
public class DataSourceConfig {
    
    @Bean
    public DataSource routingDataSource() {
        DynamicRoutingDataSource routingDataSource = new DynamicRoutingDataSource();
        
        Map<Object, Object> targetDataSources = new HashMap<>();
        targetDataSources.put("master", masterDataSource());
        targetDataSources.put("slave", slaveDataSource());
        
        routingDataSource.setTargetDataSources(targetDataSources);
        routingDataSource.setDefaultTargetDataSource(masterDataSource());
        
        return routingDataSource;
    }
}

分库分表

垂直拆分:按业务拆分

用户库:user_db
订单库:order_db
商品库:product_db

水平拆分:按数据量拆分

order_db_0: order_0, order_1, order_2
order_db_1: order_3, order_4, order_5

索引优化

-- 创建复合索引
CREATE INDEX idx_order_user_time ON orders(user_id, create_time);

-- 覆盖索引
CREATE INDEX idx_order_cover ON orders(user_id, status, total_amount);

4. 消息队列

消息队列的作用

  • 异步处理:提升响应速度
  • 流量削峰:平滑处理突发流量
  • 应用解耦:降低系统耦合度
  • 数据分发:一对多消息分发

消息队列选型

特性KafkaRabbitMQRocketMQ
吞吐量百万级万级十万级
延迟毫秒级微秒级毫秒级
可靠性非常高
适用场景日志、大数据企业应用金融交易

消息可靠性保证

@Service
public class OrderService {
    
    @Autowired
    private RocketMQTemplate rocketMQTemplate;
    
    public void createOrder(Order order) {
        // 1. 保存订单到数据库
        orderMapper.insert(order);
        
        // 2. 发送消息(异步)
        SendResult sendResult = rocketMQTemplate.syncSend(
            "order-topic", 
            MessageBuilder.withPayload(order).build()
        );
        
        // 3. 确认消息发送成功
        if (!sendResult.getSendStatus().equals(SendStatus.SEND_OK)) {
            // 处理发送失败
        }
    }
}

5. 限流降级

限流算法

算法原理优点缺点
计数器固定时间窗口计数简单突发流量问题
滑动窗口滑动时间窗口计数平滑实现复杂
漏桶请求放入桶中,匀速处理平滑不能应对突发
令牌桶匀速产生令牌,请求消耗令牌灵活实现复杂

限流实现

@Component
public class RateLimiterFilter extends OncePerRequestFilter {
    
    private final RateLimiter rateLimiter = RateLimiter.create(1000); // 每秒1000个请求
    
    @Override
    protected void doFilterInternal(HttpServletRequest request, 
                                    HttpServletResponse response, 
                                    FilterChain filterChain) throws ServletException, IOException {
        if (rateLimiter.tryAcquire()) {
            filterChain.doFilter(request, response);
        } else {
            response.setStatus(HttpStatus.TOO_MANY_REQUESTS.value());
            response.getWriter().write("请求过于频繁,请稍后再试");
        }
    }
}

降级策略

@Component
public class OrderServiceFallback implements OrderService {
    
    @Override
    @SentinelResource(value = "createOrder", fallback = "createOrderFallback")
    public Order createOrder(OrderRequest request) {
        // 正常业务逻辑
    }
    
    public Order createOrderFallback(OrderRequest request, Throwable ex) {
        // 降级逻辑:返回默认值或缓存数据
        log.warn("创建订单降级,原因:{}", ex.getMessage());
        return Order.builder()
                .status(OrderStatus.PENDING)
                .message("系统繁忙,请稍后查询订单状态")
                .build();
    }
}

四、高并发架构模式

1. 微服务架构

┌─────────────────────────────────────────┐
│              API Gateway                 │
│         (限流、认证、路由)              │
└─────────────────────────────────────────┘
                    │
    ┌───────────────┼───────────────┐
    ▼               ▼               ▼
┌─────────┐   ┌─────────┐   ┌─────────┐
│ 用户服务 │   │ 订单服务 │   │ 商品服务 │
└─────────┘   └─────────┘   └─────────┘
    │               │               │
    └───────────────┼───────────────┘
                    ▼
            ┌─────────────┐
            │  服务注册中心  │
            │  (Nacos)   │
            └─────────────┘

2. CQRS 模式(命令查询职责分离)

┌─────────────┐         ┌─────────────┐
│   写操作     │ ──────> │  写数据库    │
│  Command    │         │  (主库)    │
└─────────────┘         └─────────────┘
                              │
                              ▼
                        ┌─────────────┐
                        │  事件总线    │
                        │  (MQ)     │
                        └─────────────┘
                              │
                              ▼
┌─────────────┐         ┌─────────────┐
│   读操作     │ <────── │  读数据库    │
│   Query     │         │  (从库)    │
└─────────────┘         └─────────────┘

3. 事件驱动架构

┌─────────┐    创建订单    ┌─────────┐
│  用户   │ ────────────> │ 订单服务 │
└─────────┘               └────┬────┘
                               │
                    ┌──────────┼──────────┐
                    ▼          ▼          ▼
              ┌─────────┐ ┌─────────┐ ┌─────────┐
              │库存服务  │ │支付服务  │ │物流服务  │
              └─────────┘ └─────────┘ └─────────┘

五、高并发实践案例

案例1:电商秒杀系统

核心挑战

  • 瞬时流量巨大(百万级并发)
  • 库存超卖问题
  • 系统稳定性要求高

解决方案

┌─────────────┐
│   CDN加速   │  ← 静态资源缓存
├─────────────┤
│  秒杀网关   │  ← 限流、鉴权
├─────────────┤
│  库存预扣   │  ← Redis原子操作
├─────────────┤
│  异步下单   │  ← MQ削峰
├─────────────┤
│  订单处理   │  ← 数据库最终一致
└─────────────┘

关键代码

@Service
public class SeckillService {
    
    @Autowired
    private StringRedisTemplate redisTemplate;
    
    @Autowired
    private RedissonClient redissonClient;
    
    @Autowired
    private RocketMQTemplate rocketMQTemplate;
    
    /**
     * 秒杀下单
     */
    public SeckillResult seckill(Long userId, Long productId) {
        // 1. 用户限流检查
        if (!checkUserLimit(userId)) {
            return SeckillResult.fail("操作过于频繁");
        }
        
        // 2. 获取分布式锁
        RLock lock = redissonClient.getLock("seckill:product:" + productId);
        try {
            if (!lock.tryLock(3, 10, TimeUnit.SECONDS)) {
                return SeckillResult.fail("系统繁忙,请重试");
            }
            
            // 3. Redis预扣库存(Lua脚本保证原子性)
            Long stock = redisTemplate.execute(
                new DefaultRedisScript<>(SECKILL_SCRIPT, Long.class),
                Collections.singletonList("stock:" + productId),
                userId.toString()
            );
            
            if (stock == null || stock < 0) {
                return SeckillResult.fail("库存不足");
            }
            
            // 4. 发送异步下单消息
            SeckillOrderMessage message = SeckillOrderMessage.builder()
                    .userId(userId)
                    .productId(productId)
                    .build();
            rocketMQTemplate.asyncSend("seckill-order-topic", message, new SendCallback() {
                @Override
                public void onSuccess(SendResult sendResult) {
                    log.info("秒杀订单消息发送成功");
                }
                @Override
                public void onException(Throwable e) {
                    // 消息发送失败,回滚库存
                    redisTemplate.opsForValue().increment("stock:" + productId);
                }
            });
            
            return SeckillResult.success("抢购成功,正在处理订单");
            
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            return SeckillResult.fail("系统异常");
        } finally {
            lock.unlock();
        }
    }
    
    // Lua脚本:原子性扣减库存
    private static final String SECKILL_SCRIPT = 
        "if (redis.call('exists', KEYS[1]) == 1) then " +
        "    local stock = tonumber(redis.call('get', KEYS[1])); " +
        "    if (stock > 0) then " +
        "        redis.call('decr', KEYS[1]); " +
        "        return stock - 1; " +
        "    end; " +
        "    return -1; " +
        "end; " +
        "return -1;";
}

案例2:社交应用Feed流

核心挑战

  • 海量数据(亿级)
  • 实时性要求高
  • 个性化推荐

解决方案

推拉结合模式

┌─────────────────────────────────────────┐
│              写扩散(Push)              │
│  大V发布内容 → 推送给所有粉丝            │
├─────────────────────────────────────────┤
│              读扩散(Pull)              │
│  普通用户发布 → 粉丝拉取时间线           │
└─────────────────────────────────────────┘

多级缓存

┌─────────────┐
│  L1: 本地缓存 │  ← 用户最近Feed
├─────────────┤
│  L2: Redis  │  ← 热点Feed
├─────────────┤
│  L3: HBase  │  ← 全量Feed
└─────────────┘

六、高并发监控与运维

1. 监控指标

指标类型具体指标告警阈值
系统指标CPU、内存、磁盘、网络CPU > 80%
应用指标QPS、RT、错误率错误率 > 1%
业务指标订单量、支付成功率成功率 < 95%
中间件指标Redis、MQ、DB性能连接数 > 80%

2. 压测方案

# JMeter压测命令
jmeter -n -t seckill_test.jmx -l result.jtl -e -o report

# 关键指标
- 吞吐量(Throughput)
- 响应时间(Response Time)
- 错误率(Error Rate)
- 并发用户数(Concurrent Users)

七、总结

高并发系统设计需要从多个维度进行考虑:

1. 架构层面

  • 分层设计,职责清晰
  • 无状态设计,便于扩展
  • 微服务架构,独立部署

2. 技术层面

  • 负载均衡,流量分发
  • 多级缓存,减少数据库压力
  • 读写分离,提升数据库性能
  • 消息队列,异步削峰
  • 限流降级,保证系统稳定

3. 数据层面

  • 分库分表,水平扩展
  • 索引优化,提升查询性能
  • 最终一致性,保证数据正确

4. 运维层面

  • 全链路监控,及时发现问题
  • 自动化运维,提升效率
  • 容量规划,提前扩容

高并发系统设计是一个持续优化的过程,需要根据业务特点和实际场景,选择合适的技术方案,并在实践中不断调整和优化。

互动话题

  1. 你在实际项目中遇到过哪些高并发挑战?是如何解决的?
  2. 对于秒杀系统,你还有什么其他的优化方案?
  3. 在微服务架构中,你是如何处理分布式事务的?

欢迎在评论区交流讨论!


欢迎关注公众号:服务端技术精选,获取更多技术分享和经验。


标题:高并发系统如何设计?
作者:jiangyi
地址:http://www.jiangyi.space/articles/2026/03/18/1773586027363.html
公众号:服务端技术精选
    评论
    0 评论
avatar

取消