Swoole实现任务定时自动化调度详解,来学习下

编程

问题描述

这几天做银行对帐接口时,踩了一个坑,具体需求大致描述一下。

银行每天凌晨后,会开始准备昨天的交易流水数据,需要我们这边请求拿到。

因为他们给的是一个base64加密的zip压缩流,解开以后可以得到txt文件,里面就是我们需要的数据了。

业务程序写好以后,随手丢了一个定时任务就去睡觉了。

哪知道第二天上班的时候,检查。发现并没有拿到数据,查询一下日志的时候发现,凌晨服务端请求的时候,银行接口返回了:系统错误信息。

咨询银行那边后,银行那边相关人员建议我们多请求几次,但是在多次请求中,我发现银行那边是有频率限制的,最后得知,此接口只能半个小时才能请求一次。这就比较尴尬了,因为我不知道银行那边什么时候能返回数据给我。

于是这个问题怎么解决呢?理想的情况是,服务端请求数据,银行那边没有返回。然后程序等半个小时后,再请求一次,这样一直到银行那边返回正确的数据中止。

 

问题分析

这个功能换作别的语言也许不难,但是通过php实现的话,那就比较麻烦了。通常的话,我们可以搭配linux下的cron来实现,比如我们可以在凌晨到6:00之间做一个定时任务,每半个小时扫描一次php脚本,如果发现银行那边的状态依旧为失败的话,我们就执行一次php脚本去请求数据。直到请求到正确的数据,然后把状态更新为成功。

这不失为一种方法,但太傻了。比如说银行那边比较正常,凌晨,也就是第一次请求的时候,就已经返回了正确的数据,那么我们的cron脚本还傻傻的每个半个小时执行一次,好蠢!~

或者我们可以尝试使用linux下的at命令,但感觉还是不够优雅。

 

解决问题

于是决定给laravel扩展一个swoole插件来解决此问题,swoole的定时任务很完美的解决了我们目前的问题。

首先我们需要把swoole扩展安装好,具体过程略。
装好以后,我们写一个swoole简易的服务端测试脚本,注意,此脚本是放在app/Console/Commands/下的,笔者是放在了app/Console/Commands/Swoole/swoole.php下,具体代码为

<?php

namespace AppConsoleCommandsSwoole;

use IlluminateConsoleCommand;

class swoole extends Command

{

/**

* The name and signature of the console command.

*

* @var string

*/

protected $signature = "swoole {action}";

/**

* The console command description.

*

* @var string

*/

protected $description = "Let"s use swoole !";

private $serv;

/**

* Create a new command instance.

*

* @return void

*/

public function __construct()

{

parent::__construct();

}

/**

* Execute the console command.

*

* @return mixed

*/

public function handle()

{

$arg = $this->argument("action");

switch ($arg) {

case "start":

$this->info("swoole server started");

$this->start();

break;

case "stop":

$this->info("stoped");

$this->stop();

break;

case "restart":

$this->info("restarted");

break;

}

}

private function start()

{

$this->serv = new swoole_server("127.0.0.1", 9501);

$this->serv->set(array(

"worker_num" => 8,

"daemonize" => false,

"max_request" => 10000,

"dispatch_mode" => 2,

"task_worker_num" => 8,

"task_ipc_mode" => 3,

"log_file" => storage_path("logs/taskqueue.log"),

));

$this->serv->on("Receive", array($this, "onReceive"));

$this->serv->on("Task", array($this, "onTask"));

$this->serv->on("Finish", array($this, "onFinish"));

$this->serv->start();

}

public function onReceive(swoole_server $serv, $fd, $from_id, $data)

{

$serv->task($data);

}

public function onTask($serv, $task_id, $from_id, $data)

{

$timeon = (3) * 1000;

if ($timeon > 0) {

$serv->after($timeon, function () {

//业务逻辑处

exec("php /path/to/root/artisan Test:Command");

});

}

return date("Y-m-d H:i:s") . "第一次执行";

}

public function onFinish($serv, $task_id, $data)

{

echo "Task finish

";

}

private function stop()

{

exec("/usr/bin/killall php");

}

}

这是服务端,我们主要用到了after方法,模拟的话,是三秒一执行。实际应该是三十分钟

然后我们随便写一个客户端连接类

<?php

/**

* Created by PhpStorm.

* User: nosay

* Date: 4/13/18

* Time: 9:27 PM

*/

namespace AppExtensionphpSwoole;

class swoole{

private $data;

private $client;

public function __construct($data){

$this->data = $data;

$this->client = new swoole_client(SWOOLE_SOCK_TCP);

}

public function connect(){

if( !$this->client->connect("127.0.0.1", 9501 , 1) ) {

echo "Error";

}

$this->client->send($this->data);

}

}

于是我们在银行脚本中就可以去执行了

<?php

namespace AppConsoleCommandsTest;

use AppExtensionphpSwooleswoole;

use IlluminateConsoleCommand;

class TestCommand extends Command

{

/**

* The name and signature of the console command.

*

* @var string

*/

protected $signature = "Test:Command";

/**

* The console command description.

*

* @var string

*/

protected $description = "Command Test";

/**

* Create a new command instance.

*

* @return void

*/

public function __construct()

{

parent::__construct();

}

/**

* Execute the console command.

*

* @return mixed

*/

public function handle()

{

//这里是业务逻辑

//如果银行那边返回的为false的话,那么我们把他交给swoole的定时脚本

$status = false;

if(!$status)

{

$swoole = new swoole("hehe");

$swoole->connect();

}

}

}

以上内容希望帮助到大家,很多PHPer在进阶的时候总会遇到一些问题和瓶颈,业务代码写多了没有方向感,不知道该从那里入手去提升,对此我整理了一些资料,包括但不限于:分布式架构、高可扩展、高性能、高并发、服务器性能调优、TP6,laravel,YII2,Redis,Swoole、Swoft、Kafka、Mysql优化、shell脚本、Docker、微服务、Nginx等多个知识点高级进阶干货需要的可以免费分享给大家,需要请戳这里

以上是 Swoole实现任务定时自动化调度详解,来学习下 的全部内容, 来源链接: utcz.com/z/518538.html

回到顶部