laravel command + crontab 定时任务
有时候需要laravel 结合 系统 crontab 来执行一些定时任务。
首先说下我这里环境:lnmp (ubuntu 16.04 + nginx + mysql5.7 + php7.2) ,laravel 5.5
这里主要内容包括两部分
- laravel command 的使用
- crontab 定时任务
1.laravel command 的使用
首先进入到项目目录,执行以下命令:
[email protected]:/home/wwwroot/www.lt.com$ php artisan make:command generate
Console command created successfully.
[email protected]:/home/wwwroot/www.lt.com$ ls
app bootstrap composer.lock database package.json public resources server.php tests webpack.mix.js
artisan composer.json config gernerate.sql phpunit.xml readme.md routes storage vendor
[email protected]:/home/wwwroot/www.lt.com$ ll
执行成功后,会提示successfuly ,并且会在 app/Console/Commands目录下生成跟命令后参数相同的php文件(这里是generate.php)。
然后打开,刚生成的命令文件(这里是generate.php ,下面不在赘述),可以看到注释已经说的很清楚了
对上面描述的代码做适当修改即可,以下是我修改的:
<?php
namespace App\Console\Commands;
use App\Http\Controllers\GenerateController;
use Illuminate\Console\Command;
class generate extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'generate';
/**
* The console command description.
*
* @var string
*/
protected $description = 'generate data command ';
/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* @return mixed
*/
public function handle()
{
//
$obj = new GenerateController();
$obj->generate();
}
}
$signature 是命令名我这里是generate,$description 是命令描述我这里是generate data command ,handle 方法里编写执行定时任务代码(我这里直接调用以前写的控制器方法往数据库插数据)。
接下来,定位到Kernel.php
<?php
namespace App\Console;
use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
class Kernel extends ConsoleKernel
{
/**
* The Artisan commands provided by your application.
*
* @var array
*/
//这里加入我们新建的命令类
protected $commands = [
//
Commands\generate::class,
];
/**
* Define the application's command schedule.
*
* @param \Illuminate\Console\Scheduling\Schedule $schedule
* @return void
*/
//这里执行调度,我这里是每分钟执行一次,可以自定义
protected function schedule(Schedule $schedule)
{
$schedule->command('generate')
->everyMinute();
}
/**
* Register the commands for the application.
*
* @return void
*/
protected function commands()
{
$this->load(__DIR__.'/Commands');
require base_path('routes/console.php');
}
}
确保无误后,回到控制台,执行 php artisan list ,可以看到之前生成的命令(我这里是generate )
2. 定时任务
上面操确保无误后,就可以使用系统crontab 来执行定时任务了。
输入crontab -e,就可以编辑 crontab
[email protected]:~$ crontab -e
下面是我编辑的crontab 任务
1 # Edit this file to introduce tasks to be run by cron.
2 #
3 # Each task to run has to be defined through a single line
4 # indicating with different fields when the task will be run
5 # and what command to run for the task
6 #
7 # To define the time you can provide concrete values for
8 # minute (m), hour (h), day of month (dom), month (mon),
9 # and day of week (dow) or use '*' in these fields (for 'any').#
10 # Notice that tasks will be started based on the cron's system
11 # daemon's notion of time and timezones.
12 #
13 # Output of the crontab jobs (including errors) is sent through
14 # email to the user the crontab file belongs to (unless redirected).
15 #
16 # For example, you can run a backup of all your user accounts
17 # at 5 a.m every week with:
18 # 0 5 * * 1 tar -zcf /var/backups/home.tgz /home/
19 #
20 # For more information see the manual pages of crontab(5) and cron(8)
21 #
22 # m h dom mon dow command
23 */1 * * * * php /home/wwwroot/www.lt.com/artisan schedule:run >>/dev/null 2>&1
上面第23行的意思是:每分钟( */1 是每分钟 )让php 执行/home/wwwroot/www.lt.com/这个目录下任务调度并把标准输出和标准错误输入重定向到/dev/null 这个空设备下。
然后保存退出。crontab - l 即可看到我们刚添加进去的定时任务。
ok,现在去验证下,看定时任务有没有按照计划执行,我这里编写的定时任务是每分钟往数据库表插10条数据。
mysql> select now();
+---------------------+
| now() |
+---------------------+
| 2018-10-20 10:22:42 |
+---------------------+
1 row in set (0.00 sec)
mysql> select count(*) from dye_production_schedules;
+----------+
| count(*) |
+----------+
| 650 |
+----------+
1 row in set (0.00 sec)
mysql> select now();
+---------------------+
| now() |
+---------------------+
| 2018-10-20 10:24:01 |
+---------------------+
1 row in set (0.00 sec)
mysql> select count(*) from dye_production_schedules;
+----------+
| count(*) |
+----------+
| 670 |
+----------+
1 row in set (0.00 sec)
可见,已正常执行定时任务!
不知道,你会不会和我有一样的想法 -- 感觉laravel command 很鸡肋,因为laravel 定时任务是依赖于 crontab 来实现的,我即便不使用 laravel command (直接使用请求url 方式也可以实现),甚至可以不使用 laravel 都可以结合实现定时任务。
那为什么要用laravel command 呢? 直到我发现 command 任务钩子,顿时觉得蛮强大的,可以实现一些复杂的需求,不过一些简单的定时任务也确实没必要使用laravel command 。
至于,laravel command 更详细的资料,这里我推荐参考这篇文章:https://laravelacademy.org/post/8484.html。