php实际开发过程,4.工作实际开发应用

**本文以thinkphp5中扩展 think-queue的应用为实例**

1.安装think-queue 扩展

```

composer install topthink/think-queue

```

2.index模块下新建控制器,调用消息队列入队

~~~

```

namespace app\index\controller;

/**

* 文件路径: \application\index\controller\JobTest.php

* 该控制器的业务代码中借助了thinkphp-queue 库,将一个消息推送到消息队列

*/

use think\Exception;

use think\Queue;

use think\Log;

class JobTest

{

/**

* 一个使用了队列的 action

*/

public function actionWithHelloJob($msg){

// 1.当前任务将由哪个类来负责处理。

// 当轮到该任务时,系统将生成一个该类的实例,并调用其 fire 方法

$jobHandlerClassName = 'app\index\job\Hello'; // 对应job下处理的消息类

// 2.当前任务归属的队列名称,如果为新队列,会自动创建

$jobQueueName = "helloJobQueue";

// 3.当前任务所需的业务数据 . 不能为 resource 类型,其他类型最终将转化为json形式的字符串

// ( jobData 为对象时,存储其public属性的键值对 )

$jobData = [ 'ts' => time(), 'bizId' => uniqid() , 'a' => 1, 'msg'=>$msg , 'time'=>date('Y-m-d H:i:s') ] ;

// 4.将该任务推送到消息队列,等待对应的消费者去执行

$isPushed = Queue::push( $jobHandlerClassName , $jobData , $jobQueueName );

// database 驱动时,返回值为 1|false ; redis 驱动时,返回值为 随机字符串|false

if( $isPushed !== false ){

return date('Y-m-d H:i:s') . " a new Hello Job is Pushed to the MQ"."
";

}else{

return 'Oops, something went wrong.';

}

}

public function actionWithMultiTask($whichTask){

$taskType = $_GET['taskType'];

switch ($whichTask) {

case 'taskA':

$jobHandlerClassName = 'application\index\job\MultiTask@taskA';

$jobDataArr = ['a' => '1'];

$jobQueueName = "multiTaskJobQueue";

break;

case 'taskB':

$jobHandlerClassName = 'application\index\job\MultiTask@taskB';

$jobDataArr = ['b' => '2'];

$jobQueueName = "multiTaskJobQueue";

break;

default:

break;

}

$isPushed = Queue::push($jobHandlerClassName, $jobDataArr, $jobQueueName);

if ($isPushed !== false) {

echo("the $taskType of MultiTask Job has been Pushed to ".$jobQueueName ."
");

}else{

throw new Exception("push a new $taskType of MultiTask Job Failed!");

}

}

}

~~~

```

3.index模块下新建job目录,供调用处理进入消息队列的消息

namespace app\index\job;

use think\Log;

use think\queue\Job;

/**

* 文件路径: \application\index\job\Hello.php

* 这是一个消费者类,用于处理 helloJobQueue 队列中的任务

*/

class Hello

{

/**

* fire方法是消息队列默认调用的方法

* @param Job $job 当前的任务对象

* @param array|mixed $data 发布任务时自定义的数据

*/

public function fire(Job $job,$data)

{

// 有些消息在到达消费者时,可能已经不再需要执行了

$isJobStillNeedToBeDone = $this->checkDatabaseToSeeIfJobNeedToBeDone($data);

if(!$isJobStillNeedToBeDone){

$job->delete();

return;

}

$isJobDone = $this->doHelloJob($data);

if ($isJobDone) {

// 如果任务执行成功, 记得删除任务

$job->delete();

print("Hello Job has been done and deleted"."\n");

}else{

if ($job->attempts() > 3) {

//通过这个方法可以检查这个任务已经重试了几次了

print("Hello Job has been retried more than 3 times!"."\n");

$job->delete();

// 也可以重新发布这个任务

//print("Hello Job will be availabe again after 2s."."\n");

//$job->release(2); //$delay为延迟时间,表示该任务延迟2秒后再执行

}

}

}

/**

* 有些消息在到达消费者时,可能已经不再需要执行了

* @param array|mixed $data 发布任务时自定义的数据

* @return boolean 任务执行的结果

*/

private function checkDatabaseToSeeIfJobNeedToBeDone($data){

return true;

}

private function doHelloJob($data) {

// 根据消息中的数据进行实际的业务处理...

$this->testWriteLog($data['msg'],$data['time']);

print("Hello Job Started. job Data is: ".var_export($data,true)." \n");

print("Hello Job is Fired at " . date('Y-m-d H:i:s') ." \n");

print("Hello Job is Done!"." \n");

return true;

}

/**

* 耗时方法,测试是否异步执行

*

*/

public function testWriteLog($msg,$time)

{

sleep(30);

Log::info('测试异步执行:'.$msg.'-'.$time.'-当前时间:'.date('Y-m-d H:i:s'));

}

}

```

4.windows下执行进入项目根目录 php think queue:listen 监听消息队列发布进入

5.启动 本地redis

6.访问控制器,发布消息队列任务

7.启动消息队列执行出 php think queue:work --queue helloJobQueue

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值