##3.6.1 扩展类库:新型计划任务
此扩展类型用于后台计划任务的调度,主要功能点有:
+ 1、提供了Redis/文件/数据库三种MQ队列
+ 2、提供了本地和远程两种调度方式
+ 3、以接口的形式实现计划任务
+ 4、提供统一的crontab调度
更多内容,请查看:[[1.31] 新型计划任务:以接口形式实现的计划任务](/wikis/%5B1.31%5D-%E6%96%B0%E5%9E%8B%E8%AE%A1%E5%88%92%E4%BB%BB%E5%8A%A1%EF%BC%9A%E4%BB%A5%E6%8E%A5%E5%8F%A3%E5%BD%A2%E5%BC%8F%E5%AE%9E%E7%8E%B0%E7%9A%84%E8%AE%A1%E5%88%92%E4%BB%BB%E5%8A%A1.html)
##3.6.2 安装
###(1)内置扩展包
此安装略,已内置于PhalApi框架中。
> 温馨提示:
> PhalApi需要PhaApi 1.2.0及以上版本。
###(2)配置
我们需要在 **./Config/app.php** 配置文件中追加以下配置:
```javascript
/**
* 计划任务配置
*/
'Task' => array(
//MQ队列设置,可根据使用需要配置
'mq' => array(
'file' => array(
'path' => API_ROOT . '/Runtime',
'prefix' => 'phalapi_task',
),
'redis' => array(
'host' => '127.0.0.1',
'port' => 6379,
'prefix' => 'phalapi_task',
'auth' => '',
),
),
//Runner设置,如果使用远程调度方式,请加此配置
'runner' => array(
'remote' => array(
'host' => 'http://library.phalapi.net/demo/',
'timeoutMS' => 3000,
),
),
),
```
以上内容看情况需要而配置。
###(3)数据库表
当需要使用数据库MQ列队时,还需要将以下数据库的配置追加到 **./Config/dbs.php** 中:
```javascript
'tables' => array(
//请将以下配置拷贝到 ./Config/dbs.php 文件对应的位置中,未配置的表将使用默认路由
//10张表,可根据需要,自行调整表前缀、主键名和路由
'task_mq' => array(
'prefix' => 'phalapi_',
'key' => 'id',
'map' => array(
array('db' => 'db_demo'),
array('start' => 0, 'end' => 9, 'db' => 'db_demo'),
),
),
)
```
同时,需要将 ./Data/phalapi_task_mq.sql 文件的SQL建表语句导入到你的数据库。你也可以将利用脚本来生成。
##3.6.3 入门使用
###(1)加入MQ队列
首先,我们需要在入口文件进行对Task的初始化:
```javascript
DI()->loader->addDirs('Library');
$mq = new Task_MQ_Redis(); //可以选择你需要的MQ
DI()->taskLite = new Task_Lite($mq);
```
然后,这样即可添加一个新的计划任务到MQ:
```javascript
DI()->taskLite->add('Task.DoSth', array('id' => 1));
```
###(2)计划任务的启动
在启动计划任务前,我们需要编写简单的脚本,一如这样:
```javascript
#!/usr/bin/env php
<?php
require_once '/path/to/Public/init.php';
DI()->loader->addDirs('Demo');
if ($argc < 2) {
echo "Usage: $argv[0] <service> \n\n";
exit(1);
}
$service = trim($argv[1]);
$mq = new Task_MQ_Redis();
$runner = new Task_Runner_Local($mq);
$rs = $runnter->go($service);
echo "\nDone:\n", json_encode($rs), "\n\n";
```
然后使用nohup或者crontab启动即可。
###(3)续篇 - 统一的crontab计划任务
上面第二点的启动是通用、自定义、也是自由的启动方式。
这里再提供一种具体的、统一的启动方式,即使用crontab的方式。
首先,创建以下表(或见./Library/Task/Data/phalapi_task_progress.sql文件):
```javascript
CREATE TABLE `phalapi_task_progress` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`title` varchar(200) DEFAULT '' COMMENT '任务标题',
`trigger_class` varchar(50) DEFAULT '' COMMENT '触发器类名',
`fire_params` varchar(255) DEFAULT '' COMMENT '需要传递的参数,格式自定',
`interval_time` int(11) DEFAULT '0' COMMENT '执行间隔,单位:秒',
`enable` tinyint(1) DEFAULT '1' COMMENT '是否启动,1启动,0禁止',
`result` varchar(255) DEFAULT '' COMMENT '运行的结果,以json格式保存',
`state` tinyint(1) DEFAULT '0' COMMENT '进程状态,0空闲,1运行中,-1异常退出',
`last_fire_time` int(11) DEFAULT '0' COMMENT '上一次运行时间',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
```
接着,添加crontab计划任务:
```javascript
$ crontab -e
*/1 * * * * /usr/bin/php /path/to/PhalApi/Library/Task/crontab.php >> /tmp/phalapi_task_crontab.log 2>&1
```
然后,实现你的计划任务服务接口:
```javascript
<?php
class Api_Task_Demo extends PhalApi_Api {
public function doSth() {
// ...
}
}
```
最后,配置计划任务:
```javascript
INSERT INTO `phalapi_task_progress`(title, trigger_class, fire_params, interval_time) VALUES('你的任务名字', 'Task_Progress_Trigger_Common', 'Task_Demo.DoSth&Task_MQ_File&Task_Runner_Local', '300');
```
注意,在配置时,需要指明MQ和Runner的类型。
##3.6.4 更多说明
###(1)依赖的资源服务
名称|类|没有时是否自动创建
---|---|---
curl|PhalApi_CUrl|是
request|PhalApi_Request|强制每次初始化,用于本地调度时
response|PhalApi_Response_Json|强制每次初始化,用于本地调度时
###(2)MQ
####Redis MQ队列
Redis MQ队列需要的配置为:
```javascript
'Task' => array(
//MQ队列设置,可根据使用需要配置
'mq' => array(
'redis' => array(
'host' => '127.0.0.1',
'port' => 6379,
'prefix' => 'phalapi_task',
'auth' => '',
),
),
),
```
其中:
选项|是否必须|默认值|说明
---|---|---|---
host|否|127.0.0.1|redis的HOST
port|否|6379|redis的端口
prefix|否|phalapi_task|key的前缀
auth|否||redis的验证,不为空时执行验证
可以这样创建Redis MQ队列:
```javascript
//方法一:使用app.Task.mq.redis配置
$mq = new Task_MQ_Redis();
//方法二:外部依赖注入
$redisCache = new PhalApi_Cache_Redis(array('host' => '127.0.0.1'));
$mq = new Task_MQ_Redis($redisCache);
```
####文件MQ队列
文件MQ需要的配置为:
```javascript
'Task' => array(
//MQ队列设置,可根据使用需要配置
'mq' => array(
'file' => array(
'path' => API_ROOT . '/Runtime',
'prefix' => 'phalapi_task',
),
),
),
```
其中:
选项|是否必须|默认值|说明
---|---|---|---
path|否|API_ROOT/Runtime|缓存的文件目录
prefix|否|phalapi_task|key的前缀
可以这样创建文件MQ队列:
```javascript
//方法一:使用app.Task.mq.file配置
$mq = new Task_MQ_File();
//方法二:外部依赖注入
$fileCache = new PhalApi_Cache_File(array('path' => '/tmp/cache'));
$mq = new Task_MQ_File($fileCache);
```
####数据库MQ队列
数据库MQ队列需要的配置为:
```javascript
'tables' => array(
//请将以下配置拷贝到 ./Config/dbs.php 文件对应的位置中,未配置的表将使用默认路由
//10张表,可根据需要,自行调整表前缀、主键名和路由
'task_mq' => array(
'prefix' => 'phalapi_',
'key' => 'id',
'map' => array(
array('db' => 'db_demo'),
array('start' => 0, 'end' => 9, 'db' => 'db_demo'),
),
),
)
```
可以这样创建数据库MQ队列:
```javascript
$mq = new Task_MQ_DB();
```
####数组MQ队列
数组MQ队列是将MQ存放在PHP的数组里面,用于单元测试或者是一次性、临时性的计划任务调度。
可以这样创建数据库MQ队列:
```javascript
$mq = new Task_MQ_Array();
```
###(3)本地和远程调度
####本地调度的创建
```javascript
$runner = new Task_Runner_Local($mq, 10); //10表示每批次弹出10个进行处理
```
需要注意的是,每次执行一个计划任务,都会重新初始化必要的DI资源服务。
且此调度方式不能用于接口请求时的同步调用。
####远程调度的创建
首先需要以下配置:
```javascript
/**
* 计划任务配置
*/
'Task' => array(
//Runner设置,如果使用远程调度方式,请加此配置
'runner' => array(
'remote' => array(
'host' => 'http://library.phalapi.net/demo/',
'timeoutMS' => 3000,
),
),
),
```
其中:
选项|是否必须|默认值|说明
---|---|---|---
host|是||接口域名链接
timeoutMS|否|3000|接口超时时间,单位毫秒
可以这样创建:
```javascript
//使用默认的连接器 - HTTP + POST的方式
$runner = new Task_Runner_Remote($mq, 10); //10表示每批次弹出10个进行处理
//或者,指定连接器
$connector = new Task_Runner_Remote_Connector_Impl();
$runner = new Task_Runner_Remote($mq, 10, $connector); //10表示每批次弹出10个进行处理
```
- 欢迎使用PhalApi!
- 接口,从简单开始!
- [1.1]-下载与安装
- [1.2]-创建一个自己的项目
- [1.3]-在线体验
- [1.4]-文档、帮助和官网
- [1.10]-对PhalApi框架的抉择
- [1.11]-快速入门(backup)
- [1.12]-参数规则:接口参数规则配置
- [1.13]-统一的接口请求方式:_sevice=XXX.XXX
- [1.14]-统一的返回格式和结构:ret-data-msg
- [1.15]-数据库操作:基于NotORM的使用及优化
- [1.16]-配置读取:内外网环境配置的完美切换
- [1.17]-日记纪录:简化版的日记接口
- [1.18]-快速函数:人性化的关怀
- [1.19]-DI服务速查:各资源服务一览表
- [1.20]-DB操作:数据库基本操作速查
- [1.21]-类的自动加载:遵循PEAR包的命名规范
- [1.22]-签名验证:自定义签名规则
- [1.23]-请求和响应:GET和POST两者皆可得及超越JSON格式返回
- [1.24]-缓存策略:更灵活地可配置化的多级缓存
- [1.25]-国际化翻译:为走向国际化提前做好翻译准备
- [1.26]-数据安全:数据对称加密方案
- [1.27]-精益开发:更富表现力的Model层和重量级数据获取的应对方案
- [1.28]-COOKIE:对COOKIE原生态的支持及记忆加密升级版
- [1.29]-开放与封闭:多入口和统一初始化
- [1.30]-保持的力量:接口开发最佳实践
- [1.31]-新型计划任务:以接口形式实现的计划任务
- [2.11]-核心思想:DI依赖注入-让资源更可控
- [2.12]-海量数据:可配置的分库分表
- [2.13]-接口调试:在线SQL语句查看与性能优化
- [2.14]-测试驱动开发:意图导向编程下的接口开发
- [2.15]-演进:新型计划任务续篇
- [2.16]-领域驱动设计:应对复杂领域业务的Domain层
- [2.17]-微服务:Api接口服务层
- [2.18]-定制化:资源服务的再实现
- [2.19]-扩展库:可重用的扩展类库
- [2.20]-约定编程:架构明显的编程风格
- [2.21]-服务器统一部署方案简明版:CentOs---Nginx---php-fpm---MySql-[--Memcached]
- [2.22]-更多工具:精益项目和团队建设
- [3.1]-扩展类库:微信开发
- [3.2]-扩展类库:代理模式下phprpc协议的轻松支持
- [3.3]-扩展类库:基于PHPMailer的邮件发送
- [3.4]-扩展类库:优酷开放平台接口调用
- [3.5]-扩展类库:七牛云存储接口调用
- [3.6]-扩展类库:新型计划任务
- [3.8]-扩展类库:用户、会话和第三方登录集成
- [3.9]-扩展类库:swoole支持下的长链接和异步任务实现
- [3.11]-扩展类库:基于FastRoute的快速路由
- [4.2]-开发实战2:模拟优酷开放平台接口项目开发
- [4.3]-开发实战3:一个简单的小型项目开发(奔跑吧兄弟投票活动)
- [5.1]-架构与思想:PhalApi核心设计和思想解读
- [5.2]-杂谈:扯一些PhalApi的前世和今生
- [5.3]-框架总结:术语表和PHP开发建议
- [5.4]-许可
- [5.5]-联系和加入我们
- [5.6]-更新日记
- [5.8]-致框架贡献者:加入PhalApi开源指南
- [6.1]-基于接口查询语言的SDK包
- [6.2]-SDK包(JAVA版)
- [6.3]-SDK包(PHP版)
- [6.4]-SDK包(Objective-C版)
- [6.5]-SDK包(javascript版)
- [6.6]-SDK包(Ruby版)
- [8.1]-PhalApi视频教程
- 附录1:接口文档参考模板