liebig / 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 如何简化您的作业调度的更多信息,请参阅存在理由。
- 主页: https://liebig.github.io/cron/
- Github: https://github.com/liebig/cron/
- API: http://liebig.github.io/cron/docs/api/classes/Liebig.Cron.Cron.html
存在理由
简洁性
目标是创建一种简单的方法,使用 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 是我管理任务调度的个人方式。我是一名Web应用程序开发者,而不是基础设施人员。我喜欢用PHP处理事情,而不是在shell中。我希望将我的应用程序部署到另一台服务器,而不用担心我是否有访问crontab或其他Linux工具的权限。我真的喜欢Laravel的事件功能,但不喜欢Laravel的命令。Cron管理应该既简单又强大。最后,我喜欢在应用程序中一个地方处理所有事情,而不使用shell或为每个作业编写PHP文件。Cron是尝试无头痛地管理cron作业的尝试。
安装
Laravel 5
- 将
"liebig/cron": "dev-main"
添加到您的/path/to/laravel/composer.json
文件中的"require":
部分(有关Composer的更多信息,请参阅https://getcomposer.org.cn/) - 在您的
/path/to/laravel/
目录下,从shell运行composer update liebig/cron --no-dev
命令 - 如果您使用的是Laravel 5.4或更早版本,请将
'Liebig\Cron\Laravel5ServiceProvider'
添加到/path/to/laravel/config/app.php
文件中的'providers'
数组中 - 运行命令
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-main"
添加到您的/path/to/laravel/composer.json
文件中的"require":
部分(有关Composer的更多信息,请参阅https://getcomposer.org.cn/) - 在您的
/path/to/laravel/
目录下,从shell运行composer update liebig/cron --no-dev
命令 - 将
'Liebig\Cron\CronServiceProvider'
添加到您的/path/to/laravel/app/config/app.php
文件中的'providers'
数组中 - 运行命令
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访问权限,您可以使用在线cron作业服务(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作业的name
、cron的expression
和一个匿名function
。布尔值isEnabled
是可选的,可以启用或禁用此cron作业的执行(默认为启用)。
public static function add($name, $expression, $function, $isEnabled = true) {
name
对于在出现错误时识别cron作业以及记录日志是必需的。
expression
是一个字符串,包含五个或六个可选的子表达式,用于描述计划的详细信息。语法基于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)
如果表达式详细信息与当前时间戳匹配,则将调用给定的匿名function
。如果执行此作业时出现错误,则此函数应返回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作业,请使用带有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作业(添加方法的$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的魔力。run方法返回一个详细报告。默认情况下,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) {
注意:你可以向Cron添加自定义的Monolog记录器并启用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 记录器
如果你想向Cron添加自定义的Monolog记录器对象,请使用静态的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
函数。
防止重叠
定时任务可以防止重复执行。如果启用此功能,则同一时间只能运行一个定时任务实例。例如,如果某些作业需要5分钟来完成,但定时任务路由每分钟被调用一次,不防止重复执行,则两个定时任务实例将同时执行作业。当同时运行两个作业时,可能会出现副作用。定时任务可以通过使用简单的锁定技术来避免这种重复。
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
函数。
注意:要使用重复执行功能,定时任务需要具有Laravel存储目录的写入权限。在某些Windows机器上,锁定文件无法删除。如果您的日志中看到删除错误消息,请禁用此功能。
事件
定时任务支持Laravel事件,并提供有关运行状态和作业状态的大量信息。利用这一点,您可以响应错误。定时任务支持以下事件。
cron.collectJobs
- 在调用run方法之前触发,用于添加作业和配置定时任务。此事件仅在您使用定时任务的集成路由或命令时触发。cron.beforeRun
- 在调用run方法之前触发,通知定时任务即将开始。参数:$runDate
。cron.jobError
- 在作业执行后触发,如果该作业返回了错误(返回值不等于null)。参数:$name
、$return
、$runtime
、$rundate
。cron.jobSuccess
- 在作业执行后触发,如果该作业没有返回错误(返回值等于null)。参数:$name
、$runtime
、$rundate
。cron.afterRun
- 在定时任务运行完成后触发。参数:$rundate
、$inTime
、$runtime
、$errors
- 错误作业的数量、$crons
- 所有已执行作业的数组(键为$name
、$return
、$runtime
)、$lastRun
- 最后一次定时任务运行信息的数组(键为$rundate
和$runtime
)。如果定时任务是第一次调用或数据库记录被禁用,则$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.'); });
命令
定时任务为您提供了以下Laravel命令。
cron:run
- 触发cron.collectJobs
事件并启动定时任务。cron:list
- 触发cron.collectJobs
事件并列出所有注册的定时任务。cron:keygen
- 生成一个32字符的安全令牌。
重置 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或在线定时任务服务吗?
是的,您需要。例如,与Java应用服务器相比,PHP仅在执行时运行。如果crontab或在线定时任务服务提供商调用PHP并启动应用,定时任务可以执行作业并开始工作。如果PHP没有启动,应用将处于睡眠状态,什么也不会发生。
调用路由或命令的最佳间隔是多少?
最佳间隔取决于您的作业。如果一个作业应该每分钟执行一次,另一个作业每五分钟执行一次,则路由或命令必须每分钟调用一次。一般来说,您需要找到您作业的最大公约数。请记住,如果路由或命令不是每分钟调用(默认值),并且您想使用定时任务的准时检查,请更改runInterval
配置值。
定时任务运行不正常,并返回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 中添加对 Symfony 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 的 Artisan 命令(例如使用 crontab)
- 添加用于列出通过事件添加的所有作业的 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 的外观 - 您现在可以使用
Cron
而不是\Liebig\Cron\Cron
- 添加外观测试用例
许可协议
MIT 许可协议 (MIT)
版权所有 (c) 2013 - 2016 Marc Liebig
特此授予任何人免费获得此软件及其相关文档文件(“软件”)副本的许可,不受任何限制,包括但不限于使用、复制、修改、合并、发布、分发、转授和/或销售软件副本的许可,并允许获得软件的人将其用于此目的,受以下条件约束
上述版权声明和本许可声明应包含在软件的所有副本或主要部分中。
软件按“现状”提供,不提供任何明示或暗示的保证,包括但不限于对适销性、针对特定目的的适用性和非侵权的保证。在任何情况下,作者或版权所有者均不对任何索赔、损害或其他责任承担责任,无论这些责任是基于合同、侵权或其他方式,源自、因之产生或与此软件或其使用或其他交易有关。
图标版权所有 (c) Timothy Miller (http://www.iconfinder.com/icondetails/171279/48/alarm_bell_clock_time_icon),根据 Creative Commons (Attribution-Share Alike 3.0 Unported) 许可协议 - 感谢您拥有这个很棒的表情符号