DukeDuke
主页
文档转换
关于我们
主页
文档转换
关于我们
  • 微服务简介
  • CAP理论
  • eureka 注册中心
  • nacos 注册中心
  • gateway 网关
  • feign 服务调用
  • sentinel 限流与熔断
  • seata 分布式事务
  • redis 分布式锁
  • 高并发系统设计

高并发系统设计详解

目录

  • 1. 系统概述
  • 2. 整体架构设计
  • 3. 分层架构详解
    • 3.1 接入层
    • 3.2 网关层
    • 3.3 应用服务层
    • 3.4 缓存层
    • 3.5 数据存储层
    • 3.6 消息中间件层
  • 4. 核心组件作用说明
  • 5. 性能优化策略
  • 6. 监控与告警体系
  • 7. 可扩展性设计
  • 8. 安全防护措施
  • 9. 实际应用案例

1. 系统概述

1.1 什么是高并发系统

高并发系统是指能够同时处理大量用户请求,并在高负载情况下保持稳定性能的分布式系统。这类系统通常需要支持每秒数万甚至数十万的并发请求。

1.2 高并发系统的核心特征

  • 高可用性: 系统能够 7×24 小时稳定运行,故障恢复时间短
  • 高性能: 响应时间短,吞吐量大,资源利用率高
  • 可扩展性: 能够根据业务增长水平扩展和收缩
  • 可维护性: 代码结构清晰,易于维护和升级
  • 数据一致性: 在分布式环境下保证数据的准确性和一致性

1.3 高并发系统面临的挑战

  1. 流量冲击: 突发的高并发请求可能导致系统崩溃
  2. 资源竞争: 多个请求同时访问共享资源造成性能瓶颈
  3. 数据一致性: 分布式环境下数据同步和一致性保证
  4. 系统复杂性: 多服务、多组件之间的协调和管理
  5. 故障传播: 单个组件故障可能影响整个系统

2. 整体架构设计

2.1 高并发系统分层架构图

2.2 架构设计原则

  1. 分层解耦: 各层职责明确,通过接口交互,降低耦合度
  2. 水平扩展: 支持通过增加服务器节点来提升系统性能
  3. 故障隔离: 单个组件故障不影响整个系统运行
  4. 数据分离: 读写分离,冷热数据分离
  5. 异步处理: 非关键业务采用异步处理,提升响应速度

3. 核心组件详解

3.1 负载均衡层

3.1.1 组件作用

负载均衡层是整个高并发系统的入口,主要作用包括:

  • 流量分发: 将用户请求均匀分发到后端服务器
  • 健康检查: 监控后端服务器状态,自动剔除故障节点
  • SSL 终止: 处理 HTTPS 加密解密,减轻后端服务器压力
  • 静态资源缓存: 缓存静态文件,减少后端请求

3.1.2 技术选型

Nginx 是最常用的负载均衡器,具有以下优势:

  • 高性能:基于事件驱动的异步非阻塞架构
  • 低内存消耗:相比 Apache 等传统服务器
  • 丰富的功能:支持反向代理、负载均衡、缓存等
  • 高可靠性:经过大规模生产环境验证

3.1.3 配置示例

upstream backend {
    # 负载均衡算法
    least_conn;

    # 后端服务器
    server 192.168.1.10:8080 weight=3 max_fails=3 fail_timeout=30s;
    server 192.168.1.11:8080 weight=2 max_fails=3 fail_timeout=30s;
    server 192.168.1.12:8080 weight=1 max_fails=3 fail_timeout=30s;

    # 健康检查
    keepalive 32;
}

server {
    listen 80;
    server_name example.com;

    # 静态资源缓存
    location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
        expires 1y;
        add_header Cache-Control "public, immutable";
    }

    # API请求代理
    location /api/ {
        proxy_pass http://backend;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

        # 超时设置
        proxy_connect_timeout 5s;
        proxy_send_timeout 10s;
        proxy_read_timeout 10s;
    }
}

3.2 网关层

3.2.1 组件作用

API 网关作为微服务架构的统一入口,提供以下核心功能:

  • 路由转发: 根据请求路径将流量路由到对应的微服务
  • 认证授权: 统一处理用户身份验证和权限控制
  • 限流熔断: 保护后端服务不被过载请求压垮
  • 协议转换: 支持 HTTP、gRPC 等多种协议
  • 请求聚合: 将多个微服务调用聚合成单个请求

3.2.2 Spring Cloud Gateway 实现

@Configuration
public class GatewayConfig {

    @Bean
    public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
        return builder.routes()
            .route("user-service", r -> r.path("/api/user/**")
                .filters(f -> f
                    .addRequestHeader("X-Request-ID", UUID.randomUUID().toString())
                    .circuitBreaker(config -> config
                        .setName("user-service-cb")
                        .setFallbackUri("forward:/fallback/user")))
                .uri("lb://user-service"))
            .route("order-service", r -> r.path("/api/order/**")
                .filters(f -> f
                    .requestRateLimiter(config -> config
                        .setRateLimiter(redisRateLimiter())
                        .setKeyResolver(ipKeyResolver())))
                .uri("lb://order-service"))
            .build();
    }

    @Bean
    public RedisRateLimiter redisRateLimiter() {
        return new RedisRateLimiter(10, 20, 1);
    }

    @Bean
    public KeyResolver ipKeyResolver() {
        return exchange -> Mono.just(
            exchange.getRequest().getRemoteAddress().getAddress().getHostAddress());
    }
}

