[原创]php任务调度器 hellogerard/jobby
简介
一个强大的php层面上的定时任务调度器, 无需修改系统层面的crontab
实际中, php 结合 crontab 来实现定时任务是一种经得住考验的实践, 但每次新增/修改定时任务项时都需要去修改系统的crontab, 这会带来两个麻烦: 一个是繁琐, 一个是难以版本控制.
特点:
- 只需维护一个crontab主作业
- 子作业完全由PHP编写
- 支持标准crontab的调度时间格式
- 作业执行超时时可防止运行多个作业副本
- 作业执行出错退出时发送邮件通知
- 可以其他用户身份执行(若主crontab执行用户具有sudo权限)
- 支持仅在某个主机名上运行
- 理论上的Windows支持(包作者未测试过)
相关链接:
安装
php 5.4
composer require "hellogerard/jobby:3.4.1"
注意版本不要用3.4.1以上的, 会出问题(尽管packagist里3.4.2和3.4.3写着php>=5.4, 但实际会出问题)
php 更高版本
composer require hellogerard/jobby
配置crontab主作业
* * * * * cd /path/to/project && php jobby.php &>/dev/null
使用示例文件
cp vendor/hellogerard/jobby/resources/jobby.php .
标准使用
// 加载composer autoload
require_once __DIR__ . '/vendor/autoload.php';
// 创建Jobby实例
$jobby = new Jobby\Jobby();
// 每个job都有一个唯一名称
$jobby->add('CommandExample', [
// 运行一个shell命令
'command' => 'ls',
// 运行一个闭包(与 'command' 互斥)
//'closure' => function() {
// echo "I'm a function!\n";
// return true;
//},
// 支持通用调度配置
'schedule' => '0 * * * *',
// 可使用日期时间字符串
//'schedule' => '2017-05-03 17:15:00',
// 使用闭包返回boolean来确定是否执行
//'schedule' => function(DateTimeImmutable $now) {
// // Run on even minutes
// return $now->format('i') % 2 === 0;
//},
// 标准输出/标准错误会写入到指定日志文件
'output' => 'logs/command.log',
// 临时关闭某个任务
'enabled' => false,
]);
$jobby->run();
选项
每个任务的必须选项
| Key | Type | Description |
|---|---|---|
| schedule | string | Crontab schedule format (man -s 5 crontab) or DateTime format (Y-m-d H:i:s) or callable (function(): Bool { /* ... */ }) |
| command | string | The shell command to run (exclusive-or with closure) |
| closure | Closure | The anonymous PHP function to run (exclusive-or with command) |
以下的选项列表可应用于单个任务或全局任务(通过传入 Jobby构造器).
全局选项将会作为每个任务的默认配置, 单个任务可覆盖全局选项.
| Option | Type | Default | Description |
|---|---|---|---|
| runAs | string | null | Run as this user, if crontab user has sudo privileges |
| debug | boolean | false | Send jobby internal messages to 'debug.log' |
| Filtering 过滤 | Options to determine whether the job should run or not | ||
| environment | string | null or getenv('APPLICATION_ENV') |
Development environment for this job |
| runOnHost | string | gethostname() |
Run jobs only on this hostname |
| maxRuntime | integer | null | Maximum execution time for this job (in seconds) |
| enabled | boolean | true | Run this job at scheduled times |
| haltDir | string | null | A job will not run if this directory contains a file bearing the job's name |
| Logging 日志 | Options for logging | ||
| output | string | /dev/null | Redirect stdout and stderr to this file |
| output_stdout | string | value from output option |
Redirect stdout to this file |
| output_stderr | string | value from output option |
Redirect stderr to this file |
| dateFormat | string | Y-m-d H:i:s | Format for dates on jobby log messages |
| Mailing 邮件 | Options for emailing errors | ||
| recipients | string | null | Comma-separated string of email addresses |
| mailer | string | sendmail | Email method: sendmail or smtp or mail |
| smtpHost | string | null | SMTP host, if mailer is smtp |
| smtpPort | integer | 25 | SMTP port, if mailer is smtp |
| smtpUsername | string | null | SMTP user, if mailer is smtp |
| smtpPassword | string | null | SMTP password, if mailer is smtp |
| smtpSecurity | string | null | SMTP security option: ssl or tls, if mailer is smtp |
| smtpSender | string | jobby@ | The sender and from addresses used in SMTP notices |
| smtpSenderName | string | Jobby | The name used in the from field for SMTP messages |
项目实践
项目存在多个不同游戏服, 且每个服使用的配置文件不一样, 因此执行定时任务时需对每个服单独执行, 特创建crontab.php 文件用于针对不同服分别调用 jobby.php
crontab配置
* * * * * cd /path/to/project && php crontab.php &>/dev/null
crontab.php
<?php
// 服务器列表, 实际是从其他地方读取的
$servers = ["s1", "s2", "s3", "s4"];
foreach ($servers as $server) {
$cmd = sprintf("php jobby.php %s &>/dev/null &", $server);
exec($cmd);
var_dump(compact('cmd'));
}
jobby.php
<?php
// 环境配置
// ...
$server = $argv[1];
$cmdPrefix = "php dispatcher.php $server ";
$jobby = new \Jobby\Jobby([
'output' => "具体的日志输出文件路径",
]);
$jobs = require("jobby_config.php");
foreach ($jobs as $name => $job) {
if (isset($config['command'])) {
$config['command'] = $cmdPrefix.$config['command'];
}
$jobby->add($name, $job);
}
$jobby->run();
jobby_config.php
<?php
return [
"check_index" => [
'command' => "month_check_index",
'schedule' => '30 5 1 * *',
'maxRuntime' => 600,
],
'minute_stats' => [
'command' => "minute_stats",
'schedule' => '* * * * *',
'maxRuntime' => 300,
'enabled' => true,
],
];
dispatcher.php 加载具体服的具体环境, 并调用实际要运行的php定时任务代码
$server = $argv[1];
$command = $argv[2];
// 加载具体服的环境配置
// ...
// 执行具体定时任务代码(此处忽略异常处理)
require __DIR__ . DIRECTORY_SEPARATOR . "jobs" . DIRECTORY_SEPARATOR . $command . ".php";
jobs/month_check_index.php
<?php
// 具体任务
jobs/minute_stats.php
<?php
// 具体任务
[原创]php任务调度器 hellogerard/jobby的更多相关文章
- TaskScheduler一个.NET版任务调度器
TaskScheduler是一个.net版的任务调度器.概念少,简单易用. 支持SimpleTrigger触发器,指定固定时间间隔和执行次数: 支持CronTrigger触发器,用强大的Cron表达式 ...
- 21 BasicTaskScheduler基本任务调度器(一)——Live555源码阅读(一)任务调度相关类
21_BasicTaskScheduler基本任务调度器(一)——Live555源码阅读(一)任务调度相关类 BasicTaskScheduler基本任务调度器 BasicTaskScheduler基 ...
- 18 TaskScheduler任务调度器抽象基类——Live555源码阅读(一)任务调度相关类
这是Live555源码阅读的第二部分,包括了任务调度相关的三个类.任务调度是Live555源码中很重要的部分. 本文由乌合之众 lym瞎编,欢迎转载 http://www.cnblogs.com/ol ...
- azkaben任务调度器
azkaban学习笔记总结 01.工作流调度器azkaban 1. 任务调度概述 一个完整的数据分析系统通常都是由大量任务单元组成: shell脚本程序,java程序,mapreduce程序.hive ...
- SpringBoot2 task scheduler 定时任务调度器四种方式
github:https://github.com/chenyingjun/springboot2-task 使用@EnableScheduling方式 @Component @Configurabl ...
- Spark源码剖析 - SparkContext的初始化(五)_创建任务调度器TaskScheduler
5. 创建任务调度器TaskScheduler TaskScheduler也是SparkContext的重要组成部分,负责任务的提交,并且请求集群管理器对任务调度.TaskScheduler也可以看作 ...
- C# 可指定并行度任务调度器
可指定并行度的任务调度器 https://social.msdn.microsoft.com/Forums/zh-CN/b02ba3b4-539b-46b7-af6b-a5ca3a61a309/tas ...
- springMVC + quartz实现定时器(任务调度器)
首先我们要知道任务调度器(定时器)有几种,这边我会写三种 第一种是基于JDK的本身的一个定时器(优点:简单,缺点:满足不了复杂的需求) package com.timer1; import java. ...
- 基于Spring Task的定时任务调度器实现
在很多时候,我们会需要执行一些定时任务 ,Spring团队提供了Spring Task模块对定时任务的调度提供了支持,基于注解式的任务使用也非常方便. 只要跟需要定时执行的方法加上类似 @Schedu ...
随机推荐
- Photoshop中的高斯模糊、高反差保留和Halcon中的rft频域分析研究
在Halcon的rft变换中,我们经常可以看到这样的算子组合: rft_generic (Image, ImageFFT2, 'to_freq', 'none', 'complex', Width) ...
- code1001 舒适的路线
n次最小生成树kruskal 将所有的边排序,权值小的在前. 设排序后第i条边为路径中的最长边,那么这条路径一定是由1~i中的一些边组成 因为最高速和最低速的差尽量小,最高速确定了,最低速应尽量大. ...
- DataStage 错误集(持续更新)
DataStage 错误集(持续更新) DataStage序列文章 DataStage 一.安装 DataStage 二.InfoSphere Information Server进程的启动和停止 D ...
- js的prototype(2)
1 原型法设计模式 在.Net中可以使用clone()来实现原型法 原型法的主要思想是,现在有1个类A,我想要创建一个类B,这个类是以A为原型的,并且能进行扩展.我们称B的原型为A. 2 javasc ...
- Devexpress + wcf +ef 批量更新处理
项目结构: 1.客户端:Winform, 2.数据访问:EF4.0(从数据库生成模型-懒人必需这样) 3.DTO:直接使用EF实体 4.服务端:WCF 托管在IIS中采用basicHttp帮定(这样可 ...
- HDU 5120 Intersection (圆的面积交)
题意:给定两个圆环,求两个圆环的面积交. 析:很容易知道,圆环面积交就是,大圆与大圆面积交 - 大圆和小圆面积交 - 小圆和大圆面积交 + 小圆和小圆面积交. 代码如下: #pragma commen ...
- javascript 区分对象类型
在 JavaScript 里使用 typeof 来判断数据类型,只能区分基本类型,即 “number”,”string”,”undefined”,”boolean”,”object” 五种.对于数组. ...
- winform 开发中 把耗时操作 封装起来 异步执行(.net 4.0)
.先定义一个 BackgroundTask.cs 代码如下: public class BackgroundTask { private static WaitDialogForm LoadingDl ...
- xaml mvvm(2)之属性绑定
通过微软INotifyPropertyChanged接口,可以实现对UI实时更新,不管是数据源或者目标对象,可以实现相互通知. 下面我们根据INotifyPropertyChanged编写一个扩展类. ...
- Python2.4+ 与 Python3.0+ 主要变化与新增内容
Python2 Python3print是内置命令 print变为函数print >> f,x,y ...