You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Twilio批量调度十万量级短信时网站卡顿的解决方案求助

Twilio Notify弃用与批量调度短信性能问题解决方案

Twilio Notify弃用说明

Twilio官方宣布:“我们计划于2023年10月23日终止(弃用)Notify产品。”可参考官方迁移指南完成过渡。

Twilio Notify的短信场景可由Twilio SMS API完美替代,该API支持调度最多500,000条消息。

问题描述

用户当前使用的调度代码如下:

$sendAt = (new DateTime())->add(new DateInterval('PT61M'));
$msg= "Hi, Bonanza sale !";
foreach ($sendto_leads as $lead) // $sendto_leads 为所有目标电话号码集合
{
$to=trim($lead['phone']);
$message = $client->messages->create(
$to,
[
"messagingServiceSid" => "###########################",
"body" => $msg,
"sendAt" => $sendAt->format('c'),
"scheduleType" => "fixed",
]
);      
}

该代码在处理10、50、100条号码时运行正常,但处理10000条号码时会出现网站变慢、浏览器长时间加载的情况。

问题核心原因

当前代码采用同步循环调用Twilio API的逻辑,每发送一条短信都需要等待Twilio服务器返回响应后,才会处理下一条请求。10000次同步请求会持续占用Web进程,导致前端请求被阻塞,网站无法及时响应用户操作。

解决方案

1. 将调度任务迁移至后台队列

把短信调度逻辑从Web请求流程中剥离,交给后台队列异步执行:

  • 以Laravel框架为例,可创建独立的短信调度任务类,将目标号码、消息内容、发送时间等参数传入任务,再通过dispatch()方法将任务推入队列。
  • 后台队列进程会异步处理这些任务,Web请求只需触发任务即可立即响应前端,彻底避免页面卡顿。

示例代码(Laravel队列任务):

// 定义队列任务类
class ScheduleSms implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    protected $phoneNumbers;
    protected $message;
    protected $sendAt;

    public function __construct(array $phoneNumbers, string $message, DateTime $sendAt)
    {
        $this->phoneNumbers = $phoneNumbers;
        $this->message = $message;
        $this->sendAt = $sendAt;
    }

    public function handle(Twilio $client)
    {
        foreach ($this->phoneNumbers as $phone) {
            $client->messages->create(
                trim($phone),
                [
                    "messagingServiceSid" => "###########################",
                    "body" => $this->message,
                    "sendAt" => $this->sendAt->format('c'),
                    "scheduleType" => "fixed",
                ]
            );
        }
    }
}

// 在业务逻辑中触发任务
$sendAt = (new DateTime())->add(new DateInterval('PT61M'));
$msg = "Hi, Bonanza sale !";
$phoneNumbers = array_column($sendto_leads, 'phone');

dispatch(new ScheduleSms($phoneNumbers, $msg, $sendAt));

2. 使用异步HTTP请求批量处理

如果不依赖队列框架,可借助Guzzle等HTTP客户端的异步请求功能,同时发起多个API调用,减少整体等待时间:

use GuzzleHttp\Client;
use GuzzleHttp\Promise;

$sendAt = (new DateTime())->add(new DateInterval('PT61M'))->format('c');
$msg = "Hi, Bonanza sale !";
$client = new Client([
    'base_uri' => 'https://api.twilio.com/2010-04-01/',
    'auth' => ['你的Twilio账户SID', '你的Twilio授权令牌'],
]);

$promises = [];
// 控制每批次并发数,避免触发API限流
$batchSize = 50;
$batches = array_chunk($sendto_leads, $batchSize);

foreach ($batches as $batch) {
    foreach ($batch as $lead) {
        $to = trim($lead['phone']);
        $promises[] = $client->postAsync('Accounts/你的Twilio账户SID/Messages.json', [
            'form_params' => [
                'MessagingServiceSid' => '###########################',
                'To' => $to,
                'Body' => $msg,
                'SendAt' => $sendAt,
                'ScheduleType' => 'fixed',
            ]
        ]);
    }
    // 等待当前批次异步请求完成后再处理下一批
    Promise\Utils::unwrap($promises);
    $promises = [];
}

3. 利用Twilio原生批量调度能力

Twilio支持通过API一次性提交多个调度请求,或使用Messaging Service的批量操作功能,大幅减少HTTP请求次数,提升处理效率。可查阅Twilio官方文档了解具体实现方式。

额外优化建议

  • 添加错误捕获:在批量处理逻辑中加入异常捕获,记录发送失败的号码,方便后续重试。
  • 监控API速率:查看Twilio的API速率限制规则,确保请求频率在允许范围内,避免被限流。

内容的提问来源于stack exchange,提问作者Tapas Bera

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 12:12:44