3.3 应用服务层

3.3.1 微服务架构

微服务架构将单体应用拆分为多个独立的服务,每个服务负责特定的业务功能:

  • 用户服务: 用户注册、登录、个人信息管理
  • 商品服务: 商品信息管理、库存管理
  • 订单服务: 订单创建、状态管理、订单查询
  • 支付服务: 支付处理、退款、账单管理

3.3.2 服务间通信

同步通信 - 使用 OpenFeign:

@FeignClient(name = "user-service", fallback = UserServiceFallback.class)
public interface UserServiceClient {

    @GetMapping("/api/user/{userId}")
    UserDTO getUserById(@PathVariable("userId") Long userId);

    @PostMapping("/api/user")
    UserDTO createUser(@RequestBody CreateUserRequest request);
}

@Component
public class UserServiceFallback implements UserServiceClient {

    @Override
    public UserDTO getUserById(Long userId) {
        return UserDTO.builder()
            .id(userId)
            .name("默认用户")
            .build();
    }

    @Override
    public UserDTO createUser(CreateUserRequest request) {
        throw new ServiceUnavailableException("用户服务暂时不可用");
    }
}

异步通信 - 使用消息队列:

@Component
public class OrderEventPublisher {

    @Autowired
    private RabbitTemplate rabbitTemplate;

    public void publishOrderCreated(OrderCreatedEvent event) {
        rabbitTemplate.convertAndSend(
            "order.exchange",
            "order.created",
            event
        );
    }
}

@RabbitListener(queues = "order.created.queue")
@Component
public class OrderCreatedListener {

    @Autowired
    private InventoryService inventoryService;

    public void handleOrderCreated(OrderCreatedEvent event) {
        // 扣减库存
        inventoryService.decreaseStock(event.getProductId(), event.getQuantity());
    }
}

3.4 缓存层

3.4.1 多级缓存架构

3.4.2 缓存策略

1. 本地缓存实现

@Configuration
public class CacheConfig {

    @Bean
    public CacheManager cacheManager() {
        CaffeineCacheManager cacheManager = new CaffeineCacheManager();
        cacheManager.setCaffeine(Caffeine.newBuilder()
            .maximumSize(10000)
            .expireAfterWrite(10, TimeUnit.MINUTES)
            .recordStats());
        return cacheManager;
    }
}

@Service
public class UserService {

    @Cacheable(value = "users", key = "#userId")
    public UserDTO getUserById(Long userId) {
        // 从数据库查询用户信息
        return userRepository.findById(userId);
    }

    @CacheEvict(value = "users", key = "#user.id")
    public void updateUser(UserDTO user) {
        userRepository.save(user);
    }
}

2. Redis 分布式缓存

@Service
public class ProductService {

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    private static final String PRODUCT_CACHE_KEY = "product:";
    private static final Duration CACHE_EXPIRE = Duration.ofHours(1);

    public ProductDTO getProductById(Long productId) {
        String cacheKey = PRODUCT_CACHE_KEY + productId;

        // 先从缓存获取
        ProductDTO product = (ProductDTO) redisTemplate.opsForValue().get(cacheKey);
        if (product != null) {
            return product;
        }

        // 缓存未命中,从数据库查询
        product = productRepository.findById(productId);
        if (product != null) {
            // 写入缓存
            redisTemplate.opsForValue().set(cacheKey, product, CACHE_EXPIRE);
        }

        return product;
    }

    @CacheEvict(value = "products", key = "#product.id")
    public void updateProduct(ProductDTO product) {
        productRepository.save(product);

        // 删除Redis缓存
        String cacheKey = PRODUCT_CACHE_KEY + product.getId();
        redisTemplate.delete(cacheKey);
    }
}

3.5 数据存储层

3.5.1 数据库架构设计

3.5.2 分库分表实现

1. 分片策略配置

spring:
  shardingsphere:
    datasource:
      names: ds0,ds1,ds2,ds3
      ds0:
        type: com.zaxxer.hikari.HikariDataSource
        driver-class-name: com.mysql.cj.jdbc.Driver
        jdbc-url: jdbc:mysql://db0:3306/user_db
        username: root
        password: password
      ds1:
        type: com.zaxxer.hikari.HikariDataSource
        driver-class-name: com.mysql.cj.jdbc.Driver
        jdbc-url: jdbc:mysql://db1:3306/user_db
        username: root
        password: password
    sharding:
      tables:
        user:
          actual-data-nodes: ds$->{0..3}.user_$->{0..3}
          database-strategy:
            inline:
              sharding-column: user_id
              algorithm-expression: ds$->{user_id % 4}
          table-strategy:
            inline:
              sharding-column: user_id
              algorithm-expression: user_$->{user_id % 4}

