高并发系统设计:从理论到实践(新手友好版)

梁红
2025-06-18 22:58
阅读 745

一、什么是高并发系统?

一、什么是高并发系统?

你有没有在双十一凌晨0点抢购过商品?有没有在抢票时遇到“服务器繁忙”?这些情况的背后,就是高并发场景。也就是说,在极短的时间内,成千上万的用户同时访问一个系统,系统要能稳定处理这么多请求。

高并发系统设计,就是教你如何构建这种能够承受大量请求、响应迅速、不崩溃的系统。


二、我们需要准备什么环境?

二、我们需要准备什么环境?

1. 安装基础软件

  • Java(JDK 17)
  • Maven(项目构建工具)
  • IDEA 或 VSCode(开发工具)
  • Redis(缓存数据库)
  • MySQL(关系型数据库)
  • Postman(接口测试工具)

你可以用以下命令快速安装 Java:

sudo apt update
sudo apt install openjdk-17-jdk
java -version

Maven 安装指南可参考官网 https://maven.apache.org


三、核心概念讲解

三、核心概念讲解

1. 并发与并行的区别

  • 并发:多个任务看似同时执行(其实是轮着运行),比如浏览器同时下载图片和播放音乐。
  • 并行:真正的同时执行,需要多核 CPU。

小白理解:就像炒菜,一个人炒很多道菜是“并发”,两个人一起炒就是“并行”。

2. 请求、线程、连接池

  • 请求:用户通过浏览器或手机发送的操作指令,比如点击下单按钮。
  • 线程:程序中执行任务的最小单位。
  • 连接池:数据库连接不是每次都要新建,而是复用已有的连接。

3. 常见瓶颈与解决方案

瓶颈类型 问题描述 解决方案
数据库压力大 大量用户同时查询 加缓存(Redis)
接口响应慢 没有优化逻辑 使用线程池异步处理
系统崩溃 负载过高 使用限流、降级策略

四、实战项目:秒杀商品系统

四、实战项目:秒杀商品系统

我们将实现一个简单的商品秒杀系统,模拟高并发访问下的处理流程。

第一步:搭建 Spring Boot 项目结构

使用 Spring Initializr 创建项目:https://start.spring.io/

添加依赖:

  • Spring Web
  • Spring Data JPA
  • Redis
  • Lombok

然后解压导入 IDE 中。

第二步:简单商品表结构(MySQL)

创建一张商品表:

CREATE TABLE product (
    id BIGINT PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(100),
    stock INT
);

插入一条数据:

INSERT INTO product (name, stock) VALUES ('iPhone 15', 100);

第三步:编写控制器和业务层

Product.java 实体类:

@Entity
@Data
public class Product {
    @Id
    private Long id;
    private String name;
    private int stock;
}

ProductService.java:

@Service
@RequiredArgsConstructor
public class ProductService {

    private final ProductRepository productRepo;

    // 模拟减库存操作
    public synchronized boolean reduceStock(Long productId) {
        Product product = productRepo.findById(productId).orElse(null);
        if (product == null || product.getStock() <= 0) {
            return false;
        }
        product.setStock(product.getStock() - 1);
        productRepo.save(product);
        return true;
    }
}

ProductController.java:

缓存策略对比-2

@RestController
@RequestMapping("/products")
@RequiredArgsConstructor
public class ProductController {

    private final ProductService productService;

    @GetMapping("/{id}/buy")
    public String buyProduct(@PathVariable Long id) {
        boolean success = productService.reduceStock(id);
        return success ? "购买成功" : "库存不足";
    }
}

第四步:压力测试

使用 Apache JMeter 或 Postman 进行并发测试。

设置并发用户数为 1000,对 /products/1/buy 发起请求,你会发现库存减少正确,不会出现负数。


五、常见问题解答

❓Q1:为什么不能直接操作数据库减库存?会出什么问题?

:因为多个线程同时读写数据库可能会导致超卖(库存变成负数)。例如两个线程同时读取了库存为1,都会判断“大于0”,然后各自减1,结果库存变成了-1。

解决办法:

  • 使用synchronized关键字加锁(如上面的代码)
  • 使用数据库乐观锁机制(推荐)
  • 使用 Redis 分布式锁(适合分布式系统)

❓Q2:什么是线程池?为什么要用它?

:线程池是一组预先创建好的线程,可以重复利用它们来处理任务,避免频繁创建销毁线程带来的性能损耗。

示例:使用线程池做异步减库存:

@Configuration
@EnableAsync
public class AsyncConfig {

    @Bean(name = "taskExecutor")
    public Executor taskExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(10);
        executor.setMaxPoolSize(20);
        executor.setQueueCapacity(500);
        executor.setThreadNamePrefix("async-thread-");
        executor.initialize();
        return executor;
    }
}

调用时加上注解:

@Async("taskExecutor")
public void asyncReduceStock(Long id) {
    reduceStock(id);
}

这样可以让多个请求异步处理,提高吞吐量。


❓Q3:单机部署不够怎么办?

:可以考虑使用:

  • Nginx 做负载均衡
  • Redis 做分布式缓存
  • Spring Cloud 做服务注册与发现
  • 使用 RocketMQ 或 RabbitMQ 异步处理订单

六、下一步学习建议

服务器部署方案-1

恭喜你完成了第一个高并发小项目!接下来你可以在以下几个方向继续深入:

✅进阶路线图:

  1. 掌握数据库优化

    • 学习索引优化
    • 了解事务隔离级别和死锁处理
  2. 学习Redis应用

    • 缓存穿透、雪崩、击穿
    • 使用Redis实现分布式锁
  3. 掌握消息队列

    • RocketMQ / RabbitMQ / Kafka
    • 应用场景:异步下单、日志处理
  4. 微服务架构

    • Spring Cloud
    • Nacos、Sentinel、Gateway等组件
  5. 性能监控与调优

    • 使用 SkyWalking / Prometheus + Grafana
    • JVM调优、GC分析

结语

高并发系统设计并不神秘,只要我们一步步来,先从小项目练手,再逐步扩展知识面,你也能写出稳定的高性能系统!

如果你觉得这篇文章对你有帮助,不妨收藏或分享给其他刚入门的朋友,让我们一起成长吧!🚀


如需完整源码示例,请留言或私信获取 GitHub 地址。

评论 0

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