这是我参与8月更文挑战的第5天,活动详情查看:8月更文挑战
前言
定时任务在实际业务中经常用到,例如未支付订单超时取消,定时清理日志等。上一个项目是一个自动售货机,需要调用物联网设备,偶尔会有信号不好导致设备启动信号发出之后,接收不到设备启动信息,需要主动查询设备启动情况,启动成功将订单标记成功,失败的需要给用户退款。
初期是做了一个http接口,通过crontab定时调用触发,定期处理异常订单,但是当订单体量增大,任务执行时间增长,有时候会阻塞业务。后来改成了php命令行执行,满足了业务需求。
一、crontab
crontab 是用来让使用者在固定时间或固定间隔执行程序之用,也就是类似使用者的时程表。
定义格式如下:
minute hour day month week command
minute
分钟,范围0-59。hour
小时,范围0-23。day
每月几号,范围1-31。month
月份,范围1-12。week
一周的第几天,范围0-7,0和7都是周日。command
执行的命令。
当 minute
为 5
表示每五分钟执行一次 command
;当值为 *
表示每个时间单位都执行一次;可以用,
隔开多个值,例如2,5,10
表示设定时间内的2分,5分,10分执行命令;可以用-
隔开两个值,例如10-20
设定时间内的第10分开始到20分结束每分钟执行一次命令;*/15
表示每15分钟执行一次命令。其余单位设置方式相同。
举例:
-
每天上午10点-12点,每半个小时执行一次命令
*/30 10-12 * * *
-
每年的5月1日和10月1日凌晨2点执行一次命令
0 2 1 5,10 *
二、ThinkPHP命令行指令
1. 创建项目
composer create-project topthink/think command-demo
cd command-demo
进入项目目录,接着执行 php think
,如果没有配置php环境变量可以使用绝对路径,例如/usr/local/php/bin/php think
。如果打印出类似如下内容说明项目安装成功。
2. 创建自定义命令
php think make:command OrderCheckCommand ordercheck
上面命令的意思是在app/command/
目录下 创建一个OrderCheckCommand.php
php类文件,命令名称叫做ordercheck
。
3. 注册指令
找到config/console.php
文件,添加如下代码:
<?php
return [
// 指令定义
'commands' => [
'ordercheck' => 'app\command\OrderCheckCommand'
],
];
试着执行命令 php think ordercheck
如果看到如下输出,则命令创建成功。
4. 指令说明
打开app/command/OrderCheckCommand.php
-
其中
configure
方法是对指令的配置setName
设置指令名称;setDescription
设置指令描述内容;addArgument
设置指令参数;addOption
设置指令选项。 -
execute
当执行命令时会执行execute
中逻辑。
5. 编写业务指令
创建一个伪需求:指令接收一个订单状态参数,其中1是异常订单,需校验订单实际状态,2只查询失败订单,给用户退款;接收一个省份选项,如果输入省份则只处理某个省份的订单。
修改代码如下:
class OrderCheckCommand extends Command {
protected function configure() {
// 指令配置
$this->setName('ordercheck')
// Argument::OPTIONAL->可选参数 Argument::REQUIRED->必填参数 Argument::IS_ARRAY->数组参数
->addArgument('status', Argument::OPTIONAL, '订单状态', 1)
->addOption('province', 'p', Option::VALUE_REQUIRED, '订单所属省份', 'beijing')
->setDescription('the ordercheck command');
}
protected function execute(Input $input, Output $output) {
$status = intval($input->getArgument('status'));
$statusText = $status == 1 ? '订单状态为异常订单,进行订单实际状态校验' : '订单状态失败订单,退款给用户';
if ($input->hasOption('province')) {
$pre = '处理' . $input->getOption('province') . '订单;';
} else {
$pre = '处理全国订单;';
}
// 记录执行日志
Log::info($pre . $statusText);
// 指令输出
$output->writeln($pre . $statusText);
}
}
addArgument
接收四个参数,分别是名称、类型、描述、默认值;类型可选值分别为 Argument::OPTIONAL(可选参数)
、Argument::REQUIRED(必填参数)
、Argument::IS_ARRAY(数组参数)
。
addOption
接收五个参数,分别是选项名称、别名(简写选项名)、类型、描述、默认值,其中类型可选值分别是Option::VALUE_NONE(无需传值)
、Option::VALUE_REQUIRED(必须传值)
、Option::VALUE_OPTIONAL(可选传值)
、Option::VALUE_IS_ARRAY(传数组值)
。
6. 测试指令
三、结合crontab部署定时任务
假设需要一个定时任务,每2分钟查询省份为beijing
的失败订单给用户退款,我们需要执行的命令就是:
php think ordercheck 2 -p beijing
当命令写到crontab中需要写项目的绝对路径,最终crontab写入内容如下:
*/2 * * * * php /home/www/command-demo/think ordercheck 2 -p beijing
首先执行crontab -e
,添加上面内容,保存。
接着执行systemctl restart crond.service
,重启crontab。
等待几分钟之后查看日志,看命令是否执行。
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!