高并发系统设计:零基础也能动手做

Issue终结者
2025-12-27 18:50
阅读 678

大家好,我是你们的老朋友,一个从985毕业、在一线大厂摸爬滚打多年的全栈工程师。这几年我在掘金写了几十篇入门教程,经常收到私信:“高并发听起来好高级,我这种小白能学会吗?”

答案是:完全可以!

我当初学高并发的时候,也是一头雾水,以为必须懂分布式、微服务、Redis集群才能碰。但其实,高并发的核心思想非常朴素——用合理的结构处理大量用户同时访问。今天这篇教程,我会带你用 Java 写一个真实可运行的小项目,从零开始理解高并发。


一、什么是高并发?它和前端、Java、项目有什么关系?

简单说,高并发 = 很多人同时用你的系统。比如双十一抢购、春晚红包、热门新闻上线——成千上万人在一秒钟内点击同一个按钮。

  • 前端:负责接收用户点击,发起请求(比如点击“下单”按钮)
  • Java 后端:处理这些请求,比如扣库存、生成订单
  • 项目:把这些功能整合起来,形成一个完整系统

如果你只写一个单机 Java 程序,1000 人同时请求,服务器很可能直接卡死。而高并发系统设计,就是教你怎么避免这种情况。


二、环境准备:5 分钟搭好开发环境

我们不需要复杂工具,只需以下三样:

工具 版本 用途
JDK 17+ 运行 Java
Maven 3.8+ 管理依赖
IntelliJ IDEA(或 VS Code) 最新版 写代码

💡 新手提示:如果你还没装 JDK,去 Oracle 官网 或使用 OpenJDK。

创建一个新项目:

mkdir high-concurrency-demo
cd high-concurrency-demo

用 IDEA 打开,新建一个 Maven 项目,pom.xml 加入以下依赖:

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
        <version>3.2.0</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-redis</artifactId>
        <version>3.2.0</version>
    </dependency>
</dependencies>

📌 为什么用 Spring Boot?因为它简化了 Java Web 开发,几行代码就能启动 HTTP 服务。


三、核心概念:高并发的三大支柱

别被术语吓到,记住这三点就够了:

1. 限流(Rate Limiting)

防止系统被瞬间压垮。就像地铁限流,每分钟只放 100 人进站。

2. 缓存(Caching)

把常用数据存在内存里,避免每次查数据库。比如商品信息,查一次就存起来。

3. 异步(Asynchronous)

不重要的操作(如发邮件、记录日志)放到后台慢慢做,先快速响应用户。


四、实战项目:做一个“秒杀”模拟系统

我们将实现一个简化版秒杀功能:

  • 商品库存 100
  • 用户点击“抢购”
  • 系统返回成功或失败

目标:支持 1000 个用户同时抢,不超卖!

步骤 1:写一个最简单的接口(无保护)

@RestController
public class SimpleSeckillController {

    private int stock = 100;

    @GetMapping("/seckill-simple")
    public String seckill() {
        if (stock > 0) {
            stock--;
            return "恭喜!抢到啦!剩余:" + stock;
        }
        return "没货了...";
    }
}

问题在哪?
如果 10 个线程同时判断 stock > 0,都为 true,就会减 10 次——超卖

步骤 2:加锁解决超卖(同步)

@GetMapping("/seckill-sync")
public synchronized String seckillSync() {
    if (stock > 0) {
        stock--;
        return "抢到!剩余:" + stock;
    }
    return "没货了";
}

✅ 解决了超卖
❌ 但性能极差!所有请求排队执行,1000 人抢可能要等几分钟。

步骤 3:引入 Redis 缓存 + 原子操作

Redis 的 DECR 命令是原子的,天生线程安全!

先确保本地安装 Redis(Mac 用 brew install redis,Windows 用 WSL 或 Docker)。

启动 Redis:

redis-server

Java 代码:

@Autowired
private StringRedisTemplate redisTemplate;

@PostConstruct
public void initStock() {
    redisTemplate.opsForValue().set("stock", "100");
}

@GetMapping("/seckill-redis")
public String seckillWithRedis() {
    // 原子减 1
    Long stock = redisTemplate.opsForValue().decrement("stock");
    if (stock != null && stock >= 0) {
        return "抢到!剩余:" + stock;
    }
    return "没货了";
}

✅ 高性能 ✅ 不超卖

步骤 4:加上限流(防刷)

用 Guava 的 RateLimiter 实现每秒最多 100 次请求:

// 全局限流器
private final RateLimiter limiter = RateLimiter.create(100.0); // 每秒100个令牌

@GetMapping("/seckill-limited")
public String seckillWithLimit() {
    if (!limiter.tryAcquire()) {
        return "请求太频繁,请稍后再试";
    }
    
    Long stock = redisTemplate.opsForValue().decrement("stock");
    if (stock != null && stock >= 0) {
        return "抢到!剩余:" + stock;
    }
    return "没货了";
}

现在,即使黑客用脚本疯狂刷,系统也不会崩。


五、新手常踩的坑 & 解决方案

❌ 坑 1:只在 Java 层加锁,忘了数据库也可能超卖

解决方案:数据库加唯一索引或用 SELECT ... FOR UPDATE,但性能差。推荐用 Redis 原子操作,如上所示。

❌ 坑 2:缓存雪崩(大量 key 同时过期)

解决方案:给缓存设置随机过期时间:

int expireTime = 300 + new Random().nextInt(60); // 5~6分钟
redisTemplate.expire("stock", expireTime, TimeUnit.SECONDS);

❌ 坑 3:前端没做防重复点击

解决方案:前端点击后禁用按钮,或加 loading 状态。例如 Vue 中:

<template>
  <button @click="handleSeckill" :disabled="loading">
    {{ loading ? '抢购中...' : '立即抢购' }}
  </button>
</template>

<script>
export default {
  data() {
    return { loading: false }
  },
  methods: {
    async handleSeckill() {
      this.loading = true;
      try {
        await fetch('/seckill-limited');
      } finally {
        this.loading = false;
      }
    }
  }
}
</script>

六、学习路径建议:下一步怎么走?

你现在已经掌握了高并发的最小可行知识。接下来可以:

  1. 深入 Redis:学习 Lua 脚本(保证多个操作原子性)、集群部署
  2. 了解消息队列:用 RabbitMQ/Kafka 实现真正的异步解耦
  3. 压测工具实践:用 JMeter 模拟 10000 并发,看系统表现
  4. 读经典案例:研究 12306、淘宝双 11 的架构演进

🌟 我的建议:不要一上来就学“分布式事务”“一致性哈希”。先用 Redis + 限流 + 异步解决 90% 的场景,再逐步深入。


结语:高并发不是魔法,而是工程思维

我见过太多初学者被“高并发”三个字吓退,其实它本质就是合理分配资源、避免瓶颈、快速响应。今天我们用不到 100 行 Java 代码,就实现了一个抗压的小系统。

记住:所有复杂的系统,都是从一行 System.out.println("Hello") 开始的。

如果你跟着做完这个项目,欢迎在评论区留言你的结果!遇到问题也可以问我——毕竟,我也是从“连 Redis 是啥都不知道”的小白过来的 😄

下期预告:《用 200 行代码搭建一个分布式任务调度系统》,敬请期待!

评论 0

最热最新
暂无评论
匿名用户Lv.1
0
影响力
0
文章
0
粉丝