高并发系统设计:从理论到实践(适合初学者的完整教程)
开篇:什么是高并发系统,为什么重要?

在我们日常使用的互联网服务中,比如淘宝、微信、微博、抖音这些平台,每天可能有上亿用户同时在线。你有没有想过,这么多人都在使用,为什么网站还能保持快速响应、不崩溃?这就是高并发系统在背后发挥作用。
通俗点说:
高并发系统就是能够同时处理成千上万甚至上百万个请求的系统。
比如,双十一的时候,几千万人一起下单,服务器是怎么顶住压力的?不是靠蛮力,而是通过合理的设计和优化技术来实现的。
学习高并发系统设计,可以帮助你:
- 提升系统的稳定性
- 让程序响应更快、更可靠
- 应付面试、项目开发时的大流量场景
环境准备:搭建属于你的开发环境

为了便于实践,我们需要一个简单的后端环境。我们以 Node.js + Express 为例,配合 MySQL 和 Redis 来演示高并发相关的知识。
第一步:安装 Node.js 和 npm
前往官网下载并安装 Node.js。安装完成后,终端输入以下命令验证是否成功:
node -v # 查看版本号,如 v18.16.0
npm -v # 查看npm版本
第二步:安装 Express 框架
创建一个新文件夹 high-concurrency-demo,进入该目录,并初始化项目:
mkdir high-concurrency-demo
cd high-concurrency-demo
npm init -y
npm install express mysql redis
安装完成后,在目录下新建 server.js 文件作为我们的主程序入口。
第三步:运行简单 Web 服务
编辑 server.js 内容如下:
const express = require('express');
const app = express();
const port = 3000;
app.get('/', (req, res) => {
res.send('Hello,欢迎来到高并发世界!');
});
app.listen(port, () => {
console.log(`服务器启动在 http://localhost:${port}`);
});
运行服务:
node server.js
打开浏览器访问 http://localhost:3000,看到“Hello…”说明你的环境已经准备好啦!
核心概念:用最简单的语言解释专业术语

在正式开始实战之前,先让我们理解几个关键词:
1. 并发 vs 并行
- 并发(Concurrency):多个任务看似同时进行,其实是交替执行(常见于单核 CPU)
- 并行(Parallelism):多个任务真正的同时执行(多核 CPU 下)
📌 小贴士:你可以把并发理解为“一边听歌一边写作业”,虽然不能真正做到两件事同步,但感觉像在同时做。
2. 请求量与 QPS
- 请求量:单位时间内系统收到的请求总数
- QPS(Queries Per Second):每秒能处理多少请求
举个例子:
- 如果你的系统每秒处理 100 个请求,QPS 就是 100
3. 缓存(Cache)
缓存就像“临时笔记本”。很多请求的数据是一样的,每次从数据库查会很慢。我们可以把常用数据先存在内存里,下次就直接取,快得多。
4. 数据库连接池(Connection Pool)
频繁地连接数据库是很耗资源的,连接池就像是一个“工具箱”,提前准备好多连接,随时可以拿来用,效率大大提升。
5. 异步与非阻塞
这是 Node.js 的一大特点:
- 同步:前面的事不完成,后面的事就不能做
- 异步:前面的事不影响后面的事情
这有点像你在食堂打饭,不用排队等到前面的人打好饭才点菜,你可以点完之后去做别的事,等好了再回来拿。
实战项目:构建一个支持并发的简易商品秒杀系统

