使用 Redis 做一个简单的消息队列发送通知邮件

10-17 22:15 字数 1215 阅读 145 已编辑

十七度 “资料设置”里一直有“邮件通知”功能,但是一直没有实现功能,晚上闲来无事,顺手把这个功能做了,记录一下实现过程。

主要是站内通知通过邮件的方式通知用户,比如文章被点赞、有了新粉丝、动态被评论,这些功能不能做成同步的,因为发送邮件比较耗时,所以只能“异步”的实现,RabbitMQ 倒是可以实现,但是太复杂了,还得装软件,所以就使用 Redispushpop 简单的实现了下。

首先在 消息 表入库完成后往 list 里 push 一个 消息ID

Yii::$app->redis->rpush('notification_list', $this->id);

然后新建一个脚本定时的 pop 消息ID 发送邮件即可

$redis = Yii::$app->redis;
// 任务是否正在处理中
$taskRunningFlag = $redis->get('notification_running_flag');
$pendingTaskCount = $redis->llen('notification_list');
if ($taskRunningFlag) {
    exit("任务处理中, 上次未处理任务数: " . $pendingTaskCount . "\n");
}
// 标记任务正在处理中
$redis->set('notification_running_flag', 1);
while (($taskCount = $redis->llen('notification_list')) > 0) {
    $notificationId = $redis->lpop('notification_list');
    // 未找到通知,结束任务
    $notification = Notification::findOne($notificationId);
    if (empty($notification)) {
        $this->stdout("获取通知详情失败, notification_id: {$notificationId} \n");
        continue;
    }
    try {
        // 发送邮件,代码就不写了,很简单
    } catch (\Exception $e) {
        $redis->del('notification_running_flag');
        $this->stdout("发送邮件通知失败:{$e->getMessage()}");
        Yii::debug("发送邮件通知失败:{$e->getMessage()}");
    }
}
// 删除任务正在处理中的标记
$redis->del('notification_running_flag');
exit("任务处理完成, 共处理 {$pendingTaskCount} 条任务\n");

然后新建一个 crontab 任务 每分钟执行一下脚本就行

*/1 * * * * /usr/local/php/bin/php [脚本路径] > /home/crontablogs/notification.log

试了下,没啥大问题,跑的挺happy。

定时任务

1人点赞>
关注 收藏 改进 举报
0 条评论
排序方式 时间 投票
快来抢占一楼吧
请登录后发表评论