PHP扩展Swoole实现实时异步任务队列示例


Posted in PHP onApril 13, 2019

本文实例讲述了PHP扩展Swoole实现实时异步任务队列。分享给大家供大家参考,具体如下:

假如要发100封邮件,for循环100遍,用户直接揭竿而起,什么破网站!

但实际上,我们很可能有超过1万的邮件。怎么处理这个延迟的问题?

答案就是用异步。把“发邮件”这个操作封装,然后后台异步地执行1万遍。这样的话,用户提交网页后,他所等待的时间只是“把发邮件任务请求推送进队列里”的时间。而我们的后台服务将在用户看不见的地方跑。

在实现“异步队列”这点上,有人采用MySQL表或者redis来存放待发送的邮件,然后,每分钟定时读取待发送列表,然后处理。这便是定时异步任务队列。但当前提交的任务要一分钟后才能执行,在某些实时性要求应用场景里还是不快。有些场景要求,只有一提交任务,便马上执行,但用户不需要等待返回结果。

本文将探讨用php扩展swoole实现实时异步任务队列的方案。

服务端

在打算放置脚本的目录(你也可以自行新建)新建Server.php,代码如下

<?php
class Server
{
  private $serv;
  public function __construct()
  {
    $this->serv = new swoole_server("0.0.0.0", 9501);
    $this->serv->set(array(
      'worker_num' => 1, //一般设置为服务器CPU数的1-4倍
      'daemonize' => 1, //以守护进程执行
      'max_request' => 10000,
      'dispatch_mode' => 2,
      'task_worker_num' => 8, //task进程的数量
      "task_ipc_mode " => 3, //使用消息队列通信,并设置为争抢模式
      //"log_file" => "log/taskqueueu.log" ,//日志
    ));
    $this->serv->on('Receive', array($this, 'onReceive'));
    // bind callback
    $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)
  {
    //echo "Get Message From Client {$fd}:{$data}\n";
    // send a task to task worker.
    $serv->task($data);
  }
  public function onTask($serv, $task_id, $from_id, $data)
  {
    $array = json_decode($data, true);
    if ($array['url']) {
      return $this->httpGet($array['url'], $array['param']);
    }
  }
  public function onFinish($serv, $task_id, $data)
  {
    //echo "Task {$task_id} finish\n";
    //echo "Result: {$data}\n";
  }
  protected function httpGet($url, $data)
  {
    if ($data) {
      $url .= '?' . http_build_query($data);
    }
    $curlObj = curl_init(); //初始化curl,
    curl_setopt($curlObj, CURLOPT_URL, $url); //设置网址
    curl_setopt($curlObj, CURLOPT_RETURNTRANSFER, 1); //将curl_exec的结果返回
    curl_setopt($curlObj, CURLOPT_SSL_VERIFYPEER, FALSE);
    curl_setopt($curlObj, CURLOPT_SSL_VERIFYHOST, FALSE);
    curl_setopt($curlObj, CURLOPT_HEADER, 0); //是否输出返回头信息
    $response = curl_exec($curlObj); //执行
    curl_close($curlObj); //关闭会话
    return $response;
  }
}
$server = new Server();

客户端

启动服务后,让我们看看如何调用服务。新建测试文件Client_test.php

<?php
class Client
{
  private $client;
  public function __construct()
  {
    $this->client = new swoole_client(SWOOLE_SOCK_TCP);
  }
  public function connect()
  {
    if (!$this->client->connect("127.0.0.1", 9501, 1)) {
      throw new Exception(sprintf('Swoole Error: %s', $this->client->errCode));
    }
  }
  public function send($data)
  {
    if ($this->client->isConnected()) {
      if (!is_string($data)) {
        $data = json_encode($data);
      }
      return $this->client->send($data);
    } else {
      throw new Exception('Swoole Server does not connected.');
    }
  }
  public function close()
  {
    $this->client->close();
  }
}
$data = array(
  "url" => "http://192.168.10.19/send_mail",
  "param" => array(
    "username" => 'test',
    "password" => 'test'
  )
);
$client = new Client();
$client->connect();
if ($client->send($data)) {
  echo 'success';
} else {
  echo 'fail';
}
$client->close();

在上面代码中,url即为任务所在地址,param为所需传递参数。

保存好代码,在命令行或者浏览器中执行Client_test.php,便实现了异步任务队列。你所填写的URL,将会在每次异步任务被提交后,以HTTP GET的方式异步执行。

希望本文所述对大家PHP程序设计有所帮助。

