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中选择什么接口(mysql、mysqli)访问mysql
Feb 06 PHP
基于php冒泡排序算法的深入理解
Jun 09 PHP
php猴子选大王问题解决方法
May 12 PHP
PHP发送短信代码分享
Aug 11 PHP
基于PHP实现假装商品限时抢购繁忙的效果
Oct 16 PHP
浅析Yii2 GridView 日期格式化并实现日期可搜索教程
Apr 22 PHP
全面解析PHP操作Memcache基本函数
Jul 14 PHP
PHP中文字符串截断无乱码解决方法
Oct 10 PHP
浅谈socket同步和异步、阻塞和非阻塞、I/O模型
Dec 15 PHP
PHP FileSystem 文件系统常用api整理总结
Jul 12 PHP
TP5框架model常见操作示例小结【增删改查、聚合、时间戳、软删除等】
Apr 05 PHP
WordPress伪静态规则设置代码实例
Dec 10 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中的闭包和匿名函数
2017/12/25 PHP
phpQuery采集网页实现代码实例
2020/04/02 PHP
php实现对短信验证码发送次数的限制实例讲解
2021/03/04 PHP
Javascript实例教程(19) 使用HoTMetal(2)
2006/12/23 Javascript
JQuery 解析多维的Json数据格式
2009/11/02 Javascript
图片Slider 带左右按钮的js示例
2013/08/30 Javascript
php读取sqlite数据库入门实例代码
2014/06/25 Javascript
JavaScript中的substr()方法使用详解
2015/06/06 Javascript
JavaScript forEach()遍历函数使用及介绍
2015/07/08 Javascript
学习JavaScript设计模式(代理模式)
2015/12/03 Javascript
简单的jQuery banner图片轮播实例代码
2016/03/04 Javascript
jQuery实现的placeholder效果完整实例
2016/08/02 Javascript
D3.js实现直方图的方法详解
2016/09/25 Javascript
JS实现拖动滚动条评分的效果代码分享
2016/09/29 Javascript
Bootstrap CSS布局之按钮
2016/12/17 Javascript
windows下vue-cli导入bootstrap样式
2017/04/25 Javascript
NodeJs模拟登陆正方教务
2017/04/28 NodeJs
详解vue数组遍历方法forEach和map的原理解析和实际应用
2018/11/15 Javascript
jquery+css实现Tab栏切换的代码实例
2019/05/14 jQuery
Vue发布项目实例讲解
2019/07/17 Javascript
vue 点击其他区域关闭自定义div操作
2020/07/17 Javascript
Vue-resource安装过程及使用方法解析
2020/07/21 Javascript
Python基于回溯法解决01背包问题实例
2017/12/06 Python
Python字节单位转换实例
2019/12/05 Python
django model 条件过滤 queryset.filter(**condtions)用法详解
2020/05/20 Python
Python pip安装模块提示错误解决方案
2020/05/22 Python
市场营销毕业生自荐信
2013/11/23 职场文书
企业统计员岗位职责
2013/12/13 职场文书
人力资源部经理岗位职责规定
2014/02/23 职场文书
槐乡的孩子教学反思
2014/04/27 职场文书
解除租房协议书
2014/12/03 职场文书
总经理助理岗位职责范本
2015/03/31 职场文书
2015年行政助理工作总结
2015/04/30 职场文书
2016年三八红旗手先进事迹材料
2016/02/26 职场文书
总结Python使用过程中的bug
2021/06/18 Python
恶魔之树最顶端的三颗果实 震震果实上榜,第一可以制造岩浆
2022/03/18 日漫