1. 项目背景与核心需求
短信批量发送接口是当前企业级应用中不可或缺的基础功能模块。从电商平台的订单通知到金融行业的验证码下发,从政务系统的政策宣贯到物流行业的配送提醒,高并发批量短信发送能力直接关系到业务流程的顺畅度和用户体验。
在实际业务场景中,我们经常遇到这样的需求:
- 会员营销场景:需要向10万+用户发送促销信息
- 系统告警场景:需要在1分钟内完成上千条告警通知的发送
- 验证码场景:需要应对瞬时爆发的验证码请求
这些场景对短信接口提出了三个核心要求:
- 高并发处理能力(通常需要支持1000+ TPS)
- 稳定的送达率(商业场景要求99%以上)
- 可监控的发送状态(需要实时获取发送状态报告)
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 技术架构设计
2.1 整体架构方案
我们采用分层架构设计,将系统划分为四个核心层次:
code复制[客户端] → [API网关层] → [消息队列层] → [发送引擎层] → [运营商通道]
这种架构的优势在于:
- 各层职责分离,便于独立扩展
- 通过队列削峰填谷,应对流量波动
- 失败重试机制保障送达率
2.2 关键组件选型
消息队列选型
对比了RabbitMQ、Kafka和RocketMQ后,我们选择RocketMQ,主要基于:
- 消息堆积能力(支持亿级消息堆积)
- 分布式事务支持(适合金融级场景)
- 完善的监控体系(自带控制台)
配置示例:
java复制// RocketMQ生产者配置
DefaultMQProducer producer = new DefaultMQProducer("SMS_Producer_Group");
producer.setNamesrvAddr("192.168.1.100:9876");
producer.setRetryTimesWhenSendFailed(3);
producer.start();
数据库选型
采用MySQL+Redis组合:
- MySQL:存储发送记录(InnoDB集群部署)
- Redis:缓存模板和频控数据(Cluster模式)
注意:短信内容需要加密存储,符合GDPR等数据合规要求
3. 高并发实现方案
3.1 流量控制设计
我们实现了三级流量控制机制:
- 用户级限流:每个账号每分钟不超过300条
- 模板级限流:热点模板单独限流
- 通道级限流:根据通道质量动态调整
Redis实现示例:
python复制def check_rate_limit(user_id):
key = f"sms:limit:{user_id}"
current = redis.incr(key)
if current == 1:
redis.expire(key, 60)
return current <= 300
3.2 批量发送优化
针对批量发送场景,我们采用以下优化策略:
- 消息合并:将相同模板的短信合并发送
- 异步处理:客户端无需等待发送完成
- 压缩传输:对内容进行GZIP压缩
性能对比:
| 优化策略 | 单机吞吐量(TPS) | 网络带宽占用 |
|---|---|---|
| 原始方案 | 800 | 100% |
| 优化后 | 3500 | 30% |
4. 稳定性保障措施
4.1 通道管理策略
我们维护了通道质量评分体系:
- 成功率权重:50%
- 延迟权重:30%
- 成本权重:20%
动态路由算法伪代码:
python复制def select_channel(sms_type):
channels = get_available_channels(sms_type)
channels.sort(key=lambda x:
x.success_rate*0.5 +
(1-x.avg_delay/1000)*0.3 +
(1-x.cost)*0.2
)
return channels[0]
4.2 失败重试机制
重试策略配置:
- 首次失败:立即重试
- 第二次失败:5秒后重试
- 第三次失败:进入死信队列
重要提示:验证码类短信不应过多重试,防止被利用
5. 监控与统计实现
5.1 实时监控看板
我们基于Prometheus+Grafana搭建监控系统,关键指标包括:
- 发送成功率(按通道、模板维度)
- 平均延迟(P50/P95/P99)
- 系统吞吐量(TPS)
监控指标示例:
prometheus复制# 发送成功率指标
sms_delivery_success_rate{channel="cmcc"} 0.9923
sms_delivery_success_rate{channel="cucc"} 0.9876
# 延迟指标
sms_delivery_latency_bucket{le="100"} 4231
sms_delivery_latency_bucket{le="500"} 8765
5.2 统计分析报表
每日生成以下报表:
- 发送量TOP10模板
- 失败原因分布
- 通道质量对比
6. 安全防护方案
6.1 防攻击措施
我们实施了多重防护:
- 图形验证码:敏感操作前验证
- 行为分析:识别异常发送模式
- IP黑白名单:限制访问来源
6.2 内容安全审核
采用三级审核机制:
- 关键字过滤(敏感词库)
- 模板预审(人工审核)
- 实时抽检(AI审核)
7. 对接实现示例
7.1 RESTful API设计
发送接口规范:
code复制POST /api/v1/sms/batch
Headers:
X-API-Key: [授权密钥]
Content-Type: application/json
Body:
{
"template_id": "TPL_ORDER_PAID",
"receivers": [
{
"mobile": "13800138000",
"params": {"order_no":"123456"}
}
],
"send_time": "2023-08-20 14:00:00"
}
7.2 SDK封装示例
Java SDK核心方法:
java复制public class SmsClient {
private static final String API_ENDPOINT = "https://sms-api.example.com";
public BatchResult sendBatch(List<SmsRequest> requests) {
// 实现签名生成、重试逻辑等
}
// 使用示例
public static void main(String[] args) {
SmsClient client = new SmsClient("your_api_key");
List<SmsRequest> requests = Arrays.asList(
new SmsRequest("13800138000", "TPL_ORDER",
ImmutableMap.of("orderNo", "123456"))
);
BatchResult result = client.sendBatch(requests);
}
}
8. 性能压测数据
我们使用JMeter进行了压力测试,关键数据:
| 场景 | 并发用户数 | 平均TPS | 错误率 | 平均延迟(ms) |
|---|---|---|---|---|
| 单模板发送 | 500 | 3421 | 0.02% | 143 |
| 多模板混合 | 1000 | 4987 | 0.15% | 217 |
| 峰值压力 | 3000 | 6823 | 1.2% | 498 |
优化建议:
- 当并发超过2000时,建议增加API网关节点
- 错误率超过0.5%时应触发告警
- 延迟超过500ms需要优化通道选择
9. 常见问题解决方案
9.1 发送状态延迟
问题现象:状态报告延迟超过5分钟
排查步骤:
- 检查运营商状态回执接口
- 验证消息队列消费延迟
- 查看数据库写入性能
9.2 通道切换抖动
问题现象:切换通道时成功率短暂下降
解决方案:
- 实现平滑切换(新老通道并行)
- 设置切换缓冲期(至少5分钟)
- 预热新通道(逐步增加流量)
10. 实际部署建议
10.1 服务器配置
生产环境推荐配置:
- API节点:4C8G × 3(负载均衡)
- 队列节点:8C16G × 2(RocketMQ)
- 数据库:MySQL 8C32G 主从集群
10.2 灾备方案
我们建议采用多AZ部署:
- 主备消息队列同步
- 数据库跨机房复制
- 通道多运营商冗余
在具体实施过程中,我们发现三个关键经验:
- 预付费通道需要余额监控,建议设置阈值告警
- 节假日流量高峰前,应提前扩容50%资源
- 通道质量会随时间变化,需要每月重新评估
