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来处理多个提交任务
Oct 09 PHP
PHP脚本的10个技巧(7)
Oct 09 PHP
在PHP中使用反射技术的架构插件使用说明
May 18 PHP
php class类的用法详细总结
Oct 17 PHP
调试PHP程序的多种方法介绍
Nov 06 PHP
php采用curl实现伪造IP来源的方法
Nov 21 PHP
php+mysql实现无限级分类
Nov 11 PHP
php bootstrap实现简单登录
Mar 08 PHP
PHP7新特性foreach 修改示例介绍
Aug 26 PHP
使用Codeigniter重写insert的方法(推荐)
Mar 23 PHP
PHP微信公众号开发之微信红包实现方法分析
Jul 14 PHP
Laravel框架路由和控制器的绑定操作方法
Jun 12 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中使用Curl、socket、file_get_contents三种方法POST提交数据
2011/08/12 PHP
php实现与erlang的二进制通讯实例解析
2014/07/23 PHP
PHP观察者模式原理与简单实现方法示例
2017/08/25 PHP
解决jQuery插件tipswindown与hintbox冲突
2010/11/05 Javascript
jquery ajax提交整个表单元素的快捷办法
2013/03/27 Javascript
js兼容pc端浏览器并有多种弹出小提示的手机端浮层控件实例
2015/04/29 Javascript
JS获取当前使用的浏览器名字以及版本号实现方法
2016/08/19 Javascript
Bootstrap Modal对话框如何在关闭时触发事件
2016/12/02 Javascript
很棒的一组js图片轮播特效
2017/01/12 Javascript
JavaScript中in和hasOwnProperty区别详解
2017/08/04 Javascript
深入了解js原型模式
2019/05/30 Javascript
vue中利用Promise封装jsonp并调取数据
2019/06/18 Javascript
vue实现在线预览pdf文件和下载(pdf.js)
2019/11/26 Javascript
vue 动态设置img的src地址无效,npm run build 后找不到文件的解决
2020/07/26 Javascript
[03:07]【DOTA2亚洲邀请赛】我们,梦开始的地方
2017/03/07 DOTA
浅谈编码,解码,乱码的问题
2016/12/30 Python
python用户管理系统
2018/03/13 Python
Python设计模式之迭代器模式原理与用法实例分析
2019/01/10 Python
python实现websocket的客户端压力测试
2019/06/25 Python
手把手教你pycharm专业版安装破解教程(linux版)
2019/09/26 Python
Window10下python3.7 安装与卸载教程图解
2019/09/30 Python
解决TensorFlow模型恢复报错的问题
2020/02/06 Python
解决python3插入mysql时内容带有引号的问题
2020/03/02 Python
python 如何上传包到pypi
2020/12/24 Python
Links of London官方网站:英国标志性的珠宝品牌
2017/04/09 全球购物
丝芙兰香港官网:Sephora香港
2018/03/13 全球购物
金士达面试非笔试
2012/03/14 面试题
Ajxa常见问题都有哪些
2014/03/26 面试题
职业女性的职业规划
2014/03/04 职场文书
内科护士节演讲稿
2014/09/11 职场文书
党的群众路线教育实践活动党员个人整改措施
2014/10/27 职场文书
学校党的群众路线教育实践活动制度建设计划
2014/11/03 职场文书
2014年客服工作总结范文
2014/11/13 职场文书
和谐家庭事迹材料
2014/12/20 职场文书
领导欢迎词致辞
2015/01/23 职场文书
Spring Boot接口定义和全局异常统一处理
2022/04/20 Java/Android