swoole实现任务定时自动化调度详解
开发环境
环境:lnmp下进行试验
问题描述
这几天做银行对帐接口时,踩了一个坑,具体需求大致描述一下。
银行每天凌晨后,会开始准备昨天的交易流水数据,需要我们这边请求拿到。
因为他们给的是一个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();
}
}
}
swoole实现任务定时自动化调度详解的更多相关文章
- Kubernetes K8S之固定节点nodeName和nodeSelector调度详解
Kubernetes K8S之固定节点nodeName和nodeSelector调度详解与示例 主机配置规划 服务器名称(hostname) 系统版本 配置 内网IP 外网IP(模拟) k8s-mas ...
- Quartz.Net实现作业定时调度详解
1.Quartz.NET介绍 Quartz.NET是一个强大.开源.轻量的作业调度框架,你能够用它来为执行一个作业而创建简单的或复杂的作业调度.它有很多特征,如:数据库支持,集群,插件,支持cron- ...
- swoole是如何实现任务定时自动化调度的?
https://www.muzilong.cn/article/117 开发环境 环境:lnmp下进行试验. 框架:laravel5 问题描述 这几天做银行对帐接口时,踩了一个坑,具体需求大致描述一下 ...
- quartz实现定时功能实例详解(servlet定时器配置方法)
Quartz是一个完全由java编写的开源作业调度框架,下面提供一个小例子供大家参考,还有在servlet配置的方法 Quartz是一个完全由java编写的开源作业调度框架,具体的介绍可到http:/ ...
- 如何做ui自动化---步骤详解
第一步: 得到功能测试的常规用例,查看是否可以进行自动化,要明确,自动化不是为了自动化而自动化,自动化是节省人力,主要做回归测试,如果变动性特别大,不建议做自动化,具体可查看其它文章“什么适合做自动化 ...
- Python定时框架 Apscheduler 详解【转】
内容来自网络: https://www.cnblogs.com/luxiaojun/p/6567132.html 在平常的工作中几乎有一半的功能模块都需要定时任务来推动,例如项目中有一个定时统计程序, ...
- 资深实践篇 | 基于Kubernetes 1.61的Kubernetes Scheduler 调度详解
欢迎大家前往腾讯云技术社区,获取更多腾讯海量技术实践干货哦~ 作者:腾讯云容器服务团队 源码为 k8s v1.6.1 版本,github 上对应的 commit id 为 b0b7a323cc5a4a ...
- Linux下的crontab定时执行任务详解
在LINUX中,周期执行的任务一般由cron这个守护进程来处理[ps -ef|grep cron].cron读取一个或多个配置文件,这些配置文件中包含了命令行及其调用时间.cron的配置文件称为“cr ...
- Appium+python自动化21-DesiredCapabilities详解
Appium Desired Capabilities Desired Capabilities 是由 keys 和 values 组成的 JSON 对象. 举个简单例子: { "platf ...
随机推荐
- struct位域
1 总结下 结构体位域的使用 比如 则 struct _COM2 { u8 Len : 1;//低位 u8 EoN : 2; u8 Stop:1; u8 Bps:4;//高位 } union COM ...
- 第七章 DevOps工具链
DevOps工具生态圈 协同开发工具 敏捷开发 可视化 加强团队沟通协作 数据分析 协同开发 持续集成工具 Jenkins 自动化编译 自动化测试 自动化部署 丰富的插件库 版本管理工具 Git 简介 ...
- Jquery的load加载本地文件出现跨域错误的解决方案"Access to XMLHttpRequest at 'file:///android_asset/web/graph.json' from(Day_46)
博主是通过JS调用本地的一个json文件赋值给变量出现的跨域错误, 网上有大量文章,五花八门的,但总归,一般性此问题基本可通过这三种方法解决: https://blog.csdn.net/qq_418 ...
- 【ArcGIS遇上Python】ArcGIS Python批处理入门到精通实用教程目录
目录 1. 专栏简介 2. 专栏地址 3. 专栏目录 1. 专栏简介 Python语言是目前很火热的语言,极大的促进了人工智能发展.你知道在ArcGIS中也会有python的身影吗?事实上,在ArcG ...
- mysql数据库-备份方式简介与规范
目录 1 应对场景: 2. 备份方式分类 2.1 按备份数据类型划分 2.2 按侵入程度划分 2.3 按备份方式划分 3 备份注意要点 4 还原要点 4.1 定期还原测试,验证备份可用性 4.2 还原 ...
- Could not get JDBC Connection排查
最近在维护的一个比较旧的项目,发现总是隔一段时间JDBC就报错: Could not get JDBC Connection; nested exception is org.apache.commo ...
- python批量向kafka塞数据
python批量向kafka塞数据 from kafka import KafkaClient from kafka.producer import SimpleProducer from kafka ...
- node.js学习(7)流和管道
1 导入模块 输入流 # 读取流 # 写入流 # # 管道 # 压缩 # 解压缩
- Eclipse修改方法内容不用重启Jetty服务器
我Eclipse以前DEBUG模式时,修改方法里的内容是不用重启的, 现在修改方法里是一行代码都要重启服务器了,很麻烦,速度慢了,找了百度,那些方法对我不合适,可能遇到的问题不一样. 也许会合适遇到和 ...
- JS使用Enter事件将输入的字符倒叙输出
在JavaScript中执行当用户按下Enter键位时将用户输入的字符倒叙输出! HTML代码: <body> <form id="form1" runat=&q ...