消息队列 think-queue + crontab

1、通过composer安装 topthink/think-queue
composer require topthink/think-queue
2、创建队列任务
    /**
     * @title 保存队列工作任务
     * @param array $params
     */
    public function saveJob(array $data)
    {
        $isPushed  = false;
        if (!empty($data)){
            foreach ($data as $key => $value){
                // 配合 crontab 或 supervisor用
                // 1.当前任务将由哪个类来负责处理。
                // 当轮到该任务时,系统将生成一个该类的实例,并调用其 fire 方法
                $jobHandlerClassName  = 'app\sms_service\job\SmsJob';

                // 2.当前任务归属的队列名称,如果为新队列,会自动创建
                $jobQueueName  	  = "SmsJobQueue";

                // 3.当前任务所需的业务数据 . 不能为 resource 类型,其他类型最终将转化为json形式的字符串
                //   ( jobData 为对象时,存储其public属性的键值对 )
                $jobData       	  = [ 'ts' => time(),'bizId' => uniqid(),'list' => $value] ;

                // 4.将该任务推送到消息队列,等待对应的消费者去执行
                // 立即执行
//                $isPushed = Queue::push( $jobHandlerClassName , $jobData , $jobQueueName );
                // 延迟时间10秒
                $run_date = date('Y-m-d H:i:s',strtotime('+10 second'));
                // 延迟执行
                $time2wait = strtotime($run_date) - strtotime("now");
                // database 驱动时,返回值为 1|false  ;   redis 驱动时,返回值为 随机字符串|false
                $isPushed = Queue::later( $time2wait,$jobHandlerClassName , $jobData , $jobQueueName );
            }
        }
		
        return $isPushed;
    }
3、创建 SmsJob 类

*注:类名与位置一定要跟上面定义的一致



namespace app\sms_service\job;

use app\sms_service\model\ImportPhoneLogModel;
use app\sms_service\service\SmsService;
use think\queue\Job;


/**
 * @title 消息队列处理
 * @Class SmsJob
 * @package app\sms_service\job
 */
class SmsJob{

    /**
     * @title fire方法是消息队列默认调用的方法
     * @param Job $job 当前的任务对象
     * @param $data 发布任务时自定义的数据
     * @return void
     */
    public function fire(Job $job,$data){
        // 有些消息在到达消费者时,可能已经不再需要执行了
        $isJobStillNeedToBeDone = $this->checkDatabaseToSeeIfJobNeedToBeDone($data);
        if(!$isJobStillNeedToBeDone){
            $job->delete();
            return;
        }
        // 实际业务处理
        $isJobDone = $this->doSmsJob($data);

        if ($isJobDone) {
            // 如果任务执行成功, 记得删除任务
            $job->delete();
            print("Hello Job has been done and deleted"."\n");
        }else{
            if ($job->attempts() > 3) {
                //通过这个方法可以检查这个任务已经重试了几次了
                print("Hello Job has been retried more than 3 times!"."\n");

                $job->delete();
            }
        }
    }

    /**
     * @title 有些消息在到达消费者时,可能已经不再需要执行了
     * @param $data 发布任务时自定义的数据
     * @return bool 任务执行的结果
     */
    private function checkDatabaseToSeeIfJobNeedToBeDone($data){
        return true;
    }

    /**
     * @title 根据消息中的数据进行实际的业务处理...
     * @param $jobData 储存信息 $jobData['list']
     * @return bool
     * @throws \think\Exception
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     * @throws \think\exception\PDOException
     */
    private function doSmsJob($jobData)
    {
        print("Hello Job"."\n");
        print("Hello Job"."\n");

        return true;
    }
}
4、创建 jobs 表
CREATE TABLE `jobs`  (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `queue` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `payload` longtext CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `attempts` tinyint(3) UNSIGNED NOT NULL,
  `reserved` tinyint(3) UNSIGNED NOT NULL,
  `reserve_time` int(10) UNSIGNED NULL DEFAULT NULL,
  `available_time` int(10) UNSIGNED NOT NULL,
  `create_time` int(10) UNSIGNED NOT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = COMPACT;
5、php全局配置
'queue'                  => [
        'connector' => '\\cmf\\queue\\connector\\Database', // 数据库驱动
        'expire'    => 60,           // 任务的过期时间,默认为60秒; 若要禁用,则设置为 null
        'default'   => 'default',    // 默认的队列名称
        'table'     => 'jobs',       // 存储消息的表名,不带前缀
        'dsn'       => [],
    ],
6、执行任务

*注:执行命令一定要跟上面定义的一致

php think queue:work --queue SmsJobQueue
7、crontab 执行任务

*注:执行命令一定要跟上面定义的一致
*注:/usr/bin/php php安装位置自行修改(find / -name php
*注:/www/wwwroot/项目名/think 项目位置自行修改(find / -name php

*/1 * * * * /usr/bin/php /www/wwwroot/项目名/think queue:work --queue SmsJobQueue
创建、编辑计划任务:

crontab -e

查看当前计划任务:

crontab -l

删除某条计划任务:

crontab -r

说明( * 占位):

minute hour day month week command 顺序:分 时 日 月 周 命令

使用crond设置任务的参数字段说明:
minute 表示分钟,是从0到59之间的任何整数
hour 表示小时,是从0到23之间的任何整数
day 表示日期,是从1到31之间的任何整数
month 表示月份,是从1到12之间的任何整数
week 表示星期,是从0到7之间的任何整数,其中0或7代表星期日
command 要执行的命令,可以是系统命令,也可以是自己编写的脚本文件

查看 crontab 状态:

service crond status

启动服务:

service crond start/

关闭服务:

service crond stop

重启服务:

service crond restart

重新载入配置:

service crond reload

你可能感兴趣的:(数据库,服务器,php)