本文介紹如何實(shí)現(xiàn)前臺(tái)觸發(fā)后臺(tái)異步批量發(fā)送短信,且不影響用戶體驗(yàn)。 用戶點(diǎn)擊按鈕后,前臺(tái)立即返回成功提示,后臺(tái)則異步執(zhí)行數(shù)據(jù)庫查詢、redis緩存寫入和短信發(fā)送。
核心思路:異步處理
該方案利用異步處理機(jī)制,將耗時(shí)操作移至后臺(tái)執(zhí)行,避免阻塞前臺(tái)。 具體步驟如下:
-
前臺(tái)ajax請(qǐng)求: 用戶點(diǎn)擊發(fā)送按鈕,前端使用Ajax向后臺(tái)發(fā)送請(qǐng)求,請(qǐng)求參數(shù)包含短信模板ID、手機(jī)號(hào)列表和短信內(nèi)容。
$.ajax({ url: '/send-sms', type: 'POST', data: { template_id: 123, mobiles: ['13800138000', '13800138001'], content: '測(cè)試短信' }, success: function(response) { alert('短信發(fā)送請(qǐng)求已提交'); }, error: function(error) { alert('請(qǐng)求失敗:' + error.responseText); } });
-
后臺(tái)接收請(qǐng)求并返回響應(yīng): 后臺(tái)接收Ajax請(qǐng)求后,立即返回成功響應(yīng)(json格式),告知前臺(tái)請(qǐng)求已接收。 關(guān)鍵在于,短信發(fā)送邏輯被放入異步任務(wù)中。
// 后臺(tái)控制器方法 public function sendSmsAction() { $templateId = $_POST['template_id']; $mobiles = $_POST['mobiles']; $content = $_POST['content']; // 立即返回成功響應(yīng) echo json_encode(['success' => true, 'message' => '請(qǐng)求已接收,短信發(fā)送任務(wù)已啟動(dòng)']); // 將任務(wù)添加到隊(duì)列(例如使用redis或rabbitmq) $this->addTaskToQueue($templateId, $mobiles, $content); }
-
異步任務(wù)處理: addTaskToQueue 方法將短信發(fā)送任務(wù)添加到消息隊(duì)列中。 一個(gè)獨(dú)立的后臺(tái)進(jìn)程(例如使用隊(duì)列工作者)持續(xù)監(jiān)聽隊(duì)列,取出任務(wù)并執(zhí)行。
// 添加任務(wù)到隊(duì)列 (示例使用redis) private function addTaskToQueue($templateId, $mobiles, $content) { $redis = new Redis(); $redis->connect('127.0.0.1', 6379); $redis->lPush('sms_queue', json_encode(['template_id' => $templateId, 'mobiles' => $mobiles, 'content' => $content])); }
-
隊(duì)列工作者: 隊(duì)列工作者從 sms_queue 隊(duì)列中獲取任務(wù),執(zhí)行短信發(fā)送,并處理錯(cuò)誤日志。
// 隊(duì)列工作者 (示例) while (true) { $task = $redis->rPop('sms_queue'); if ($task) { $data = json_decode($task, true); $result = $this->sendSms($data['template_id'], $data['mobiles'], $data['content']); if ($result !== true) { // 記錄錯(cuò)誤日志 error_log("短信發(fā)送失敗: " . $result); } } sleep(1); // 避免CPU占用過高 }
-
短信發(fā)送函數(shù) (sendSms): 該函數(shù)調(diào)用短信服務(wù)商API發(fā)送短信。
通過以上步驟,前臺(tái)用戶體驗(yàn)不受影響,后臺(tái)則高效地處理批量短信發(fā)送。 選擇合適的隊(duì)列系統(tǒng)(Redis、RabbitMQ、Beanstalkd等)至關(guān)重要,它能保證任務(wù)可靠地被處理,并支持分布式環(huán)境。 此外,完善的錯(cuò)誤處理和日志記錄機(jī)制也必不可少。