JAVA:如何设计一个高并发的系统

admin
6
2025-08-08

⚡1、简述

随着互联网业务的发展,系统每天要处理的请求量急剧上升。一个高并发系统的设计,需要综合考虑性能、扩展性、可用性、稳定性等多个维度。

本文将带你系统性地理解高并发系统的设计原则,并通过 Java + Redis + MQ 的落地示例,帮助你掌握高并发系统的基本建模方法。

image-8lnp.png


📊 2、架构设计

2.1 高并发系统核心挑战

性能指标要求

🔹 吞吐量:QPS ≥ 10万级
🔹 延迟:P99 < 200ms
🔹 可用性:99.99% SLA
🔹 容错能力:自动故障转移 < 30s

瓶颈类型 表现症状 影响范围
计算瓶颈 CPU持续100% 响应延迟飙升
I/O瓶颈 磁盘/网络I/O等待 吞吐量下降
数据库瓶颈 慢查询、连接池耗尽 整体系统瘫痪
缓存失效 缓存击穿/雪崩 服务连锁故障
锁竞争 线程阻塞、低吞吐 业务处理停滞

2.2 设计原则

🔹 无状态设计:Session外部化存储
🔹 异步化:非核心流程消息队列解耦
🔹 冗余设计:多活部署+自动故障转移
🔹 弹性伸缩:自动扩缩容能力
🔹 柔性可用:降级、熔断机制

graph TD A[客户端] --> B[CDN] B --> C[负载均衡] C --> D[应用集群] D --> E[缓存集群] E --> F[数据库集群] F --> G[分库分表]

💻 3、关键技术实现方案

3.1 流量接入层优化

Nginx配置示例

# 百万连接优化
worker_processes auto;
worker_rlimit_nofile 100000;
events {
    worker_connections 4000;
    use epoll;
    multi_accept on;
}

# 负载均衡
upstream backend {
    zone backend 64k;
    least_conn;
    server 10.0.0.1:8080 max_fails=3;
    server 10.0.0.2:8080 backup;
}

# 缓存静态资源
location ~* \.(js|css|png)$ {
    expires 365d;
    add_header Cache-Control "public";
}

3.2 应用层优化实践

线程模型优化(Java示例)

// 自定义线程池
@Bean
public ThreadPoolTaskExecutor taskExecutor() {
    ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
    executor.setCorePoolSize(50);
    executor.setMaxPoolSize(200);
    executor.setQueueCapacity(1000);
    executor.setThreadNamePrefix("async-");
    executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
    return executor;
}

// 异步处理
@Async("taskExecutor")
public CompletableFuture<Result> processRequest(Request req) {
    // 业务处理逻辑
}

3.3 缓存体系设计

多级缓存实现

public Product getProduct(Long id) {
    // 1. 本地缓存
    Product product = caffeineCache.get(id, k -> {
        // 2. Redis集群
        return redisTemplate.opsForValue().get("product:"+id);
    });
  
    if (product == null) {
        // 3. 数据库查询
        product = dbQuery(id);
        // 异步回填
        CompletableFuture.runAsync(() -> {
            redisTemplate.opsForValue().set(
                "product:"+id, 
                product,
                30, TimeUnit.MINUTES);
        });
    }
    return product;
}

🧠 4、数据库高并发方案

4.1 分库分表示例

-- 用户表分片规则(16个库×16个表)
CREATE TABLE user_00.user_tab_00 (
    id BIGINT PRIMARY KEY,
    username VARCHAR(50),
    -- 其他字段
) ENGINE=InnoDB;

-- 使用ShardingSphere配置
spring:
  shardingsphere:
    datasource:
      names: ds0,ds1
    sharding:
      tables:
        user:
          actual-data-nodes: ds$->{0..15}.user_tab_$->{0..15}
          database-strategy:
            inline:
              sharding-column: id
              algorithm-expression: ds$->{id % 16}
          table-strategy: 
            inline:
              sharding-column: id
              algorithm-expression: user_tab_$->{id % 16}

4.2 读写分离+数据同步

graph LR A[主库] -->|Binlog| B[Canal] B --> C[消息队列] C --> D[从库消费]

📦5、典型场景实践案例

5.1 秒杀系统实现

关键技术点:

🔹 库存预热:提前加载到Redis
🔹 原子扣减:Lua脚本实现
🔹 限流措施:令牌桶算法
🔹 异步下单:消息队列削峰

Redis库存扣减Lua脚本