2. 自定义分片算法

public class UserShardingAlgorithm implements PreciseShardingAlgorithm<Long> {

    @Override
    public String doSharding(Collection<String> availableTargetNames,
                           PreciseShardingValue<Long> shardingValue) {
        Long userId = shardingValue.getValue();
        String suffix = String.valueOf(userId % 4);

        for (String tableName : availableTargetNames) {
            if (tableName.endsWith(suffix)) {
                return tableName;
            }
        }
        throw new UnsupportedOperationException();
    }
}

3.6 消息队列层

3.6.1 消息队列架构

3.6.2 Kafka 配置与使用

1. 生产者配置

@Configuration
public class KafkaProducerConfig {

    @Bean
    public ProducerFactory<String, Object> producerFactory() {
        Map<String, Object> configProps = new HashMap<>();
        configProps.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9092");
        configProps.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class);
        configProps.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, JsonSerializer.class);
        configProps.put(ProducerConfig.ACKS_CONFIG, "all");
        configProps.put(ProducerConfig.RETRIES_CONFIG, 3);
        configProps.put(ProducerConfig.BATCH_SIZE_CONFIG, 16384);
        configProps.put(ProducerConfig.LINGER_MS_CONFIG, 1);
        configProps.put(ProducerConfig.BUFFER_MEMORY_CONFIG, 33554432);

        return new DefaultKafkaProducerFactory<>(configProps);
    }

    @Bean
    public KafkaTemplate<String, Object> kafkaTemplate() {
        return new KafkaTemplate<>(producerFactory());
    }
}

2. 消息发送

@Service
public class OrderEventService {

    @Autowired
    private KafkaTemplate<String, Object> kafkaTemplate;

    public void publishOrderCreated(OrderCreatedEvent event) {
        kafkaTemplate.send("order-created", event.getOrderId().toString(), event);
    }

    public void publishOrderPaid(OrderPaidEvent event) {
        kafkaTemplate.send("order-paid", event.getOrderId().toString(), event);
    }
}

3. 消息消费

@Component
public class OrderEventListener {

    @KafkaListener(topics = "order-created", groupId = "inventory-group")
    public void handleOrderCreated(OrderCreatedEvent event) {
        log.info("处理订单创建事件: {}", event);
        // 扣减库存逻辑
        inventoryService.decreaseStock(event.getProductId(), event.getQuantity());
    }

    @KafkaListener(topics = "order-paid", groupId = "notification-group")
    public void handleOrderPaid(OrderPaidEvent event) {
        log.info("处理订单支付事件: {}", event);
        // 发送支付成功通知
        notificationService.sendPaymentSuccessNotification(event.getUserId());
    }
}

4. 性能优化策略

4.1 数据库优化

4.1.1 索引优化

-- 复合索引优化
CREATE INDEX idx_user_status_created ON users(status, created_at);

-- 覆盖索引
CREATE INDEX idx_order_user_status ON orders(user_id, status) INCLUDE (order_id, amount, created_at);

-- 部分索引
CREATE INDEX idx_active_users ON users(email) WHERE status = 'ACTIVE';

4.1.2 查询优化

@Repository
public class UserRepository {

    // 使用分页查询避免大结果集
    @Query("SELECT u FROM User u WHERE u.status = :status ORDER BY u.createdAt DESC")
    Page<User> findActiveUsers(@Param("status") String status, Pageable pageable);

    // 使用投影查询只返回需要的字段
    @Query("SELECT new UserSummaryDTO(u.id, u.name, u.email) FROM User u WHERE u.id IN :ids")
    List<UserSummaryDTO> findUserSummaries(@Param("ids") List<Long> ids);

    // 批量操作
    @Modifying
    @Query("UPDATE User u SET u.lastLoginAt = :loginTime WHERE u.id IN :userIds")
    int updateLastLoginTime(@Param("userIds") List<Long> userIds, @Param("loginTime") LocalDateTime loginTime);
}

4.2 缓存优化

4.2.1 缓存预热

@Component
public class CacheWarmupService {

    @Autowired
    private ProductService productService;

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    @EventListener(ApplicationReadyEvent.class)
    public void warmupCache() {
        // 预热热门商品缓存
        List<Long> hotProductIds = productService.getHotProductIds();
        hotProductIds.parallelStream().forEach(productId -> {
            productService.getProductById(productId);
        });

        // 预热用户会话缓存
        List<Long> activeUserIds = userService.getActiveUserIds();
        activeUserIds.parallelStream().forEach(userId -> {
            userService.getUserById(userId);
        });
    }
}

4.2.2 缓存更新策略

@Service
public class ProductService {

    @CacheEvict(value = "products", key = "#product.id")
    @CachePut(value = "products", key = "#product.id")
    public Pro
最近更新:: 2026/4/17 13:21
Contributors: Duke
Prev
redis 分布式锁