PHP 使用 Redis 来做队列服务

为客户端开发 Api,采用 PHP,我们使用了一个叫做 Swoole_framework 的框架,同时使用了 swoole 扩展。在开发接口时使用了框架提供的模型类,但是,服务端除了接口,不可避免还有一些后台脚本,比如每日任务初始化,用户分数结算,后台脚本直接 require 相关配置文件,然后手动 update 数据库数据。这两天做需求的时候就发现,有些业务逻辑在服务端 api 层需要实现,在后台脚本里面也要实现,而这两处的代码不能复用,因此同样地逻辑处理了两遍,随着后续功能的增加,重复的代码还会增加。上周因为比较急就先采用这种方法完成了代码,实现了功能,这两天测试联调,总感觉同样地逻辑在多个地方出现,不仅写代码时麻烦,测试时也麻烦,下午灵光一现想到可以使用任务队列来完成这个工作。

简单来说,就是在原先逻辑处理的地方,只是简单增加一个任务,不再进行具体的业务逻辑,后台脚本和 api 都如此,然后再单独跑一个脚本,拉取任务,进行业务逻辑处理。这个的思路好处很明显,同样地逻辑归到了一处,开发以及调试找错时会清晰很多。

需要实现一个任务队列,使用 redis ,简单封装了一个队列:

<?php

class Queue
{
    protected $redis;
    protected $key;

    public function __construct(\Redis $redis, $key)
    {
        $this->redis = $redis;
        $this->key = $key;
    }

    public function pop()
    {
        return $this->redis->lPop($this->key); // 左边出
    }

    public function push($task)
    {
        return $this->redis->rPush($this->key, $task); // 右边入
    }
}

队列的一个特点就是先进先出(FIFO),很显然,先产生的任务需要被先处理,redis 的 List 可以保证这一点。

晚上将代码重新组织,用任务队列加单独脚本的方式实现了需要的业务功能,顿时感觉浑身舒畅了许多。