用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作为异步任务队列兼具定时任务功能,这套东西用着还行,但反正就折 ...
随机推荐
- shell 正则匹配IP地址
比如255.255.255.255 ,共4段,我们将255分为四个部分,0-99,100-199,200-249,250-255 0-99:[1-9]?[0-9] # ...
- 七牛云-上传、删除文件,工具类(Day49)
要求: 1. java1.8以上 2. Maven: 这里的version指定了一个版本范围,每次更新pom.xml的时候会尝试去下载7.5.x版本中的最新版本,你可以手动指定一个固定的版本. < ...
- grasshopper | 通过图层引用线条 报错:“ Data conversion failed from Guid to Curve ”的避免方法
需求:通过 LunchBox - > layer reference 电池 可以快速选中图层所在的线条,但是选择的数据流错误 直接选择会报错--"Data conversion fai ...
- 5G通讯与芯片
5G通讯与芯片 美国商务部可能接近达成一项新的规则,允许美国公司与华为重启谈判,在共同制定下一代通信技术5G标准方面进行合作. 华为美国首席安全官安迪·珀迪(Andy Purdy)向第一财经记者独家回 ...
- Deep Learning部署TVM Golang运行时Runtime
Deep Learning部署TVM Golang运行时Runtime 介绍 TVM是一个开放式深度学习编译器堆栈,用于编译从不同框架到CPU,GPU或专用加速器的各种深度学习模型.TVM支持来自Te ...
- UI自动化在RobotFramework中采用的分层设计
RF测试数据 RF测试数据由4种表数据组成.这些测试数据由表的第一个单元格标识,名称和用法如下: 表名 用法 别名 设置表 导入测试库,资源文件和变量文件.为测试套件和测试用例定义元数据 Settin ...
- Redis 入门权威指北
前言 看看业务遇到了什么问题? 我们要从互联网架构的演变之路开始说起Redis的前世今生. 在我们小的时候,网络世界好像就是只有通过大屁股台式机才能进入一样,彼时的手机只是用来打打电话,发发短信,网上 ...
- 十六、.net core(.NET 6)搭建基于Redis的Hangfire定时器
搭建基于Redis的Hangfire定时器 Hangfire的定时配置信息会自动生成在指定到数据库内,包括关系型数据库或非关系型数据库内.目前为止,它在Redis.Oracle上面,可以支持最短15秒 ...
- MySQL的自增ID用完了,怎么办?
既然这块知识点不清楚,那回头就自己动手实践下. 首先,创建一个最简单的表,只包含一个自增id,并插入一条数据. create table t0(id int unsigned auto_increme ...
- 2020想进大厂你不得不了解的MySQL意外事件的查询技巧
导读:数据库是导致应用系统运行缓慢的常见原因.面对数据库引性能问题,很多开发者或者DBA却束手无策.本文作者经过多年的实际经验,整理了一些材料,将Linux环境下MySQL性能突发事件问题排查技巧分享 ...