PHP 相关文章推荐
用PHP制作的意见反馈表源码
Mar 11 PHP
PHP MemCached 高级缓存应用代码
Aug 05 PHP
php伪静态之APACHE篇
Jun 02 PHP
PHP页面实现定时跳转的方法
Oct 31 PHP
php短网址和数字之间相互转换的方法
Mar 13 PHP
php+js实现百度地图多点标注的方法
Nov 30 PHP
Yii2中多表关联查询hasOne hasMany的方法
Feb 15 PHP
PHP实现基于图的深度优先遍历输出1,2,3...n的全排列功能
Nov 10 PHP
PHP设计模式之装饰器模式实例详解
Feb 07 PHP
PHP结合Ffmpeg快速搭建流媒体服务的实践记录
Oct 31 PHP
PHP信号处理机制的操作代码讲解
Apr 19 PHP
PHP图像处理 imagestring添加图片水印与文字水印操作示例
Feb 06 PHP
php+ajax实现商品对比功能示例
Apr 13 #PHP
PHP开发的文字水印,缩略图,图片水印实现类与用法示例
Apr 12 #PHP
详解PHP素材图片上传、下载功能
Apr 12 #PHP
laravel 事件/监听器实例代码
Apr 12 #PHP
Laravel5.7 数据库操作迁移的实现方法
Apr 12 #PHP
laravel使用Faker数据填充的实现方法
Apr 12 #PHP
Laravel5.7 Eloquent ORM快速入门详解
Apr 12 #PHP
You might like
一些操作和快捷键的理解和讨论
2020/03/04 星际争霸
php定义数组和使用示例(php数组的定义方法)
2014/03/29 PHP
php自定义urlencode,urldecode函数实例
2015/03/24 PHP
php实现微信公众平台账号自定义菜单类
2015/10/11 PHP
PHP根据树的前序遍历和中序遍历构造树并输出后序遍历的方法
2017/11/10 PHP
jQuery 获取对象 定位子对象
2010/05/31 Javascript
jquery 之 $().hover(func1, funct2)使用方法
2012/06/14 Javascript
JS注释所产生的bug 即使注释也会执行
2013/11/19 Javascript
使用jQuery和PHP实现类似360功能开关效果
2014/02/12 Javascript
JavaScript中的object转换函数toString()与valueOf()介绍
2014/12/31 Javascript
JS+CSS实现带关闭按钮DIV弹出窗口的方法
2015/02/27 Javascript
Linux CentOS系统下安装node.js与express的方法
2017/04/01 Javascript
JavaScript基础教程之如何实现一个简单的promise
2018/09/11 Javascript
小程序登录/注册页面设计的实现代码
2019/05/24 Javascript
vue element自定义表单验证请求后端接口验证
2019/12/11 Javascript
JavaScript实现栈结构Stack过程详解
2020/03/07 Javascript
[01:25]2014DOTA2国际邀请赛 zhou分析LGD比赛情况
2014/07/14 DOTA
给Python IDLE加上自动补全和历史功能
2014/11/30 Python
简单介绍Python下自己编写web框架的一些要点
2015/04/29 Python
python PyTorch参数初始化和Finetune
2018/02/11 Python
matplotlib调整子图间距,调整整体空白的方法
2018/08/03 Python
Python的iOS自动化打包实例代码
2018/11/22 Python
解决使用PyCharm时无法启动控制台的问题
2019/01/19 Python
解决python中画图时x,y轴名称出现中文乱码的问题
2019/01/29 Python
python 利用pandas将arff文件转csv文件的方法
2019/02/12 Python
pyqt5 从本地选择图片 并显示在label上的实例
2019/06/13 Python
PIL图像处理模块paste方法简单使用详解
2019/07/17 Python
python利用JMeter测试Tornado的多线程
2020/01/12 Python
pytorch 实现在一个优化器中设置多个网络参数的例子
2020/02/20 Python
python 解压、复制、删除 文件的实例代码
2020/02/26 Python
Python之Matplotlib文字与注释的使用方法
2020/06/18 Python
名词解释WEB SERVICE,SOAP,UDDI,WSDL,JAXP,JAXM;JSWDL开发包的介绍。
2012/10/27 面试题
医学专业五年以上个人求职信
2013/12/03 职场文书
《我的信念》教学反思
2014/02/15 职场文书
单位作风建设剖析材料
2014/10/11 职场文书
Python四款GUI图形界面库介绍
2022/06/05 Python