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", );
$this->serv->set(array(
'worker_num' => ,
'daemonize' => false,
'max_request' => ,
'dispatch_mode' => ,
'task_worker_num' => ,
'task_ipc_mode' => ,
'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 = () * ;
if ($timeon > ) {
$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", , ) ) {
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

 

swoole是如何实现任务定时自动化调度的?的更多相关文章

  1. swoole实现任务定时自动化调度详解

    开发环境 环境:lnmp下进行试验 问题描述 这几天做银行对帐接口时,踩了一个坑,具体需求大致描述一下. 银行每天凌晨后,会开始准备昨天的交易流水数据,需要我们这边请求拿到. 因为他们给的是一个bas ...

  2. 10万级etl批量作业自动化调度工具Taskctl之轻量级Web应用版

    什么是批量作业: 批量处理是银行业整个信息后台最为重要的技术形态,也是银行核心信息资产数据的分享.传输.演化的重要技术手段.有调查指出,全球70%的数据是经过批量处理得以再次使用,可见批量处理在整个信 ...

  3. 开源作业调度工具实现开源的Datax、Sqoop、Kettle等ETL工具的作业批量自动化调度

    1.阿里开源软件:DataX DataX 是一个异构数据源离线同步工具,致力于实现包括关系型数据库(MySQL.Oracle等).HDFS.Hive.ODPS.HBase.FTP等各种异构数据源之间稳 ...

  4. DW/BI领域的自动化调度方案

    1,利用专用自动化工具:如Tidal,Ctrl-M,Jenkins等.特点是功能强大,可以调用各种平台程序,脚本,可以设置依赖关系,调度时间,可以监控运行状态,发送邮件. 2,利用工具自身携带的调度功 ...

  5. ETL作业自动化调度软件TASKCTL4.5安装程序是选项解释

    下文仅针对TASKCTL4.5有效,在执行安装程序后,会看到安装程序有4个选项,其中,1和2是需要了解的. 1, 典型安装: 这个选项是单机部署,在第一次使用TASKCTL的时候,我用的是这种安装方式 ...

  6. java定时调度器解决方案分类及特性介绍

    什么是定时调度器? 我们知道程序的运行要么是由事件触发的,而这种事件的触发源头往往是用户通过ui交互操作层层传递过来的:但是我们知道还有另外一种由机器系统时间触发的程序运行场景.大家想想是否遇到或者听 ...

  7. LBPL--基于Asp.net、 quartz.net 快速开发定时服务的插件化项目

    LBPL 这一个基于Asp.net. quartz.net 快速开发定时服务的插件化项目 由于在实际项目开发中需要做定时服务的操作,大体上可以理解为:需要动态化监控定时任务的调度系统. 为了实现快速开 ...

  8. 3分钟学会如何调度运营海量Redis系统

    本文由云+社区发表 作者:冯伟源 作者:冯伟源,高级工程师,腾讯云Redis系统运维负责人.6年DBA经验,一直从事SQL优化.实例调优.数据库架构.海量数据库集群运维.运营平台建设和管理等工作.为 ...

  9. Jenkins自动化构建python nose测试

    [本文出自天外归云的博客园] 简介 通过Jenkins自动化构建python nose测试分两步: 1. 创建节点(节点就是执行自动化测试的机器): 2. 创建任务并绑定节点(用指定的机器来跑我们创建 ...

随机推荐

  1. mybatis中的动态SQL语句

    有时候,静态的SQL语句并不能满足应用程序的需求.我们可以根据一些条件,来动态地构建 SQL语句. 例如,在Web应用程序中,有可能有一些搜索界面,需要输入一个或多个选项,然后根据这些已选择的条件去执 ...

  2. USACO 2007 November Silver Best Cow Line /// oj21653

    题目大意: 输入n 接下来n行字母 在队头和队尾中选出较小的放入新的队列 Sample Input 6ACDBCB Sample Output ABCBCD   注意相同的情况 先判断内层的大小 输出 ...

  3. centos yum install 找不到软件包

    yum install epel-release 然后再试试yum install 其他安装包

  4. Spark RDD API(scala)

    1.RDD RDD(Resilient Distributed Dataset弹性分布式数据集)是Spark中抽象的数据结构类型,任何数据在Spark中都被表示为RDD.从编程的角度来看,RDD可以简 ...

  5. [转]Visual Studio 各版本下载

    原文地址:[置顶] Visual Studio 各版本下载 文件名称 文件大小 百度网盘下载 微软官方下载 Visual Studio 2015 Enterprise - 企业版 - 简体中文 3.8 ...

  6. Shell 学习(二)

    目录 Shell 学习(二) 1 设置环境变量 1.1 基本语法 1.2 实践 2 位置参数变量 2.1 介绍 2.2 基本语法 2.3 位置参数变量应用实例 3 预定义变量 3.1 基本介绍 3.2 ...

  7. Centos7 pxe

    yum install dnsmasq mv /etc/dnsmasq.conf /etc/dnsmasq.conf.backup # vim /etc/dnsmasq.conf interface= ...

  8. Windows服务调试状态下用Console启动

    最近一直在用服务,发现服务也没有那么难调试. Windows服务调试状态下用Console启动:步骤分两步 第一步改Program,启动代码 static class Program { /// &l ...

  9. Python学习笔记(六)——类和对象

    1.self的用法 全面理解self 2. 继承 子类继承父类,自动拥有父类的全部方法 >>> class Animal: def run(self): print('Animal ...

  10. [笔记]Laravel TDD 胡乱记录

    TDD: 测试驱动开发(Test-Driven Development),TDD的原理是在开发功能代码之前,先编写单元测试用例代码,测试代码确定需要编写什么产品代码. -- 载自TDD百度百科 参考 ...