swoole是如何实现任务定时自动化调度的?

swoole是如何实现任务定时自动化调度的?

https://www.muzilong.cn/article/117

开发环境

环境:lnmp下进行试验。

框架:laravel5

 

问题描述

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

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

因为他们给的是一个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 App\Console\Commands\Swoole; use Illuminate\Console\Command; 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\n"; } private function stop() { exec('/usr/bin/killall php'); } }

 

 

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

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

<?php /** * Created by PhpStorm. * User: nosay * Date: 4/13/18 * Time: 9:27 PM */ namespace App\Extension\php\Swoole; 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 App\Console\Commands\Test; use App\Extension\php\Swoole\swoole; use Illuminate\Console\Command; 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(); } } }

https://mp.weixin.qq.com/s/e_ophgURO6qRvfKd3YDJXQ

 
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/112700.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • mac idea2021永久激活码【中文破解版】

    (mac idea2021永久激活码)JetBrains旗下有多款编译器工具(如:IntelliJ、WebStorm、PyCharm等)在各编程领域几乎都占据了垄断地位。建立在开源IntelliJ平台之上,过去15年以来,JetBrains一直在不断发展和完善这个平台。这个平台可以针对您的开发工作流进行微调并且能够提供…

  • 普通用户nginx安装步骤,并能够启动mongo的配置

    普通用户nginx安装步骤,并能够启动mongo的配置普通用户nginx安装步骤,并能够启动mongo的配置

  • python实现注册登录系统_python实现登录与注册系统「建议收藏」

    python实现注册登录系统_python实现登录与注册系统「建议收藏」本文实例为大家分享了python实现登录与注册系统的具体代码,供大家参考,具体内容如下实现功能1.调用文本文件里的用户信息2.可以将注册信息存储在文本文件里3.实现了密码格式的限制具体用户信息将如下格式存储在txt文本文件下转换后便于代码利用的格式(列表中嵌套字典)具体代码如下:#-*-coding=utf8-*-#@author:sololi#date:2020/11/3#文件说…

  • idea 2022激活码 csdn【2022最新】

    (idea 2022激活码 csdn)最近有小伙伴私信我,问我这边有没有免费的intellijIdea的激活码,然后我将全栈君台教程分享给他了。激活成功之后他一直表示感谢,哈哈~https://javaforall.cn/100143.htmlIntelliJ2021最新激活注册码,破解教程可免费永久激活,亲测有效,上面是详细链接哦~FZP9…

  • IDEA 安装步骤「建议收藏」

    IDEA 安装步骤「建议收藏」1、下载与安装下载地址:https://www.jetbrains.com下载完成后安装选择安装的位置安装完成激活码:K03CHKJCFT-eyJsaWNlbnNlSWQiOiJLMDNDSEtKQ0ZUIiwibGljZW5zZWVOYW1lIjoibnNzIDEwMDEiLCJhc3NpZ25lZU5hbWUiOiIiLCJhc3NpZ25lZUVtYWlsIjoi…

  • adminLTE的介绍

    adminLTE的介绍一.adminLTE的介绍adminLTE的官方网站:adminLTE官方网站和github:adminLTE的github演示地址:adminLTE演示地址adminLTE是基于bootstrap3的前端框架,并且将bootstrap3进行修改来适应自身的样式。adminLTE除了可以使用bootstrap3的大多数样式之外,自身也提供了一些非常实用的样式包装,并且在样式演

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号