Skip to content

队列

队列一般应用于异步处理,应用解耦,流量削锋和消息通讯等场景。

说明

Yii-Queue提供了File, DB, Redis, RabbitMQ, AMQP, Beanstalk, ActiveMQ 和 Gearman等队列模型,为了简化安装,DZ-SHOP目前在安装时仅支持File、DB和Redis队列配置。如果需要其它的队列模式,请参考队列文档

特别注意

由于队列的执行方式不同,即使通过安装程序配置了队列,队列是不会自动执行的,需要手动配置队列的执行方式,请参考下面的“执行队列”。

DZ-SHOP目前的队列应用如下:

  • 写日志
  • 物流通知
  • 邮件发送
  • 短信发送
  • 分销升级
  • 公众号模板推送

提示

队列并不是必须的,在不开启队列的情况下,具体任务会在进程内直接执行。DZ-SHOP对于并发小于1000的应用来说,启用队列没有太大的实际意义。

创建队列

DZ-SHOP的队列任务统一在common/queues中。

每个被发送到队列的任务应该被定义为一个单独的类。 例如,如果您需要下载并保存一个文件,该类可能看起来如下:

php
class DownloadJob extends BaseObject implements \yii\queue\JobInterface
{
    public $url;
    public $file;
    
    public function execute($queue)
    {
        file_put_contents($this->file, file_get_contents($this->url));
    }
}

下面是将任务添加到队列:

php
Yii::$app->queue->push(new DownloadJob([
    'url' => 'http://example.com/image.jpg',
    'file' => '/tmp/image.jpg',
]));

将作业推送到队列中延时5分钟运行:

php
Yii::$app->queue->delay(5 * 60)->push(new DownloadJob([
    'url' => 'http://example.com/image.jpg',
    'file' => '/tmp/image.jpg',
]));

执行队列

队列的执行分为准实时模式和定时任务模式。准实时模式的处理速度在秒级(或毫秒级),定时任务模式则每分钟处理一次。

准实时模式

使用控制台

在控制台进入DZ-SHOP文件夹执行如下命令,启动一个守护进程,它可以无限查询队列。如果有新的任务,他们立即得到并执行:

bash
# timeout 是下一次查询队列的时间
php yii queue/listen [timeout]

由于PHP的特性,控制台进程可能会因为各种原因在一段时间后崩溃而无法执行。因此我们建议在生产环境下使用supervisor或使用systemd来实现守护进程,确保队列进程的正确执行。

使用supervisor(推荐)

supervisor 是Linux的进程监视器。它会自动启动您的控制台进程。如果使用“宝塔”,可以在“宝塔”内直接安装supervisor。也可以直接使用如下命令安装supervisor:

bash
sudo apt-get install supervisor

supervisor 配置文件通常可用 /etc/supervisor/conf.d。 你可以创建任意数量的配置文件。

配置示例:

bash
[program:dz-shop-queue]
process_name=%(program_name)s_%(process_num)02d
command=/usr/bin/php /你的部署文件夹/yii queue/listen --verbose=1 --color=0
autostart=true
autorestart=true
user=www-data
numprocs=4
redirect_stderr=true
stdout_logfile=/var/www/my_project/log/dz-shop-queue.log

在这种情况下,supervisor 会启动4个 queue/listen worker。输出将写入相应日志文件。有关 supervisor 配置和使用的更多信息,请参阅文档

使用systemd

Systemd 是linux启动引导文件,可以在/etc/systemd/system中创建一个dz-shop-queue@.service的配置项,包含以下内容:

bash
[Unit]
Description=Dz Shop Queue %I
After=network.target
# the following two lines only apply if your queue backend is mysql
# replace this with the service that powers your backend
After=mysql.service
Requires=mysql.service

[Service]
User=www-data
Group=www-data
ExecStart=/usr/bin/php /你的部署文件夹/yii queue/listen --verbose
Restart=on-failure

[Install]
WantedBy=multi-user.target

重新加载配置:

bash
systemctl daemon-reload

以下是相关进程命令:

bash
# 开始2个进程
systemctl start dz-shop-queue@1 dz-shop-queue@2

# 获取进程状态
systemctl status "dz-shop-queue@*"

# 停止工作进程
systemctl stop dz-shop-queue@2

# 停止所有进程
systemctl stop "dz-shop-queue@*"

# 系统启动时开始2个进程
systemctl enable dz-shop-queue@1 dz-shop-queue@2

有关 systemd 配置和使用的更多信息,请参阅文档

定时任务模式

可以用cron开始worker。需要使用 queue/run 命令。只要队列包含作业,它就能进行执行。

只需要在 /你的部署文件夹/console/schedule.php添加如下代码即可每分钟执行一次队列:

php
$schedule->command('queue/run')->everyMinute()->sendOutputTo($path . 'queue.log');

广州大舟信息科技 版权所有