├── README.md ├── composer.json ├── config.php ├── console.config.php ├── crontab.php ├── daemon.php └── src └── PHPKit └── Console ├── Config ├── ILoader.php ├── Loader.php ├── LoaderDb.php └── LoaderFile.php ├── Console.php ├── Crontab ├── Handler.php ├── ParseCrontab.php └── TickTable.php ├── Daemon └── Handler.php ├── Tasks ├── BaseTask.php ├── EchoTask.php └── ITask.php ├── Traits └── HandlerTrait.php └── Workers ├── BaseWorker.php ├── IWorker.php └── PushMessageWorker.php /README.md: -------------------------------------------------------------------------------- 1 | Swoole-Crontab(基于Swoole扩展) 2 | ============== 3 | 1.概述 4 | -------------- 5 | + 基于swoole的定时器程序,支持秒级处理. 6 | + 异步多进程处理。 7 | + 完全兼容crontab语法,且支持秒的配置,可使用数组规定好精确操作时间 8 | + 请使用swoole扩展1.7.9-stable及以上版本.[Swoole](https://github.com/swoole/swoole-src) 9 | + 支持worker处理beanstalk队列任务 10 | 11 | 2.Crontab配置的支持 12 | -------------- 13 | 具体配置文件请看 [src/console.config.php] 14 | 介绍一下时间配置 15 | 16 | 0 1 2 3 4 5 17 | | | | | | | 18 | | | | | | +------ day of week (0 - 6) (Sunday=0) 19 | | | | | +------ month (1 - 12) 20 | | | | +-------- day of month (1 - 31) 21 | | | +---------- hour (0 - 23) 22 | | +------------ min (0 - 59) 23 | +-------------- sec (0-59)[可省略,如果没有0位,则最小时间粒度是分钟] 24 | 3.帮助信息 25 | ---------- 26 | * Usage: /path/to/php console.php [options] -- [args...] 27 | 28 | * -h [--help] 显示帮助信息 29 | * -s start 启动进程 30 | * -s stop 停止进程 31 | * -s restart 重启进程 32 | 33 | 4.运行配置 34 | ----------- 35 | define('PHPKIT_RUN_DEBUG',true); 36 | 开启调试模式,将通过syslog函数打印运行日志 37 | 38 | define('PHPKIT_CONSOLE_CONFIG_PATH',realpath('config.php')); 39 | 定义配置文件路径,未定义则不能运行 40 | 41 | 42 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name":"mawenpei/swoole-crontab", 3 | "type":"library", 4 | "description":"A PHP Crontab", 5 | "keywords":["swoole","crontab","beanstalk"], 6 | "homepage":"https://github.com/mawenpei/swoole-crontab", 7 | "autoload":{ 8 | "psr-4":{ 9 | "":"" 10 | } 11 | }, 12 | "authors":[{"name":"mawenpei","email":"249350293@qq.com"}], 13 | "require":{ 14 | "php":">=5.4.1", 15 | "ext-swoole":">=1.7.17", 16 | "gabordemooij/redbean":"4.3.1" 17 | } 18 | 19 | } -------------------------------------------------------------------------------- /config.php: -------------------------------------------------------------------------------- 1 | 'file', 5 | 'file'=>realpath(__DIR__ . '/console.config.php'), 6 | 'redbeanphp'=>realpath(__DIR__ . '/rb.php'), 7 | 'mysql'=>[ 8 | 'host'=>'localhost', 9 | 'port'=>'3306', 10 | 'db'=>'module_user', 11 | 'table'=>'config', 12 | 'user'=>'root', 13 | 'password'=>'111111' 14 | ] 15 | ]; 16 | -------------------------------------------------------------------------------- /console.config.php: -------------------------------------------------------------------------------- 1 | [ 11 | [ 12 | 'taskname'=>'php', 13 | 'rule'=>'*/5 * * * * *', 14 | 'unique'=>2, 15 | 'execute'=>'\\PHPKit\\Console\\Tasks\\EchoTask', 16 | 'args'=>[ 17 | 'cmd'=>'php -v', 18 | 'ext'=>[] 19 | ] 20 | ] 21 | ], 22 | 'daemon'=>[ 23 | ['className'=>'\\PHPKit\\Console\\Workers\\PushMessageWorker','processNum'=>'5','queue'=>[ 24 | 'host'=>'127.0.0.1','port'=>'11300','tube'=>'testtube' 25 | ]] 26 | ] 27 | ]; -------------------------------------------------------------------------------- /crontab.php: -------------------------------------------------------------------------------- 1 | handle = new LoaderFile($options); 33 | break; 34 | case 'mysql': 35 | $this->handle = new LoaderDb($options); 36 | break; 37 | } 38 | } 39 | } 40 | 41 | public static function getInstance($options) 42 | { 43 | if(!self::$instance){ 44 | self::$instance = new Loader($options); 45 | } 46 | return self::$instance; 47 | } 48 | 49 | public function config() 50 | { 51 | switch(CURRENT_RUN_MODE){ 52 | case Console::RUN_MODE_DAEMON: 53 | return self::loadDaemonConfig(); 54 | break; 55 | case Console::RUN_MODE_CRONTAB: 56 | return self::loadCrontabConfig(); 57 | break; 58 | } 59 | } 60 | 61 | protected function loadCrontabConfig() 62 | { 63 | return $this->handle->loadCrontabConfig(); 64 | } 65 | 66 | protected function loadDaemonConfig() 67 | { 68 | return $this->handle->loadDaemonConfig(); 69 | } 70 | } -------------------------------------------------------------------------------- /src/PHPKit/Console/Config/LoaderDb.php: -------------------------------------------------------------------------------- 1 | config = include($options['file']); 18 | } 19 | public function loadCrontabConfig() 20 | { 21 | return $this->config['crontab']; 22 | } 23 | 24 | public function loadDaemonConfig() 25 | { 26 | return $this->config['daemon']; 27 | } 28 | } -------------------------------------------------------------------------------- /src/PHPKit/Console/Console.php: -------------------------------------------------------------------------------- 1 | 60){ 29 | self::getInstance()->insert(array("tick"=>$sec,"task"=>$task)); 30 | }else{ 31 | self::getInstance()->insert(array("tick"=>$time+$sec,"task"=>$task)); 32 | } 33 | } 34 | } 35 | 36 | public static function get_task(){ 37 | $time = time(); 38 | $ticks = array(); 39 | while(self::getInstance()->valid()){ 40 | $data = self::getInstance()->extract(); 41 | if($data["tick"] > $time){ 42 | self::getInstance()->insert($data); 43 | break; 44 | }else{ 45 | $ticks[] = $data["task"]; 46 | } 47 | } 48 | return $ticks; 49 | } 50 | } -------------------------------------------------------------------------------- /src/PHPKit/Console/Daemon/Handler.php: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mawenpei/swoole-crontab/0231eb32c3a2b205d8c0da6adc1999c2b07b7ab2/src/PHPKit/Console/Daemon/Handler.php -------------------------------------------------------------------------------- /src/PHPKit/Console/Tasks/BaseTask.php: -------------------------------------------------------------------------------- 1 | worker = $worker; 18 | $this->run($args); 19 | } 20 | } -------------------------------------------------------------------------------- /src/PHPKit/Console/Tasks/EchoTask.php: -------------------------------------------------------------------------------- 1 | options = $options['queue']; 28 | $this->queue = new Pheanstalk($this->options['host'],$this->options['port']); 29 | defined('PHPKIT_RUN_DEBUG') && syslog(LOG_INFO,'queue init success' . json_encode($this->options)); 30 | } 31 | } 32 | 33 | public function tick(\swoole_process $worker) 34 | { 35 | $this->worker = $worker; 36 | defined('PHPKIT_RUN_DEBUG') && syslog(LOG_INFO,'tick success'); 37 | \swoole_timer_tick(500,function(){ 38 | while(true){ 39 | $this->checkExit(); 40 | $job = $this->getWaitDoingJob(); 41 | if(!$job){ 42 | defined('PHPKIT_RUN_DEBUG') && syslog(LOG_INFO,'job is empty'); 43 | break; 44 | } 45 | $success = $this->run($job->getData()); 46 | if($success){ 47 | $this->queue->delete($job); 48 | }else{ 49 | // 50 | $this->queue->release($job,1024,300); 51 | } 52 | 53 | } 54 | }); 55 | } 56 | 57 | public function getWaitDoingJob() 58 | { 59 | defined('PHPKIT_RUN_DEBUG') && syslog(LOG_INFO,'queue pop start success'); 60 | $job = $this->queue->watch($this->options['tube'])->ignore('default')->reserve(5); 61 | defined('PHPKIT_RUN_DEBUG') && syslog(LOG_INFO,'queue pop finish success'); 62 | if($job){ 63 | return $job; 64 | } 65 | return null; 66 | } 67 | 68 | protected function _exit() 69 | { 70 | syslog(LOG_INFO,'exit success'); 71 | $this->worker->exit(1); 72 | } 73 | 74 | private function checkExit() 75 | { 76 | $ppid = posix_getppid(); 77 | if($this->ppid==0){ 78 | $this->ppid = $ppid; 79 | } 80 | if($this->ppid != $ppid){ 81 | $this->_exit(); 82 | } 83 | } 84 | } -------------------------------------------------------------------------------- /src/PHPKit/Console/Workers/IWorker.php: -------------------------------------------------------------------------------- 1 |