背景:某头部电商平台在双十一大促期间,通过精准的 QPS、TPS 评估和容量规划,成功将系统承载能力从每秒 10 万请求提升至 50 万+,同时保持 99.99%的服务稳定性。本文将深入解析 QPS、TPS 与系统容量规划的关系,并结合实际案例提供落地指南。
一、QPS、TPS 的核心概念与关系
1.1 核心定义
# 关键术语
1. **QPS(Queries Per Second)**:每秒查询数,衡量系统的请求处理能力。
2. **TPS(Transactions Per Second)**:每秒事务数,通常指完整的业务逻辑操作。
3. **系统容量**:系统能承载的最大QPS/TPS,受硬件资源、软件设计、网络带宽等限制。
1.2 QPS 与 TPS 的关系
-
关键点:
-
一个 QPS 可能包含多个 TPS(如一次请求触发多步事务)。
-
容量规划需综合考虑 QPS 与 TPS 的比例关系。
-
二、实战案例:电商订单系统的容量规划 🔥
2.1 业务背景
- 需求描述:
每秒需处理50万+订单请求,保障库存扣减准确性和支付成功率。
-
原始痛点:
-
数据库连接池耗尽,高峰期服务不可用。
-
缓存击穿导致热点商品查询超时。
-
系统瓶颈难以量化,扩容缺乏依据。
-
2.2 解决方案
压测评估 QPS 与 TPS
使用 JMeter 进行压测
<!-- JMeter配置文件 -->
<TestPlan>
<ThreadGroup guiclass="ThreadGroupGui" testclass="ThreadGroup">
<stringProp name="ThreadGroup.num_threads">100</stringProp><!-- 并发用户数 -->
<stringProp name="ThreadGroup.ramp_time">10</stringProp><!-- 启动时间 -->
<stringProp name="ThreadGroup.duration">60</stringProp><!-- 测试时长 -->
<HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy">
<stringProp name="HTTPSampler.domain">api.example.com</stringProp>
<stringProp name="HTTPSampler.port">8080</stringProp>
<stringProp name="HTTPSampler.path">/order/create</stringProp>
<boolProp name="HTTPSampler.follow_redirects">true</boolProp>
<stringProp name="HTTPSampler.method">POST</stringProp>
</HTTPSamplerProxy>
</ThreadGroup>
</TestPlan>
压测结果分析
# 压测输出
QPS: 50,000 requests/sec
TPS: 40,000 transactions/sec
Database Connections: 95% utilized
-
问题定位:数据库成为主要瓶颈,需优化或扩容。
容量规划公式
# 计算公式
1. 系统容量 = (单机 QPS \* 实例数) / 安全系数
2. 单机 QPS = (CPU 核心数 \* 每核处理能力) / 请求复杂度
3. 安全系数:建议取值 1.5~2,避免资源过载。
示例计算
# 假设单机QPS为10,000,目标QPS为50万
instances_needed = (500000 / 10000) * 1.5 # 考虑安全系数1.5
print(instances_needed) # 输出75台实例
异步解耦提升 TPS
使用 Kafka 异步处理订单
// 发布订单创建事件
@Service
public class OrderService {
@Autowired
private KafkaTemplate<String, OrderCreatedEvent> kafkaTemplate;
public void createOrder(String orderId) {
kafkaTemplate.send("order-created-topic", new OrderCreatedEvent(orderId));
}
}
消费订单事件
@KafkaListener(topics = "order-created-topic")
public void handleOrderCreated(OrderCreatedEvent event) {
paymentService.processPayment(event.getOrderId());
}
三、性能优化策略 🛠️
3.1 数据库优化
分库分表
-- 按用户ID分库分表
CREATETABLE orders_0 (
idBIGINT PRIMARY KEY,
user_id BIGINT,
product_id BIGINT,
amount DECIMAL(10,2)
);
CREATETABLE orders_1 (
idBIGINT PRIMARY KEY,
user_id BIGINT,
product_id BIGINT,
amount DECIMAL(10,2)
);
动态路由
// 根据用户ID路由到对应分片
public String getShardKey(Long userId) {
return "orders_" + (userId % 2); // 假设分为2个分片
}
3.2 缓存优化
Redis 缓存预热
# 提前加载热点商品库存到Redis
def preload_stock(product_id, stock):
redis_client.set(f"stock:{product_id}", stock)
缓存穿透防护
# 缓存空值防止穿透
def get_product_stock(product_id):
stock = redis_client.get(f"stock:{product_id}")
if stock is None:
stock = db.query_stock(product_id)
if stock == 0:
redis_client.setex(f"stock:{product_id}", 60, 0) # 缓存空值1分钟
else:
redis_client.set(f"stock:{product_id}", stock)
return stock
3.3 弹性扩容
配置 HPA(Horizontal Pod Autoscaler)
apiVersion: autoscaling/v2
kind:HorizontalPodAutoscaler
metadata:
name:order-service
spec:
scaleTargetRef:
apiVersion:apps/v1
kind:Deployment
name:order-service
minReplicas:10
maxReplicas:50
metrics:
-type:Resource
resource:
name:cpu
target:
type:Utilization
averageUtilization:70
四、性能对比与总结 📊
4.1 优化前后对比
场景 |
优化前 |
优化后 |
提升率 |
---|---|---|---|
系统 QPS |
10 万 |
50 万+ |
400%↑ |
数据库负载 |
高峰期超载 |
稳定运行 |
40%↓ |
故障恢复时间 |
>5 分钟 |
<30 秒 |
90%↓ |
4.2 总结与建议
1. **提前规划容量**:压测评估峰值流量,预留足够资源。
2. **分层治理流量**:通过限流、降级、熔断保护核心服务。
3. **异步解耦**:减少实时调用链路,提升系统弹性。
4. **监控与告警**:实时监控关键指标,快速响应异常。