digiservnet / cron
Laravel 的任务调度
Requires
- php: >=5.3.0
- dragonmantank/cron-expression: 2.*
Requires (Dev)
- illuminate/support: 4.0.x|~5.0
README
Laravel 的任务调度
Cron 可以轻松地在 Laravel 中执行 cron 任务。如果您想从互联网或只是从本地计算机运行任务,Cron 可以帮助您。有关 Cron 如何简化任务调度的更多信息,请参阅 raison d'être。
- 主页: https://liebig.github.io/cron/
- Github: https://github.com/liebig/cron/
- API: http://liebig.github.io/cron/docs/api/classes/Liebig.Cron.Cron.html
raison d’être
简单性
目标是创建一种简单的方法来使用 Laravel 定义 cron 任务。使用 Cron 创建 cron 任务非常简单,因为该工具提供大量事件,您可以使用这些事件来管理所有任务。要创建任务,您只需要一个任务名称、一个 cron 表达式以及一个在时间到来时将被调用的函数。当然,只有在您调用它时 PHP 才会运行,因此您需要一些附加内容来启动 Cron。
可访问性
Cron 启动调用可以从与 Laravel 相同的机器(例如使用 crontab)执行,也可以从互联网上的任何地方(例如使用 web cron 服务)执行 - 它只是一个命令执行或路由调用。
集中化
Cron 管理在您的应用程序中集中在一个点上。您在 PHP 中定义所有任务,不需要使用其他工具。禁用或删除 Cron 任务只需要一个 PHP 函数调用。
平台独立性
Laravel 是构建小型和大中型 Web 应用的好方法。但并非每个应用平台都运行在允许 Unix Shell 访问的服务器上。对于这些应用,Cron 提供了使用外部 Web Cron 服务启动 Cron 的可能性。如果您有 shell 访问权限 - 那太好了,您可以使用 Cron 的命令来启动任务管理。
监控
如果您的任务出现错误,Cron 将通知您。除了记录到 Monolog、Laravel 日志记录功能和数据库外,您还可以添加事件监听器以获取有关错误任务或成功执行的任务的信息。执行后,您将收到关于 Cron 运行的详细报告。利用 PHP 和事件的力量,您可以在发生任何事情时发送邮件、通知或其他内容。Cron 像您的祖母一样健谈。
我的个人舒适区
最后,Cron 是我管理任务调度的个人方式。我是一个网络应用开发者,不是基础设施专家。我喜欢用 PHP 而不是在 shell 中处理事情。我想将我的应用程序部署到另一台服务器,而不用担心是否有访问 crontab 或其他 Linux 工具的权限。我真的很喜欢 Laravel 的事件功能,但不怎么喜欢 Laravel 命令。Cron 管理应该既简单又强大。最后,我喜欢在一个地方处理我的应用程序中的事情,而不用使用 shell 或为每个工作写一个 PHP 文件。Cron 是尝试无烦恼地管理 cron 作业的尝试。
安装
Laravel 5
- 将
"liebig/cron": "dev-master"
添加到您的/path/to/laravel/composer.json
文件的"require":
部分(了解更多关于 composer 的信息,请访问 https://getcomposer.org.cn/) - 在您的
/path/to/laravel/
目录中运行composer update liebig/cron --no-dev
命令 - 如果您使用的是 Laravel 5.4 或更早版本,请在
/path/to/laravel/config/app.php
文件中的'providers'
数组中添加'Liebig\Cron\Laravel5ServiceProvider'
- 运行命令
php artisan migrate --path=vendor/liebig/cron/src/migrations
以迁移数据库 - 运行命令
php artisan vendor:publish
发布配置文件 - 现在您可以在/path/to/laravel/config/liebigCron.php
找到 Cron 配置文件,并且此文件在任何更新中都不会被覆盖 - 现在您可以在任何地方免费使用
Cron
Laravel 4
- 将
"liebig/cron": "dev-master"
添加到您的/path/to/laravel/composer.json
文件的"require":
部分(了解更多关于 composer 的信息,请访问 https://getcomposer.org.cn/) - 在您的
/path/to/laravel/
目录中运行composer update liebig/cron --no-dev
命令 - 在
/path/to/laravel/app/config/app.php
文件中的'providers'
数组中添加'Liebig\Cron\CronServiceProvider'
- 运行命令
php artisan migrate --package="liebig/cron"
以迁移数据库 - 运行命令
php artisan config:publish liebig/cron
发布配置文件 - 现在您可以在/path/to/laravel/app/config/packages/liebig/cron
找到 Cron 配置文件,并且此文件在任何更新中都不会被覆盖 - 现在您可以在任何地方免费使用
Cron
配置
Cron 是设计成即插即用的,无需配置。为此,设置了一些默认值。要更改 Cron 的默认设置,有两种可能性。
设置方法
您可以使用 Cron 的设置方法(例如 setDatabaseLogging
,setRunInterval
)来更改 Cron 的行为。这些更改是临时的,并且必须每次都调用设置方法。
配置文件
行为值将从配置文件中加载。您可以通过在 Laravel 5 中编辑 /path/to/laravel/app/config/liebigCron.php
文件以及在 Laravel 4 中编辑 /path/to/laravel/app/config/packages/liebig/cron/config.php
文件来轻松更改这些值。这是一种更持久的方法。如果您只想在具有条件的情况下更改一次设置,我们建议使用设置方法。
注意:通过方法设置的所有值将覆盖从配置文件加载的值。
示例
Cron
如果您使用 Cron 集成的路由或命令,您只需要监听 cron.collectJobs
事件。在 Laravel 5 中,最佳做法是在 /path/to/laravel5/app/Providers/AppServiceProvider.php
文件的 boot
方法中执行此操作,在 Laravel 4 中是在 /path/to/laravel/app/start/global.php
文件中。
Laravel 5 - AppServiceProvider.php
<?php namespace App\Providers; use Illuminate\Support\ServiceProvider; class AppServiceProvider extends ServiceProvider { //... /** * Bootstrap any application services. * * @return void */ public function boot() { // Please note the different namespace // and please add a \ in front of your classes in the global namespace \Event::listen('cron.collectJobs', function() { \Cron::add('example1', '* * * * *', function() { // Do some crazy things unsuccessfully every minute return 'No'; }); \Cron::add('example2', '*/2 * * * *', function() { // Do some crazy things successfully every two minute return null; }); \Cron::add('disabled job', '0 * * * *', function() { // Do some crazy things successfully every hour }, false); }); } }
Laravel 4 - global.php
Event::listen('cron.collectJobs', function() { Cron::add('example1', '* * * * *', function() { // Do some crazy things unsuccessfully every minute return 'No'; }); Cron::add('example2', '*/2 * * * *', function() { // Do some crazy things successfully every two minute return null; }); Cron::add('disabled job', '0 * * * *', function() { // Do some crazy things successfully every hour }, false); });
在匿名函数内部,您可以使用所有 Laravel 和 Cron 函数。在下一步中,您必须配置启动 Cron 的路由或命令。
使用 Cron 集成的路由
如果您没有对服务器的 shell 访问权限,您可以使用在线 cronjob 服务(Google 知道一些好的提供商)。此提供商将在定义的间隔运行 Cron 的路由。Cron 路由必须受保护,因为如果除了服务提供商之外的其他人调用它,我们的作业将被执行得太频繁。因此,我们需要一个安全密钥,除了路由路径外还需要这个密钥。您可以使用 php artisan cron:keygen
命令调用生成此密钥,并将其设置在 Cron 配置文件中的 cronKey
键中。
// Cron application key for securing the integrated Cron run route - if the value is empty, the route is disabled 'cronKey' => '1PBgabAXdoLTy3JDyi0xRpTR2qNrkkQy'
现在您需要在您的在线cron作业服务提供商处配置地址和运行间隔。集成Cron路由的地址始终是 http://yourdomain.com/cron.php?key=securitykey
。对于上述示例,此地址可以是 http://exampledomain.com/cron.php?key=1PBgabAXdoLTy3JDyi0xRpTR2qNrkkQy
,运行间隔必须是每分钟(由于名为“example1”的作业)。现在已添加作业,生成了路由密钥,并已配置服务提供商。
使用Cron的集成命令
如果您的托管提供商为您提供shell访问或您可以使用控制面板软件(例如cPanel或Plesk)管理cron作业,则运行Cron的最佳方式是使用集成的 artisan cron:run
命令。对于上述示例,crontab或控制面板软件命令可以是 * * * * * /usr/bin/php /var/www/laravel/artisan cron:run
。
注意:如果您想使用Cron的时间检查,该检查将测试两次Cron运行方法调用之间的时间是否正确,请配置密钥 runInterval
。在我们的示例中,我们每分钟调用一次路由,因此值应该是 1
。
API
添加 cron 任务
通过使用静态 add 函数轻松将cron作业添加到Cron。作为参数需要cron作业的 名称、cron 表达式 和一个匿名 函数。布尔值 isEnabled 是可选的,可以启用或禁用此cron作业的执行(默认为启用)。
public static function add($name, $expression, $function, $isEnabled = true) {
需要 名称 来识别cron作业,如果出现错误则用于记录。
表达式是一个字符串,包含五个或六个可选的子表达式,描述了计划的详细信息。语法基于Linux cron守护进程定义。
* * * * * *
- - - - - -
| | | | | |
| | | | | + year [optional]
| | | | +----- day of week (0 - 7) (Sunday=0 or 7)
| | | +---------- month (1 - 12)
| | +--------------- day of month (1 - 31)
| +-------------------- hour (0 - 23)
+------------------------- min (0 - 59)
如果表达式详细信息与当前时间戳匹配,将调用给定的匿名 函数。此函数在执行作业时成功则应返回null,如果执行此作业时出现错误则返回任何其他内容。默认情况下,错误情况将被记录到数据库和一个Monolog记录器对象(如果启用了记录器)。
isEnabled 布尔参数使您能够不删除作业即可将其从执行中停用。稍后可以通过将方法中的布尔值设置为true非常容易地启用作业执行。此参数是可选的,默认值是启用。
示例
\Cron::add('example1', '* * * * *', function() { // Do some crazy things successfully every minute return null; }); \Cron::add('example2', '*/2 * * * *', function() { // Oh no, this job has errors and runs every two minutes return false; }, true);
删除 cron 任务
要删除运行时的设置cron作业,请使用带字符串参数的 remove 方法。
public static function remove($name) {
示例
\Cron::add('example1', '* * * * *', function() { // Do some crazy things successfully every minute return null; }); \Cron::remove('example1');
启用或禁用cron作业
在添加已启用或已禁用的cron作业(调用add方法的 isEnabled 布尔参数)后,您可以通过名称禁用或启用cron作业。为此,请使用 setEnableJob 或 setDisableJob 函数。
public static function setEnableJob($jobname, $enable = true) {
public static function setDisableJob($jobname) {
示例
\Cron::add('example1', '* * * * *', function() { // Do some crazy things successfully every minute return null; }); \Cron::setDisableJob('example1'); // No jobs will be called $report = \Cron::run(); \Cron::setEnableJob('example1'); // One job will be called $report = \Cron::run();
获取器
要获取作业的启用状态布尔值,请使用静态方法 isJobEnabled($jobname)
。
运行 cron 任务
运行cron作业与添加它们一样简单。只需调用静态 run 方法,等待检查每个添加的cron作业表达式。一旦表达式的时刻到来,相应的cron作业将被调用。这就是Cron的魔法。默认情况下,Cron假设您每分钟调用此方法一次(* * * * *),并且默认情况下,报告(包括它们的cron作业错误)将被记录到数据库。您可以使用 setRunInterval
函数更改此间隔。
public static function run() {
示例
$report = \Cron::run();
注意:调用 run 方法必须是添加作业、设置间隔、停用数据库记录和其他函数调用之后的最后一个函数调用。
设置运行间隔
运行间隔是两次cron作业路由调用之间的时间。一些cron服务提供商只支持每15分钟或甚至每30分钟调用一次。在这种情况下,您必须将此值设置为15或30。此值仅用于确定当前运行调用是否及时。如果您已禁用数据库日志记录,则无需关心此。
public static function setRunInterval($minutes) {
注意:如果路由调用间隔不是每分钟一次,您必须调整cron作业表达式以适应此间隔。
示例
// Set the run intervall to 15 minutes \Cron::setRunInterval(15); // Or set the run intervall to 30 minutes \Cron::setRunInterval(30);
获取器
要获取当前设置的运行间隔,请使用静态getRunInterval()
方法。
启用或禁用Laravel日志记录
Laravel日志记录功能位于Monolog之上。默认情况下,Laravel配置为为您的应用程序创建每日日志文件,这些文件存储在app/storage/logs
中。Cron默认使用Laravel日志记录功能。您可以通过在配置文件中将laravelLogging
值设置为false或在运行时调用setLaravelLogging
函数来禁用此功能。
public static function setLaravelLogging($bool) {
注意:您可以将自定义Monolog记录器添加到Cron并启用Laravel日志记录。在这种情况下,所有消息都将记录到Laravel和您的自定义Monolog记录器对象中。
示例
// Laravel logging is enabled by default \Cron::run(); // Disable Laravel logging \Cron::setLaravelLogging(false); // Laravel logging is disabled \Cron::run();
获取器
要获取启用或禁用布尔值,请使用静态isLaravelLogging()
方法。
设置 Monolog 日志记录器
如果您想将自定义Monolog记录器对象添加到Cron,请使用静态setLogger
方法。
public static function setLogger(\Monolog\Logger $logger = null) {
注意:如果您想删除记录器,只需在不带参数调用setLogger
方法。
示例
\Cron::setLogger(new \Monolog\Logger('cronLogger')); // And remove the logger again \Cron::setLogger();
获取器
要获取设置的记录器对象,请使用静态getLogger()
方法。如果没有设置记录器对象,则返回null。
禁用数据库日志记录
默认情况下,数据库日志记录已启用,并在每次cron运行后,管理器对象和作业对象将被保存到数据库中。我们强烈建议保持数据库日志记录激活,因为只有使用此选项,Cron才能检查当前运行是否及时。在某些情况下,可以使用setDatabaseLogging
方法禁用数据库日志记录。
public static function setDatabaseLogging($bool) {
示例
\Cron::setDatabaseLogging(false);
获取器
要获取当前数据库日志记录布尔值,只需使用静态isDatabaseLogging()
函数。
仅将错误任务记录到数据库
默认情况下,Cron将记录所有作业到数据库。有时您可能只想使用静态setLogOnlyErrorJobsToDatabase
函数将错误作业(不返回null)记录到数据库。
public static function setLogOnlyErrorJobsToDatabase($bool) {
示例
// Log only error jobs to database \Cron::setLogOnlyErrorJobsToDatabase(true);
获取器
要获取当前错误作业日志记录的布尔值,请使用静态isLogOnlyErrorJobsToDatabase()
函数。
删除旧数据库条目
Cron可以为您删除旧数据库条目。在每次运行方法调用期间,Cron检查数据库中是否存在旧的管理器和作业条目,以及是否达到参考值,条目将被删除。您可以通过调用setDeleteDatabaseEntriesAfter
函数来更改参考值。默认值为240小时(10天)。要禁用删除旧条目,只需将参考值设置为0。
public static function setDeleteDatabaseEntriesAfter($hours) {
示例
// Set the delete database entries reference value to 10 days (24 hours x 10 days) \Cron::setDeleteDatabaseEntriesAfter(240);
获取器
要获取当前参考值,请使用静态getDeleteDatabaseEntriesAfter
方法。
防止重叠
Cron可以防止重叠。如果启用此功能,则同一时间只能运行一个Cron实例。例如,如果某些作业需要5分钟来执行,而Cron路由每分钟将被调用一次,没有防止重叠,两个Cron实例将同时执行作业。当同时运行作业两次时,可能会发生副作用。Cron可以通过使用简单的锁定技术来避免此类重叠。
public static function setEnablePreventOverlapping() {
示例
// The configuration could be set via config file with the key 'preventOverlapping' or via method \Cron::setEnablePreventOverlapping(); // Now the Cron run will only run once at the same time \Cron::setDisablePreventOverlapping(); // Prevent overlapping is disabled and many Cron run executions are possible at the same time
获取器
要获取当前布尔值,请使用静态isPreventOverlapping
方法。
注意:要使用重叠功能,Cron需要写入Laravel存储目录的权限。在某些Windows机器上,无法删除锁定文件。如果您在日志中看到删除错误消息,请禁用此功能。
事件
Cron支持Laravel事件,并提供有关运行状态和作业状态的许多信息。使用此功能可以响应错误。Cron支持以下事件。
cron.collectJobs
- 在调用运行方法之前触发以添加作业和配置Cron。此事件仅在您使用Cron的集成路由或命令时触发。cron.beforeRun
- 在调用运行方法之前触发,告知Cron即将启动。参数:$runDate
。cron.jobError
- 在一个作业执行后触发,该作业返回了错误(返回值不等于null)。参数:$name
、$return
、$runtime
、$rundate
。cron.jobSuccess
- 在一个作业执行后触发,该作业没有返回错误(返回值等于null)。参数:$name
、$runtime
、$rundate
。cron.afterRun
- 在Cron运行完成后触发。参数:$rundate
、$inTime
、$runtime
、$errors
- 错误作业数量、$crons
- 所有执行作业的数组(键为$name
、$return
、$runtime
)、$lastRun
- 包含最后一次Cron运行信息的数组(键为$rundate
和$runtime
)。如果Cron第一次被调用或数据库日志被禁用,则$lastRun
参数为空数组,因此$inTime
参数等于-1
。cron.locked
- 如果找到锁文件,则触发。参数:$lockfile
。
要订阅事件,请使用Laravel的Event
功能。最佳位置是/path/to/laravel/app/start/global.php
文件。
\Event::listen('cron.jobError', function($name, $return, $runtime, $rundate){ \Log::error('Job with the name ' . $name . ' returned an error.'); });
命令
Cron提供了以下Laravel命令。
cron:run
- 触发cron.collectJobs
事件并启动Cron。cron:list
- 触发cron.collectJobs
事件并列出所有注册的Cron作业。cron:keygen
- 生成一个32字符的安全令牌。
重置 Cron
要重置Cron管理,调用静态reset
方法。它将所有变量重置为默认值。
public static function reset() {
示例
\Cron::add('example1', '* * * * *', function() { // Do some crazy things successfully every minute return null; }); \Cron::setLogger(new \Monolog\Logger('cronLogger')); \Cron::reset(); // \Cron::remove('example1') === false // \Cron::getLogger() === NULL
常见问题解答
我真的需要crontab或在线cronjob服务吗
是的,你需要。与Java应用服务器相比,PHP只有在其被执行时才会运行。如果crontab或在线cronjob服务提供商调用PHP并启动应用程序,Cron可以执行作业并开始工作。如果PHP没有启动,应用程序将休眠,什么都不会发生。
最佳的时间间隔来调用路由或命令是什么?
最佳时间间隔取决于你的作业。如果一个作业每分钟执行一次,而另一个作业每五分钟执行一次,那么路由或命令每分钟必须调用一次。一般来说,你需要找到你作业的最大公约数。请记住,如果你不想每分钟调用路由或命令(默认值),并且想使用Cron的inTime检查,请更改runInterval
配置值。
Cron运行不正常,返回runtime
和inTime
的值都是-1
默认情况下,Cron会防止重叠。这意味着同一时间只能运行一个Cron实例。如果调用另一个实例,Cron将不会运行,并将返回值和inTime参数设置为-1。在某些Windows机器上,删除锁文件失败,你必须禁用此功能。请参阅防止重叠部分。
变更日志
2019/05/21 - 1.3
- 错误修复
2017/09/13 - 1.2
- 添加对Laravel 5.5的支持
- 添加对Laravel 5.4的支持
2016/11/15 - 1.1.2
- 添加对Laravel 5.2中Symfonys 3 Table类的支持
2016/06/07 - 1.1.1
- 修复与Laravel 5.2相关的错误
2015/03/02 - 1.1.0
- 添加对Laravel 5的支持
- 为'cron_job'表添加索引
- 删除Eloquent类别名
- 将'cron_job'表的'cron_manager_id'列改为无符号
- 修复'setDisableInTimeCheck'方法
2015/02/02 - 1.0.2
- 添加cron.locked事件
- 将Cron标记为稳定
- 将$function参数类型更改为"callable",以修复IDE类型提示
2014/10/13 - 1.0.1
- 在run方法中添加try-catch-finally块,以确保始终删除锁文件
- 向cron.afterRun事件添加$lastRun参数
- 添加对Laravel 5 composer的支持
- 删除超过500个字符的返回字符串
- 修复cron.afterRun事件
2014/06/12 - 1.0.0
- 添加带安全令牌的Laravel路由
- 添加用于生成安全令牌的Artisan命令
- 添加用于轻松运行Cron(例如crontab)的Artisan命令
- 添加用于列出通过事件添加的所有任务的Artisan命令
- 添加事件
- 添加重叠保护
- 将配置键'logOnlyErrorJobsToDatabase'的默认值更改为false
- 修复PHP文档标记
- 生成API
- 修复此README文件
- 微小错误修复
2014/02/11 - v0.9.5
- 错误修复版本
- 修复PSR0自动加载问题
- 修复时间问题 - 如果一个任务执行时间超过一分钟,则后续任务未被处理
2013/11/12 - v0.9.4
- 添加Laravel日志功能 - 默认情况下,Cron现在将记录到Laravel
- 添加异常 - Cron现在会抛出InvalidArgumentExceptions和UnexpectedValueExceptions
- 微小错误修复
2013/11/01 - v0.9.3
- 添加Cron的facade - 你现在可以使用
Cron
而不是\Liebig\Cron\Cron
- 添加facade测试用例
许可
MIT许可(MIT)
版权所有 (c) 2013 - 2016 Marc Liebig
特此授予任何获得此软件及其相关文档副本(以下简称“软件”)的人免费权利,在不受限制的情况下处理该软件,包括但不限于使用、复制、修改、合并、发布、分发、再许可和/或销售软件的副本,并允许获得该软件的人这样做,前提是遵守以下条件
上述版权声明和本许可声明应包含在软件的所有副本或主要部分中。
软件按“原样”提供,不提供任何形式的保证,明示或暗示,包括但不限于适销性、适用于特定用途和不受侵犯的保证。在任何情况下,作者或版权持有人不对任何索赔、损害或其他责任承担责任,无论是基于合同、侵权或其他方式,从软件产生、产生于或与软件的使用或其他交易有关。
图标版权所有 (c) Timothy Miller (http://www.iconfinder.com/icondetails/171279/48/alarm_bell_clock_time_icon),根据Creative Commons(署名-相同3.0未本地化)许可 - 感谢您拥有这个很棒的图标