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 相关文章推荐
无限级别菜单的实现
Oct 09 PHP
PHP 编程请选择正确的文本编辑软件
Dec 21 PHP
GBK的页面输出JSON格式的php函数
Feb 16 PHP
php设计模式 Strategy(策略模式)
Jun 26 PHP
PHP获取和操作配置文件php.ini的几个函数介绍
Jun 24 PHP
php上传图片并压缩的实现方法
Dec 22 PHP
PHP二分查找算法示例【递归与非递归方法】
Sep 29 PHP
PHP CURL与java http使用方法详解
Jan 26 PHP
php实现微信支付之退款功能
May 30 PHP
php封装的pdo数据库操作工具类与用法示例
May 08 PHP
在laravel中实现事务回滚的方法
Oct 10 PHP
PHP实现获取文件mime类型多种方法解析
May 28 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
PHP初学者头疼问题总结
2006/07/08 PHP
PHP和Mysqlweb应用开发核心技术 第1部分 Php基础-1 开始了解php
2011/07/03 PHP
PHP和Mysqlweb应用开发核心技术 第1部分 Php基础-3 代码组织和重用2
2011/07/03 PHP
php中计算中文字符串长度、截取中文字符串的函数代码
2011/08/09 PHP
解析thinkphp的左右值无限分类
2013/06/20 PHP
php实现mysql封装类示例
2014/05/07 PHP
mysql desc(DESCRIBE)命令实例讲解
2016/09/24 PHP
基于Jquery实现的一个图片滚动切换
2012/06/21 Javascript
javascript移动设备Web开发中对touch事件的封装实例
2014/06/05 Javascript
JavaScript函数作用域链分析
2015/02/13 Javascript
JS获取iframe中marginHeight和marginWidth属性的方法
2015/04/01 Javascript
实现前后端数据交互方法汇总
2015/04/07 Javascript
jQuery+CSS3折叠卡片式下拉列表框实现效果
2015/11/02 Javascript
AngularJS实现Model缓存的方式
2016/02/03 Javascript
jQuery图片前后对比插件beforeAfter用法示例【附demo源码下载】
2016/09/20 Javascript
JavaScript  event对象整理及详细介绍
2016/10/10 Javascript
Jquery通过ajax请求NodeJS返回json数据实例
2016/11/08 NodeJs
浅谈JS读取DOM对象(标签)的自定义属性
2016/11/21 Javascript
Bootstrap基本组件学习笔记之缩略图(13)
2016/12/08 Javascript
React-intl 实现多语言的示例代码
2017/11/03 Javascript
微信小程序商品详情页的底部弹出框效果
2020/11/16 Javascript
JavaScript判断对象和数组的两种方法
2019/05/31 Javascript
微信小程序聊天功能的示例代码
2020/01/13 Javascript
layui实现显示数据表格、搜索和修改功能示例
2020/06/03 Javascript
[48:46]完美世界DOTA2联赛PWL S2 SZ vs FTD.C 第二场 11.19
2020/11/19 DOTA
python使用rsa加密算法模块模拟新浪微博登录
2014/01/22 Python
python实现简单爬虫功能的示例
2016/10/24 Python
python 根据pid杀死相应进程的方法
2017/01/16 Python
django 修改server端口号的方法
2018/05/14 Python
浅谈Python反射 &amp; 单例模式
2019/03/21 Python
pygame实现贪吃蛇游戏(下)
2019/10/29 Python
自动化职业生涯规划书范文
2014/01/03 职场文书
市政管理求职信范文
2014/05/07 职场文书
2014员工聘用协议书(最新版)
2014/11/24 职场文书
教师廉洁自律个人总结
2015/02/10 职场文书
大学团日活动总结书
2015/05/11 职场文书