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 相关文章推荐
一个数据采集类
Feb 14 PHP
php 中的4种标记风格介绍
May 10 PHP
php DOS攻击实现代码(附如何防范)
May 29 PHP
php实现多张图片上传加水印技巧
Apr 18 PHP
PHP中的函数-- foreach()的用法详解
Jun 24 PHP
Laravel框架表单验证详解
Sep 04 PHP
PHP针对JSON操作实例分析
Jan 12 PHP
PHP简单实现断点续传下载的方法
Sep 25 PHP
php批量删除超链接的实现方法
Oct 19 PHP
深入理解PHP之OpCode原理详解
Jun 01 PHP
Yii2创建控制器(createController)方法详解
Jul 23 PHP
php处理静态页面:页面设置缓存时间实例
Jun 22 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 - Html Transfer Code
2006/10/09 PHP
使用php+apc实现上传进度条且在IE7下不显示的问题解决方法
2013/04/25 PHP
PHP怎么实现网站保存快捷方式方便用户随时浏览
2013/08/15 PHP
网页上facebook分享功能具体实现
2014/01/26 PHP
PHP中抽象类、接口的区别与选择分析
2016/03/29 PHP
PHP基于接口技术实现简单的多态应用完整实例
2017/04/26 PHP
基于jQuery的弹出警告对话框美化插件(警告,确认和提示)
2010/06/10 Javascript
Fastest way to build an HTML string(拼装html字符串的最快方法)
2011/08/20 Javascript
js 手机号码合法性验证代码集合
2012/09/29 Javascript
jQuery获得指定元素坐标的方法
2015/04/14 Javascript
根据user-agent判断蜘蛛代码黑帽跳转代码(js版与php版本)
2015/09/14 Javascript
实例讲解jQuery EasyUI tree中state属性慎用
2016/04/01 Javascript
ES6所改良的javascript“缺陷”问题
2016/08/23 Javascript
简单谈谈Javascript函数中的arguments
2017/02/09 Javascript
jQuery实现节点的追加、替换、删除、复制功能示例
2017/07/11 jQuery
node.js-v6新版安装具体步骤(分享)
2017/09/06 Javascript
用React-Native+Mobx做一个迷你水果商城APP(附源码)
2017/12/25 Javascript
微信小程序webview 脚手架使用详解
2019/07/22 Javascript
微信接入之获取用户头像的方法步骤
2019/09/23 Javascript
JS实现页面数据懒加载
2020/02/13 Javascript
JavaScript实现网页留言板功能
2020/11/23 Javascript
python从网络读取图片并直接进行处理的方法
2015/05/22 Python
Django ORM框架的定时任务如何使用详解
2017/10/19 Python
python Celery定时任务的示例
2018/03/13 Python
python微信公众号之关注公众号自动回复
2018/10/25 Python
浅析Python 抽象工厂模式的优缺点
2020/07/13 Python
pandas 数据类型转换的实现
2020/12/29 Python
CSS3中animation实现流光按钮效果
2020/12/21 HTML / CSS
HTML5 Web 存储详解
2016/09/16 HTML / CSS
财务副总经理工作职责
2013/11/25 职场文书
积极向上的团队口号
2014/06/06 职场文书
房屋转让协议书
2014/10/18 职场文书
昆虫记读书笔记
2015/06/26 职场文书
英语读书笔记
2015/07/02 职场文书
工作感言一句话
2015/08/01 职场文书
应用最多的公文《通知》如何写?
2019/04/02 职场文书