我们将一步步带你实现一个“商品秒杀”服务,模拟大并发场景下的请求处理。
第一步:创建数据库表
创建一个名为 seckill 的数据库,在其中建立一张商品库存表:
CREATE DATABASE seckill;
USE seckill;
CREATE TABLE goods (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(255),
stock INT DEFAULT 0
);
INSERT INTO goods (name, stock) VALUES ('iPhone', 10);
第二步:编写基础接口
继续完善 server.js 文件:
const express = require('express');
const mysql = require('mysql');
const app = express();
const port = 3000;
// 创建数据库连接池
const pool = mysql.createPool({
host: 'localhost',
user: 'root',
password: 'your_password',
database: 'seckill',
connectionLimit: 10
});
function query(sql, params) {
return new Promise((resolve, reject) => {
pool.query(sql, params, (error, results) => {
if (error) reject(error);
else resolve(results);
});
});
}
app.get('/buy/:id', async (req, res) => {
const goodsId = req.params.id;
try {
// 查询库存
const rows = await query('SELECT stock FROM goods WHERE id = ?', [goodsId]);
if (rows.length === 0 || rows[0].stock <= 0) {
return res.send({ success: false, message: '商品已售罄' });
}
// 减库存
await query('UPDATE goods SET stock = stock - 1 WHERE id = ?', [goodsId]);
res.send({ success: true, message: '购买成功!' });
} catch (err) {
console.error(err);
res.status(500).send({ success: false, message: '服务器异常' });
}
});
app.listen(port, () => {
console.log(`服务器启动在 http://localhost:${port}`);
});
第三步:测试并发效果
我们可以用 Apache Benchmark 工具(ab)进行并发测试。在命令行中执行:
ab -n 100 -c 50 http://localhost:3000/buy/1
-n 100表示总共发起 100 个请求-c 50表示并发数是 50
你会看到输出中有大量“商品已售罄”,这是因为没有做并发控制导致超卖问题。
第四步:解决超卖问题——使用 Redis 加锁
使用 Redis 做一个分布式锁来限制对库存的操作:
安装 Redis 客户端:
npm install redis
修改代码添加 Redis 锁机制:
const redis = require('redis');
const client = redis.createClient();
async function acquireLock(key, expireTime) {
const result = await client.set(key, 'locked', { EX: expireTime, NX: true });
return result === 'OK';
}
async function releaseLock(key) {
await client.del(key);
}
然后在 /buy/:id 接口里加锁:
app.get('/buy/:id', async (req, res) => {
const goodsId = req.params.id;
const lockKey = `lock:goods:${goodsId}`;
try {
const isLocked = await acquireLock(lockKey, 10); // 获取锁
if (!isLocked) return res.send({ success: false, message: '请求太频繁,请稍后再试' });
// 查询库存
const rows = await query('SELECT stock FROM goods WHERE id = ?', [goodsId]);
if (rows.length === 0 || rows[0].stock <= 0) {
await releaseLock(lockKey);
return res.send({ success: false, message: '商品已售罄' });
}
// 减库存
await query('UPDATE goods SET stock = stock - 1 WHERE id = ?', [goodsId]);
await releaseLock(lockKey);
res.send({ success: true, message: '购买成功!' });
} catch (err) {
console.error(err);
res.status(500).send({ success: false, message: '服务器异常' });
}
});
这样我们就能避免并发操作带来的库存错误了!
常见问题解答(FAQ)
❓ 问题一:为什么并发高会导致“商品被卖出多次”?
这是因为多个请求几乎同时读取了库存为 1 的状态,都以为自己还有机会减库存,所以最后变成了负数。这种现象叫做“并发竞争”。
✅ 解决方法:
- 使用事务或数据库乐观锁
- 使用 Redis 分布式锁(上面已展示)
- 使用队列异步处理
❓ 问题二:QPS 太低怎么办?
如果你发现系统每秒只能处理几十个请求,可能是以下几个原因:
✅ 建议排查点:
- 是否用了同步阻塞的方法?
- 数据库性能是否瓶颈?
- 是否需要引入缓存?
- 是否缺少负载均衡?
❓ 问题三:Redis 是必须的吗?
不一定,但在高并发场景下 Redis 是非常强大的工具,尤其是在:
- 缓存热门数据
- 分布式锁
- 队列任务管理
它可以大幅提升系统性能和一致性。
学习建议:下一步该怎么学?
恭喜你完成了第一个高并发项目的实践!接下来,你可以沿着这几个方向深入学习:
🔹 第一阶段:进阶知识
- 数据库索引优化
- 使用 ORM 框架(如 TypeORM / Sequelize)
- 掌握 RESTful API 设计规范
- 使用 Nginx 做负载均衡
- 引入消息队列(如 RabbitMQ、Kafka)
🔹 第二阶段:分布式架构
- 微服务架构(Spring Cloud / Dubbo)
- 分布式事务(Seata / Saga 模式)
- 使用 Zookeeper / Etcd 进行服务注册与发现
- 性能监控工具(Prometheus + Grafana)
🔹 第三阶段:大规模高可用
- 使用 Kubernetes 部署服务
- 构建熔断限流机制(Hystrix)
- 使用 CDN 缓存静态资源
- 跨地域容灾备份方案
结语:成为高并发高手只是时间问题
高并发系统设计并不是一蹴而就的技术栈,而是通过不断实践和积累逐步掌握的能力。本文通过一个实际的小案例,带你了解了如何处理并发请求、避免超卖、使用缓存以及构建简单的分布式锁。
只要你肯动手写代码、遇到问题多问多查,你也可以轻松驾驭“百万并发”这一听起来很厉害的词汇!
💡 小彩蛋提醒:
本项目完整的源码可在 GitHub 上查找参考(可自行创建仓库练习),后续我们会持续更新更多实战项目内容。
🎉 欢迎你继续关注本系列,下一节我们讲《用 Redis 实现限流与熔断》,敬请期待!
字数统计:约 3626 字

评论 0