🧩 一、背景:为什么要压?
Next.js 很强大,但在高并发场景下(例如金融数据查询、实时行情页面),
如果你没做好性能调优,它也可能在 1K 并发量下 直接宕机 ,
就像一辆没换刹车油的赛车,跑快的时候最先冒烟的就是后座。
因此我们需要:
- 使用 k6 打压 Next.js 服务的极限
- 通过 连接池调优 / 索引优化 / SSR缓存 等手段提升吞吐量
🧰 二、测试环境准备
假设你正在测试一个部署好的 Next.js 应用:
arduino
https://api.example.com/orders
环境配置建议:
| 组件 | 说明 | 调优方向 |
|---|---|---|
| Node.js | 建议 v18+ | 启用 HTTP Keep-Alive、性能分析 |
| 数据库 | PostgreSQL / MySQL / MongoDB | 检查索引、优化连接池 |
| 服务器 | Nginx or PM2 cluster | 使用多进程 |
| 网络 | ≥ 1Gbps | 保证脚本测试不受限于带宽 |
📈 三、k6 压测脚本示例
下面是一个完整的 1K 并发压测脚本示例,可直接运行。
javascript
// 文件名:load_test.js
import http from 'k6/http';
import { check, sleep } from 'k6';
export let options = {
stages: [
{ duration: '10s', target: 200 }, // warm up
{ duration: '20s', target: 1000 }, // ramp up to 1k users
{ duration: '30s', target: 1000 }, // sustain 1k concurrency
{ duration: '10s', target: 0 }, // ramp down
],
thresholds: {
http_req_duration: ['p(95)<500'], // 95% 响应小于500ms
http_req_failed: ['rate<0.01'], // 错误率小于1%
},
noConnectionReuse: false, // 启用 HTTP keep-alive
};
export default function () {
const url = 'https://api.example.com/orders';
const res = http.get(url, { headers: { 'Accept': 'application/json' } });
check(res, {
'status 为 200': (r) => r.status === 200,
'响应包含 data 字段': (r) => r.body.includes('data'),
});
sleep(1);
}
运行命令:
arduino
k6 run load_test.js
🧮 四、读取结果分析
输出中会出现以下关键信息:
| 指标 | 含义 | 优化方向 |
|---|---|---|
http_req_duration |
平均响应时间 | 查找慢 SQL、缓存命中率 |
vus / vus_max |
并发虚拟用户数 | 上调 Node worker 数量 |
iteration_duration |
完整请求周期时间 | 检查网络延迟或渲染瓶颈 |
http_req_failed |
错误率 | 检查 5xx 与 DB 超时 |
⚙️ 五、性能调优方向
1. Node.js + Next.js 层优化
🧵 多线程与连接池管理
采用 Cluster 模式或 PM2 管理:
arduino
pm2 start npm --name "next-app" -- run start -i max
或在 server.js 自建 HTTP/2 + Keep-Alive:
ini
import http from 'http';
import next from 'next';
const app = next({ dev: false });
const handle = app.getRequestHandler();
app.prepare().then(() => {
const server = http.createServer((req, res) => handle(req, res));
server.keepAliveTimeout = 65000; // 允许连接复用
server.listen(3000, () => console.log('🚀 Next.js server running'));
});
2. 数据库性能优化
✅ 连接池配置(以 Prisma + PostgreSQL 为例)
schema.prisma 中:
ini
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
connection_limit = 20
}
.env 文件:
ini
DATABASE_URL="postgresql://user:pwd@host:5432/db?connection_limit=20&pool_timeout=5"
Tips:
- 根据
cpu核心数 × 2 + 连接余量设置连接池上限; - 对高频查询字段(如
order_id、user_id)建立 B-tree 索引; - 查询优化:把 N+1 查 改为
JOIN或IN 查询。
3. ⚡ 缓存策略
- 短期缓存(SSR 缓存) :
利用 Next.js 的getServerSideProps+ Redis 缓存接口层结果; - 静态编译缓存(SSG) :
对变化不频繁的页面使用预渲染,减少服务端计算开销; - Nginx 缓存 :
针对GET接口设置微缓存,例如 1s,极大抵消瞬时高并发。
ini
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=my_cache:10m max_size=1g inactive=60m use_temp_path=off;
location /api/ {
proxy_cache my_cache;
proxy_cache_valid 200 1s;
}
📊 六、可视化监控建议
| 工具 | 用途 | 建议 |
|---|---|---|
| Grafana + InfluxDB | 显示 k6 实时指标 | 接入 k6 run --out influxdb=http://... |
| PM2 monit | 观察 Node 内存占用 | Detect leaks |
| pg_stat_statements | PostgreSQL 查询耗时统计 | 聚焦慢 SQL |
| Chrome Lighthouse | 前端性能测量 | 检查 TTFB / SSR Bottleneck |
🧭 七、结尾:让Next.js跑得快的哲学
优化性能不是一次性的事,而是一种「工程禅」:
"压测让你看到系统的真相,
调优让系统配得上它的潜力。"
💡 总结Checklist:
✅ k6 压测 1K 并发
✅ 启用 HTTP Keep-Alive
✅ PM2 集群化
✅ 数据库连接池 & 索引优化
✅ SSR + 缓存层
✅ 实时监控 & 慢查询分析