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

哈希表少年
2025-06-27 17:18
阅读 712

开篇:什么是高并发系统?

开篇:什么是高并发系统?

你有没有遇到过这样的情况?在某个电商大促的时候,打开网页特别慢,甚至直接打不开。这就是因为访问的人太多,服务器处理不过来

这个时候我们就需要一个“更强的系统”来应对大量的请求,这种系统就叫高并发系统

那什么是高并发呢?简单来说,就是同时处理成千上万个请求的能力。比如:

  • 淘宝双11时,几千万人同时下单
  • 微信发红包时,几百万用户一起抢红包
  • 春运抢票时,无数人同时访问购票系统

这些背后的技术,都是高并发系统在支撑。

本教程的目标是带你从零开始,用最简单的语言、最清晰的步骤,亲手写一个可以应对小规模并发请求的Web服务。


第一步:环境准备(跟着做,不复杂!)

第一步:环境准备(跟着做,不复杂!)

我们先准备好开发环境。以下是推荐配置:

所需软件:

软件 用途 下载地址(官网)
VS Code 编写代码 code.visualstudio.com
Node.js 后端运行环境 nodejs.org
Postman 发送网络请求测试用 postman.com
Redis 做缓存 redis.io/download
MongoDB 数据库存储数据 mongodb.com

提示:Windows用户推荐使用NVM for Windows管理Node版本,Mac用户可使用brew安装。

安装检查

在终端输入以下命令,如果输出类似内容说明安装成功:

node -v
# 输出 v20.x.x
npm -v
# 输出 9.x.x

第二步:核心概念讲解(通俗易懂)

第二步:核心概念讲解(通俗易懂)

要理解高并发系统,我们需要知道几个关键角色和概念:

1. 并发 ≠ 请求数量

很多人以为并发数 = 同时有多少个请求,其实并不是。并发是指系统在同一时间能处理多少个请求。例如,一个网站有1万人访问,但只有100个同时下单的人,这叫并发100。

2. 线程 vs 协程

  • 线程:操作系统层面的“工人”,可以并行处理任务。
  • 协程:一种轻量级线程,常用于异步编程中,比如Node.js中的Promise/async-await。

类比:你可以把线程想象成员工,协程就像员工的工作效率,他们可以在一个员工里快速切换任务。

3. 缓存(Cache)

当很多用户都来查同一个信息时,每次都去数据库读太慢。我们可以把这些信息“记下来”,放在内存中,这样下次就快了,这就叫缓存

4. 异步非阻塞

传统程序是一条一条顺序执行的,如果有耗时操作(如读数据库),程序就会卡住等待。而异步非阻塞方式可以让程序在等待的同时去做别的事情,效率更高。


第三步:实战项目:做一个简单的高并发计数器API

数据流转过程-1

我们来实现一个功能:每有一个用户访问 /visit 接口,就将计数加一,并记录当前总访问数。

我们将用 Node.js + Express 实现这个接口,并演示如何让它支持并发访问。

步骤1:创建项目

mkdir high-concurrency-demo
cd high-concurrency-demo
npm init -y
npm install express

新建 app.js 文件,内容如下:

const express = require('express');
let count = 0;

const app = express();

app.get('/visit', (req, res) => {
  count += 1;
  res.send(`总访问人数:${count}`);
});

app.listen(3000, () => {
  console.log('服务启动在 http://localhost:3000');
});

运行项目:

node app.js

打开浏览器访问 http://localhost:3000/visit,刷新多次你会发现数字会增加!

但是问题来了:如果是多个用户同时访问,会不会出错?

我们来模拟一下并发访问。

步骤2:用Node.js发起并发请求测试

新建文件 test.js

const axios = require('axios');

async function testConcurrency() {
  const requests = Array(10).fill(axios.get('http://localhost:3000/visit'));
  const responses = await Promise.all(requests);
  responses.forEach((res, i) => {
    console.log(`第 ${i+1} 次请求结果:`, res.data);
  });
}

testConcurrency();

运行命令:

node test.js

注意:此时你会看到有些次数没被正确统计,比如应该是10次但只加到了7次。这是因为我们的程序没有使用锁机制,出现了并发安全问题

解决方案:引入Redis缓存与原子操作

安装Redis模块:

npm install redis

修改 app.js 如下:

const express = require('express');
const redis = require('redis');

const client = redis.createClient(); // 默认连接 localhost:6379

const app = express();

app.get('/visit', async (req, res) => {
  client.incr('visit_count', (err, count) => {
    if (err) throw err;
    res.send(`总访问人数:${count}`);
  });
});

app.listen(3000, () => {
  console.log('服务启动在 http://localhost:3000');
});

现在再运行测试脚本,你会发现每次都能准确累计。

✅ 为什么Redis能解决并发问题?

因为Redis提供了一个叫做 INCR原子操作,意思是在加一的过程中不会被打断,确保了数据的一致性。


第四步:常见问题解答(FAQ)

Q1:我的程序为什么会并发出错?

A:因为你用了普通变量来做计数器。在并发访问时,两个请求可能同时读取值,导致只加了一次。这时候需要用锁机制原子操作来避免冲突。

Q2:Redis是什么?必须用吗?

A:Redis是一种内存数据库,适合用来做缓存和计数等高速读写场景。你也可以不用它,但如果想自己实现并发安全,就需要用像Mutex锁、CAS指令等方法。

Q3:怎么查看Redis的值?

A:你可以使用Redis命令行工具:

redis-cli get visit_count

第五步:学习建议与下一步方向

恭喜你完成了第一个高并发系统的小项目!

接下来可以尝试以下进阶学习路径:

学习路线图:

  1. 【基础】学好Node.js/Express基本语法
  2. 【中间件】学习使用Nginx做负载均衡
  3. 【缓存】深入了解Redis高级用法(分布式锁、持久化)
  4. 【消息队列】学习使用Kafka/RabbitMQ实现异步处理
  5. 【微服务】了解Spring Cloud/Dubbo构建大型分布式系统
  6. 【性能测试】掌握JMeter/LoadRunner进行压测

推荐资源:

类型 名称 地址
书籍 《高并发系统实战》 天猫/京东搜索
视频 B站:Java高并发系统设计课程 Bilibili 搜索关键词
工具 Apache JMeter https://jmeter.apache.org/
社区 SegmentFault/CSDN问答 sf.gg / bbs.csdn.net

总结

本文从零讲起,通过一个小小的项目让你理解了:

  • 高并发是什么
  • 为什么会出现并发错误
  • 如何用Redis保证并发安全
  • 以及如何用Node.js编写并发友好的程序

记住一句话:

“并发不是多,而是协调。”

你已经迈出了成为后端高手的第一步。继续加油!如果你觉得这篇文章对你有帮助,请收藏分享,让更多新手加入高效编程的世界 😊

评论 0

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