-- KEYS[1]: 库存key
-- ARGV[1]: 扣减数量
local stock = tonumber(redis.call('GET', KEYS[1]))
if stock >= tonumber(ARGV[1]) then
    return redis.call('DECRBY', KEYS[1], ARGV[1])
else
    return -1
end

5.2 实时排行榜

Redis ZSET实现

import redis

r = redis.Redis()

# 更新分数
r.zadd("leaderboard", {"player1": 1000, "player2": 1500})

# 获取TOP10
top_players = r.zrevrange("leaderboard", 0, 9, withscores=True)

# 分段查询
players = r.zrangebyscore(
    "leaderboard", min=1000, max=2000,
    start=0, num=50, withscores=True
)

🔁6、容灾与降级方案

6.1 熔断降级配置(Hystrix示例)

@HystrixCommand(
    fallbackMethod = "defaultProducts",
    commandProperties = {
        @HystrixProperty(name="circuitBreaker.requestVolumeThreshold", value="20"),
        @HystrixProperty(name="circuitBreaker.sleepWindowInMilliseconds", value="5000")
    },
    threadPoolProperties = {
        @HystrixProperty(name="coreSize", value="50"),
        @HystrixProperty(name="maxQueueSize", value="1000")
    }
)
public List<Product> getHotProducts() {
    // 远程调用
}

public List<Product> defaultProducts() {
    return Collections.emptyList();
}

6.2 多活部署架构

graph TD A[华东用户] --> B[上海机房] C[华北用户] --> D[北京机房] B -->|双向同步| D B --> E[全局数据库] D --> E

🚀 7、性能测试与调优

7.1 JMeter压测配置

<!-- 10万并发测试计划 -->
<ThreadGroup guiclass="ThreadGroupGui" testclass="ThreadGroup" testname="高并发测试">
  <intProp name="ThreadGroup.num_threads">100000</intProp>
  <intProp name="ThreadGroup.ramp_time">300</intProp>
  <longProp name="ThreadGroup.duration">600</longProp>
</ThreadGroup>

<HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="/api/order">
  <elementProp name="HTTPsampler.Arguments" elementType="Arguments">
    <collectionProp name="Arguments.arguments"/>
  </elementProp>
  <stringProp name="HTTPSampler.domain">api.example.com</stringProp>
  <stringProp name="HTTPSampler.port">443</stringProp>
  <stringProp name="HTTPSampler.protocol">https</stringProp>
  <stringProp name="HTTPSampler.path">/api/order</stringProp>
  <stringProp name="HTTPSampler.method">POST</stringProp>
</HTTPSamplerProxy>

7.2 关键优化参数

组件 参数 推荐值
Linux内核 net.ipv4.tcp_tw_reuse 1
JVM -Xmx/-Xms 机器内存的70%
MySQL innodb_buffer_pool_size 机器内存的80%
Redis maxmemory-policy volatile-lru
Tomcat maxThreads 500-1000

🧹8、监控与告警体系

8.1 Prometheus监控指标

# 应用关键指标
- job_name: 'order-service'
  metrics_path: '/actuator/prometheus'
  scrape_interval: 5s
  static_configs:
    - targets: ['10.0.0.1:8080']
  relabel_configs:
    - source_labels: [__address__]
      target_label: instance
      regex: '(.*):\d+'
      replacement: '$1'

8.2 Grafana看板配置

{
  "panels": [{
    "title": "QPS监控",
    "type": "graph",
    "targets": [{
      "expr": "rate(http_requests_total[1m])",
      "legendFormat": "{{instance}}"
    }],
    "thresholds": [
      {"value": 10000, "color": "red"}
    ]
  }]
}

🔚 9、总结

高并发系统设计是一个系统工程,关键在于「拆分 + 缓冲 + 降压」。核心原则是:

🔹 能缓存就缓存,能异步就异步

🔹 能拆分就拆分,能水平扩展就扩展

🔹 能限流就限流,不能崩就降级

高并发系统建设是持续优化的过程,建议采用渐进式架构演进策略,初期保证核心链路的高可用,逐步完善各层级的弹性设计。记住:没有银弹架构,最适合业务现状的方案才是最好的选择。

🧩 附:技术栈推荐

模块 技术
架构框架 SpringBoot + Dubbo
缓存 Redis
消息队列 RocketMQ / Kafka
数据库 MySQL + 分库分表
网关 Nginx / Spring Cloud Gateway
动物装饰