{T}

高性能架构设计

概述

高性能架构的核心目标是让系统在单位时间内处理更多请求、保持低延迟响应。本文从核心性能指标(TPS/QPS/RPS)出发,讲解并发量估算方法、性能监控体系搭建、性能测试策略,以及缓存、异步、数据库、架构四个层面的优化手段,并结合电商秒杀、12306 抢票等真实场景说明设计要点。

前置知识

学习目标

  • 区分 TPS、QPS、RPS 的含义与适用场景
  • 掌握并发量估算公式与经验比例
  • 了解性能监控系统架构(Prometheus + Grafana)
  • 熟悉四类性能测试方法
  • 掌握多层级性能优化策略

一、核心性能指标

1.1 三大指标定义

指标全称含义典型量级适用场景
TPSTransactions Per Second每秒完成的完整业务事务数较低核心业务性能评估
QPSQueries Per Second每秒查询/接口调用数较高数据库 / API 性能监控
RPSRequests Per Second每秒 HTTP 请求数较高Web 服务器性能

核心关系QPS ≈ RPS > TPS(一次事务通常包含多次查询)

1.2 TPS 与 QPS 的关系

图表渲染中…
  • 一次事务(TPS=1)可能触发 5+ 次数据库查询(QPS=5)
  • 当一次事务仅包含一次查询时,TPS ≈ QPS(如 GET /api/user/profile

1.3 吞吐量计算

javascript
// QPS = 总请求数 / 时间窗口(秒)
const qps = 6000 / 60; // 100 QPS

// TPS = 总事务数 / 时间窗口(秒)
const tps = 18000 / 3600; // 5 TPS

企业通常不公开性能数据:暴露 QPS 上限可能被攻击者利用,在业务低峰期发起精准 DDoS 攻击。

二、并发量估算

2.1 核心公式

code
并发量 = QPS × 平均响应时间(秒)

2.2 经验比例(容量规划)

换算步骤比例示例
总用户 → 在线用户10:11000 万注册 → 100 万在线
在线用户 → 峰值 QPS10:1100 万在线 → 10 万 QPS
峰值 QPS → 峰值 TPS5~10:110 万 QPS → 1~2 万 TPS

2.3 实战场景

电商系统

  • 峰值 QPS = 50,000,平均响应 200ms
  • 并发量 = 50,000 × 0.2 = 10,000 并发

秒杀系统

  • 峰值 QPS = 500,000,平均响应 100ms
  • 并发量 = 500,000 × 0.1 = 50,000 并发(抢 1000 台库存)
  • 优化策略:请求队列 + 限流 → Redis 预扣库存 → 异步创建订单 → CDN 静态化

2.4 真实案例参考

系统峰值特征核心挑战
天猫双十一数据库 TPS 1.4 亿次/秒(2020)峰值是日常的几百倍
12306 春运秒级流量暴增 + 多平台汇聚库存原子扣减、防超卖
微博热点突发 10 倍+ 流量自动扩容速度 < 流量涌入速度

三、性能监控体系

3.1 监控架构

图表渲染中…

3.2 Node.js 集成 Prometheus

javascript
const client = require('prom-client');

// 请求耗时直方图
const httpRequestDuration = new client.Histogram({
  name: 'http_request_duration_seconds',
  help: 'Duration of HTTP requests in seconds',
  labelNames: ['method', 'route', 'status_code'],
  buckets: [0.1, 0.5, 1, 1.5, 2, 5]
});

// 请求计数(用于计算 QPS)
const qpsCounter = new client.Counter({
  name: 'http_requests_total',
  help: 'Total number of HTTP requests',
  labelNames: ['method', 'route']
});

// Express 中间件
app.use((req, res, next) => {
  const start = Date.now();
  res.on('finish', () => {
    const duration = (Date.now() - start) / 1000;
    httpRequestDuration.labels(req.method, req.route?.path, res.statusCode).observe(duration);
    qpsCounter.labels(req.method, req.route?.path).inc();
  });
  next();
});

// 暴露 /metrics 端点供 Prometheus 抓取
app.get('/metrics', async (req, res) => {
  res.set('Content-Type', client.register.contentType);
  res.end(await client.register.metrics());
});

3.3 Prometheus 配置

yaml
# prometheus.yml
global:
  scrape_interval: 15s

scrape_configs:
  - job_name: 'nodejs-app'
    static_configs:
      - targets: ['localhost:3000']

四、性能测试方法

4.1 四类测试策略

测试类型目的关注指标
负载测试预期负载下的性能表现QPS、响应时间、资源使用率
压力测试找到系统极限与崩溃点最大 QPS、恢复时间
并发测试同时处理多请求的能力成功率、死锁、竞态条件
耐久性测试长时间运行稳定性内存泄漏、性能衰减

4.2 常用工具

工具特点典型命令
Apache Bench (ab)轻量、快速ab -n 10000 -c 100 http://localhost:3000/api
wrk高效、多线程wrk -t12 -c400 -d30s http://localhost:3000/api
JMeterGUI、多协议、可扩展图形化配置线程组 + 采样器
ArtilleryYAML 配置、渐进加压artillery run config.yml

4.3 Artillery 渐进加压示例

yaml
config:
  target: 'http://localhost:3000'
  phases:
    - duration: 60
      arrivalRate: 10
      name: "Warm up"
    - duration: 120
      arrivalRate: 10
      rampTo: 50
      name: "Ramp up"
    - duration: 300
      arrivalRate: 50
      name: "Sustained load"

scenarios:
  - name: "User browsing"
    flow:
      - get: { url: "/api/products" }
      - think: 2
      - get: { url: "/api/products/{{ $randomNumber(1, 100) }}" }

五、性能优化策略

5.1 优化层次

图表渲染中…

5.2 多级缓存

层级工具TTL适用数据
L1 本地缓存node-cache / Map60s热点配置、字典数据
L2 分布式缓存Redis1h会话、共享业务数据
L3 CDN 缓存CloudFlare / 阿里云24h静态资源、公开 API 响应
javascript
class CacheManager {
  constructor() {
    this.local = new Map();
    this.redis = new Redis();
  }

  async get(key) {
    // L1: 本地缓存
    if (this.local.has(key)) return this.local.get(key);
    // L2: Redis
    const cached = await this.redis.get(key);
    if (cached) { this.local.set(key, cached); return cached; }
    // L3: 数据库回源
    const data = await this.queryDB(key);
    if (data) {
      await this.redis.set(key, data, 'EX', 3600);
      this.local.set(key, data);
    }
    return data;
  }
}

5.3 异步处理

核心思想:快速响应核心操作,非核心任务投递消息队列异步执行。

javascript
// 订单创建 — 异步优化
async function createOrder(orderData) {
  const order = await Order.create(orderData); // 核心:同步

  // 非核心:投递消息队列
  MessageQueue.publish('order.created', {
    orderId: order.id,
    userId: order.userId
  });

  return order; // 立即返回
}

// 消费者异步处理
MessageQueue.subscribe('order.created', async ({ userId }) => {
  await Email.send(userId, '订单创建成功');
  await SMS.send(userId, '订单创建成功');
});

5.4 数据库优化

优化手段说明
索引优化为高频 WHERE/ORDER BY 字段建立索引
查询精简只 SELECT 必要字段,避免 SELECT *
分页优化游标分页(WHERE id > lastId)替代大 OFFSET
读写分离主库写、从库读,轮询负载均衡
分库分表垂直按业务拆库,水平按 userId % N 分表

5.5 读写分离实现

javascript
class DatabaseManager {
  constructor() {
    this.master = createConnection({ host: 'master.db' });
    this.slaves = [
      createConnection({ host: 'slave1.db' }),
      createConnection({ host: 'slave2.db' })
    ];
    this.idx = 0;
  }

  write(sql, params) { return this.master.query(sql, params); }

  read(sql, params) {
    const slave = this.slaves[this.idx % this.slaves.length];
    this.idx++;
    return slave.query(sql, params);
  }
}

六、高性能设计模式

模式核心思想适用场景
读写分离主写从读,数据同步读多写少系统
分库分表数据水平/垂直拆分单表数据量 > 千万
消息队列削峰异步消费,平滑流量秒杀、抢购
多级缓存逐级回源,命中率递增热点数据频繁访问
限流熔断超阈值拒绝/降级保护下游不被打垮

常见问题

问题根因解决方案
QPS 突然下降慢查询 / 缓存大面积失效优化 SQL + 缓存预热
响应时间过长代码瓶颈 / 网络延迟Profiling + CDN
并发量上不去锁竞争 / 资源瓶颈异步化 + 水平扩容
系统频繁崩溃内存泄漏 / 资源耗尽内存监控 + 自动重启 + 扩容
连接池耗尽连接未释放连接池配置优化 + 读写分离
缓存穿透大量无效 key 请求布隆过滤器 + 空值缓存

最佳实践

  1. 监控先行:先建立 Prometheus + Grafana 可观测体系,再做优化
  2. 数据驱动:基于压测数据定位瓶颈,避免凭感觉优化
  3. 缓存优先:能缓存的不查库,能异步的不同步
  4. 渐进加压:性能测试从低到高逐步增加并发,找到拐点
  5. 预案机制:限流、降级、熔断策略提前配置并演练

延伸阅读


上一篇: 架构设计五大维度 下一篇: 高可用架构设计 — SLA、主备切换、集群与分布式