环境:MySQL
表结构
[test] > CREATE TABLE `sms_message_log` (
`id` int NOT NULL AUTO_INCREMENT,
`message_id` varchar(64) DEFAULT NULL,
`task_id` varchar(64) DEFAULT NULL,
`phone_number` varchar(64) DEFAULT NULL,
`status` varchar(64) DEFAULT NULL,
`callback_time` varchar(64) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `uniq_1` (`message_id`,`task_id`,`phone_number`)
) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
这里演示对表结构做了一些简化,实际上还应该有一些其它字段(例如发送失败的原因等)。提交发短信任务的时候,会将推送给三方的这些手机号等基础信息批量写到 sms_message_log 表里,类似如下:
[test] > select * from sms_message_log ;
+----+------------+---------+--------------+--------+---------------+
| id | message_id | task_id | phone_number | status | callback_time |
+----+------------+---------+--------------+--------+---------------+
| 1 | 1111 | 2222 | 13141516888 | 0 | |
| 3 | 1111 | 22222 | 13141516888 | 0 | |
| 4 | 999 | 333 | 13141516888 | 0 | |
+----+------------+---------+--------------+--------+---------------+
3 rows in set (0.00 sec)然后,第三方会把处理后的结果返回来(可能需要一段时间)。
这种情况下,可以将三方的回调信息先写入到mq中,然后在消费数据insert/update到 sms_message_log 表里。
但是默认情况下是逐条的UPDATE(即使使用 ON DUPLICATE KEY UPDATE),在高并发场景下仍然可能成为瓶颈。
这种情况下,可以使用下面的优化方案:
每个消费者从mq拉取回调数据后,先缓存在内存(如List/Queue),而不是直接写库。当缓冲达到一定数量(如1000条)或时间窗口(如5秒)时,一次性批量写入数据库。
批量写入SQL例子如下:
[test] > INSERT INTO sms_message_log (message_id, task_id, phone_number, status, callback_time)
VALUES
('1111','2222','13141516888','1','2025-08-06 16:11:29'),
('1111','22222','13141516888','1','2025-08-06 16:11:29'),
('999','333','13141516888','0','2025-08-06 16:11:29')
ON DUPLICATE KEY UPDATE
status = VALUES(status),
callback_time = VALUES(callback_time);这时,数据库状态如下
[test] > select * from sms_message_log ;
+----+------------+---------+--------------+--------+---------------------+
| id | message_id | task_id | phone_number | status | callback_time |
+----+------------+---------+--------------+--------+---------------------+
| 1 | 1111 | 2222 | 13141516888 | 1 | 2025-08-06 16:11:29 |
| 3 | 1111 | 22222 | 13141516888 | 1 | 2025-08-06 16:11:29 |
| 4 | 999 | 333 | 13141516888 | 0 | 2025-08-06 16:11:29 |
+----+------------+---------+--------------+--------+---------------------+
3 rows in set (0.00 sec)
这种设计方案算是比较简单和通用的。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。