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日期时间函数的高级应用技巧
May 16 PHP
PHP中文分词的简单实现代码分享
Jul 17 PHP
PHP抽象类 介绍
Jun 13 PHP
php中通过数组进行高效随机抽取指定条记录的算法
Sep 09 PHP
PHP贪婪算法解决0-1背包问题实例分析
Mar 23 PHP
php正则preg_replace_callback函数用法实例
Jun 01 PHP
yii权限控制的方法(三种方法)
Dec 28 PHP
php使用变量动态创建类的对象用法示例
Feb 06 PHP
php面向对象之反射功能与用法分析
Mar 29 PHP
laravel如何开启跨域功能示例详解
Aug 31 PHP
PHP实现简单的协程任务调度demo示例
Feb 01 PHP
php高性能日志系统 seaslog 的安装与使用方法分析
Feb 29 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+MYSQL会员系统的开发实例教程
2014/08/23 PHP
jQuery+PHP发布的内容进行无刷新分页(Fckeditor)
2015/10/22 PHP
Laravel使用原生sql语句并调用的方法
2019/10/09 PHP
PHP安装扩展mcrypt以及相关依赖项深入讲解
2021/03/04 PHP
javascript动画浅析
2012/08/30 Javascript
jQuery ui插件的使用方法代码实例
2013/05/08 Javascript
javascript 实现键盘上下左右功能的小例子
2013/09/15 Javascript
javascript代码运行不出来执行错误的可能情况整理
2013/10/18 Javascript
JavaScript中的普通函数与构造函数比较
2015/04/07 Javascript
《JavaScript高级编程》学习笔记之object和array引用类型
2015/11/01 Javascript
日常收藏的jquery技巧
2015/12/02 Javascript
一步一步封装自己的HtmlHelper组件BootstrapHelper(三)
2016/09/14 Javascript
教大家轻松制作Bootstrap漂亮表格(table)
2016/12/13 Javascript
JScript实现地址选择功能
2017/08/15 Javascript
Vue项目全局配置微信分享思路详解
2018/05/04 Javascript
layui在form表单页面通过Validform加入简单验证的方法
2019/09/06 Javascript
[05:42]DOTA2英雄梦之声_第10期_蝙蝠骑士
2014/06/21 DOTA
python下os模块强大的重命名方法renames详解
2017/03/07 Python
Python Json序列化与反序列化的示例
2018/01/31 Python
Python cookbook(数据结构与算法)将序列分解为单独变量的方法
2018/02/13 Python
对python中Matplotlib的坐标轴的坐标区间的设定实例讲解
2018/05/25 Python
python中从str中提取元素到list以及将list转换为str的方法
2018/06/26 Python
华为2019校招笔试题之处理字符串(python版)
2019/06/25 Python
mac系统下Redis安装和使用步骤详解
2019/07/09 Python
Python描述数据结构学习之哈夫曼树篇
2020/09/07 Python
处理textarea中的换行和空格
2019/12/12 HTML / CSS
加拿大最大的体育用品、鞋类和服装零售商:Sport Chek
2018/11/29 全球购物
英国水族馆和池塘用品购物网站:Warehouse Aquatics
2019/08/29 全球购物
现代绅士日常奢侈品:Todd Snyder
2019/12/13 全球购物
小学新学期寄语
2014/04/02 职场文书
七一慰问简报
2015/07/20 职场文书
法制主题班会教案
2015/08/13 职场文书
2019年第四季度财务部门工作计划
2019/11/02 职场文书
祝福语集锦:给百岁老人祝寿贺词
2019/11/19 职场文书
Python爬虫中urllib3与urllib的区别是什么
2021/07/21 Python
Windows Server 2016服务器用户管理及远程授权图文教程
2022/08/14 Servers