用swoole实现异步任务队列
应用场景如下:
假如要发100封邮件,for循环100遍,这种方法显然是不可取的。
在一些比较繁杂的业务里,我们很可能有超过1万的邮件要群发。那我们怎么处理这个延迟的问题?
答案就是用异步。把“发邮件”这个操作封装,然后后台异步地执行1万遍。这样的话,用户提交网页后,他所等待的时间只是“把发邮件任务请求推送进队列里”的时间。而我们的后台服务将在用户看不见的地方跑。
在实现“异步队列”这点上,有人采用MySQL表或者redis来存放待发送的邮件,然后,每分钟定时读取待发送列表,然后处理。这便是定时异步任务队列。但当前提交的任务要一分钟后才能执行,在某些实时性要求高的应用场景里还是不快,比如发送短信的场景,只要一提交任务,便要马上执行,用户不需要等待返回结果。
以下将探讨用php扩展swoole实现实时异步任务队列发送短信的方案。
服务端
第一步:创建tcp服务器
第二步:设置服务器的相关属性
第三步:设置服务端的相关回调函数处理任务
具体代码如下:tcp_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'));
$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){
$serv->task($data);
}
public function onTask($serv, $task_id, $from_id, $data){
$data = json_decode($data,true);
if(!empty($data)){
return $this->sendsms($data['mobile'],$data['message']);
}
}
public function onFinish($serv, $task_id, $data){
echo "Task {$task_id} finish\n";
}
public function sendsms($mobile,$text)
{
$timestamp = date("Y-m-d H-i-s");
$pid = "888888888";
$send_sign = md5($pid.$timestamp."abcdefghijklmnopqrstuvwxyz");
$post_data = array();
$post_data['partner_id'] = $pid;
$post_data['timestamp'] =$timestamp;
$post_data['mobile'] = $mobile;
$post_data['message'] = $text;
$post_data['sign'] = $send_sign;
$url='http://182.92.149.100/sendsms';
$o="";
foreach ($post_data as $k=>$v)
{
$o.= "$k=".urlencode($v)."&";
}
$post_data=substr($o,0,-1);
$ch = curl_init();
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_URL,$url);
//为了支持cookie
//curl_setopt($ch, CURLOPT_COOKIEJAR, 'cookie.txt');
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$result = curl_exec($ch);
if(strpos($result,"success")!==false)
{
$outstr=1;
}
else
{
$outstr=502;
}
return $outstr;
}
}
$server = new Server();
?>
客户端
启动后端服务后,客户端首先创建tcp客户端服务器,然后连接tcp后端服务器,并向后端tcp服务器发送数据,具体代码如下:client.php
<?php
class Client{
public $client;
public function __construct(){
$this->client= new swoole_client(SWOOLE_SOCK_TCP);//默认同步tcp客户端,添加参数SWOOLE_SOCK_ASYNC为异步
}
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()){
$data = json_encode($data);
//print $data;
if($this->client->send($data)){
return 1;
}else{
throw new Exception(sprintf('Swoole Error: %s', $this->client->errCode));
}
}else{
throw new Exception('Swoole Server does not connected.');
}
}
public function close(){
$this->client->close();
}
}
$client= new Client();
$client->connect();
$data=array(
'mobile'=>'18511487955',
'message'=>'you mobile 18511487955'
);
if($client->send($data)){
echo 'succ';
}else{
echo 'fail';
}
?>
用swoole实现异步任务队列的更多相关文章
- Swoole来实现实时异步任务队列
假如要发100封邮件,for循环100遍,用户直接揭竿而起,什么破网站!但实际上,我们很可能有超过1万的邮件.怎么处理这个延迟的问题?答案就是用异步.把“发邮件”这个操作封装,然后后台异步地执行1万遍 ...
- PHP使用swoole来实现实时异步任务队列
转载来自第七星尘的技术博客的<PHP使用swoole来实现实时异步任务队列> 关于异步任务队列 用户打开了我们的网站.他要做的就是勾选需要发邮件的代理商列表,然后把结算邮件发出去.假如我们 ...
- 异步任务队列Celery在Django中的使用
前段时间在Django Web平台开发中,碰到一些请求执行的任务时间较长(几分钟),为了加快用户的响应时间,因此决定采用异步任务的方式在后台执行这些任务.在同事的指引下接触了Celery这个异步任务队 ...
- Django使用Celery异步任务队列
1 Celery简介 Celery是异步任务队列,可以独立于主进程运行,在主进程退出后,也不影响队列中的任务执行. 任务执行异常退出,重新启动后,会继续执行队列中的其他任务,同时可以缓存停止期间接收 ...
- redis实现异步任务队列
redis实现异步任务队列 先说思路: 将任务对象序列为JSON字符串,然后推入REDIS缓存,这叫入队. 通过独立的工作线程从REDIS拉出一个任务,这叫出队,工作线程将JSON字符串还原为任务对象 ...
- c# 异步任务队列(可选是否使用单线程执行任务,以及自动取消任务)
使用demo,(.net framework 4.0 自行添加async wait 扩展库) class Program { static void Main(string[] args) { Con ...
- Python多线程异步任务队列
原文地址 python的多线程异步常用到queue和threading模块 #!/usr/bin/env python # -*- coding: UTF-8 -*- import logging i ...
- [Flask]celery异步任务队列的使用
Celery异步任务队列 目录结构树: 配置文件config.py: # 设置中间人地址 broker_url = 'redis://127.0.0.1:6379/1' 主main.py: impor ...
- Asp-Net-Core开发笔记:集成Hangfire实现异步任务队列和定时任务
前言 最近把Python写的数据采集平台往.Net Core上迁移,原本的采集任务使用多进程+线程池的方式来加快采集速度,使用Celery作为异步任务队列兼具定时任务功能,这套东西用着还行,但反正就折 ...
随机推荐
- centos7 启动docker失败
现象:Centos7.3通过yum安装完docker后,启动docker失败 机器的系统版本:CentOS Linux release 7.3.1611 (Core) centos7,执行完安装命令: ...
- easyUI中datagrid展示对象下属性以及显示多个子属性(Day_37)
easyUI中datagrid展示对象下属性以及显示多个子属性 显示对象单个属性值 添加formatter属性 <th field="decidedzone" width=& ...
- openssl自签发证书
DOMAIN=www.example.com openssl genrsa -out ${DOMAIN}.key # 生成私有key openssl req -x509 -new -nodes -ke ...
- WEB安全防护相关响应头(下)
前篇"WEB安全防护相关响应头(上)"中,我们分享了 X-Frame-Options.X-Content-Type-Options.HTTP Strict Transport Se ...
- Django(44)drf序列化源码分析(1)
序列化与反序列化 一般后端数据返回给前端的数据格式都是json格式,简单易懂,但是我们使用的语言本身并不是json格式,像我们使用的Python如果直接返回给前端,前端用的javascript语言 ...
- THINKPHP_(4)_TP模型中with、withJoin和多层关联的深入分析
1.个人之前博文: TP模型的多表关联查询和多表字段的关键字搜索 TP6中实现多层关联,第一个表关联第二个表查询出的数据,再关联第三个表 2.withJoin的特性 2.1 第一个特性 在TP模型的多 ...
- Camera Calibration 相机标定
Camera Calibration 相机标定 一.相机标定方法 在opencv中提供了一组函数用于实现相机的标定,标定返回的值包括:相机内参矩阵(fx fy xc yc).相机外参矩阵(R t)以及 ...
- 旷视MegEngine数据加载与处理
旷视MegEngine数据加载与处理 在网络训练与测试中,数据的加载和预处理往往会耗费大量的精力. MegEngine 提供了一系列接口来规范化这些处理工作. 利用 Dataset 封装一个数据集 数 ...
- Python 5种方法实现单例模式
基本介绍 一个对象只允许被一次创建,一个类只能创建一个对象,并且提供一个全局访问点. 单例模式应该是应用最广泛,实现最简单的一种创建型模式. 特点:全局唯一,允许更改 优缺点 优点: 避免对资源的多重 ...
- Springboot自定义starter打印sql及其执行时间
前面写到了通过实现mybatis提供的org.apache.ibatis.plugin.Interceptor接口实现了打印SQL执行时间,并格式化SQL及其参数,如果我们使用的是ssm还得再配置文件 ...