redis 发布订阅实现异步实时发短信
redis 中发布和订阅可以实现消息的实时传输,这里我只是用它的事件驱动,当客户端发送了消息,服务器端立马可以接收指令处理相应的业务逻辑。
客户端
client.php
<?php //发布 $redis = new Redis(); $redis->connect('11.10.1.121', 6379); $message = 'send msg';
#将手机号存放到队列中 $redis->lPush("phone", "15013028236"); $ret = $redis->publish('subscribe', $message);
服务器端
server.php
<?php //订阅端 常驻进程 ini_set('default_socket_timeout', -1); //不超时 $redis = new Redis(); $redis->connect('11.10.1.121', 6379); $result = $redis->subscribe(array('subscribe'), 'callback'); function callback($instance, $channelName, $message) { # 回调函数内只能使用 SUBSCRIBE、PSUBSCRIBE、UNSUBSCRIBE、PUNSUBSCRIBE 4 条命令 # 事件驱动 接到信息后执行业务逻辑 如 发送短信 、邮件等 //请求接口 接口完成发送短信、邮件业务逻辑 $curl = curl_init(); curl_setopt($curl, CURLOPT_URL, 'http://www.layui.test/home/article/attrJob'); curl_setopt($curl, CURLOPT_HEADER, 1); curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); $data = curl_exec($curl); echo curl_getinfo($curl, CURLINFO_HTTP_CODE); curl_close($curl); }
发送短信示例代码
public function attrJob(){ //示例代码 $redis = new Redis(); $redis->connect('11.10.1.121', 6379); $phone = $redis->rPop("phone"); if (!$phone || ctype_digit($phone)) { echo json_encode(['error_code' => 1, 'msg' => "s手机号不能为空!"]); return; } #使用短信接口 echo json_encode(['error_code' => 0, 'msg' => "短信已发送!"]); }
########## 测试1000并发下处理业务逻辑 ############
客户端
<?php //发布 $redis = new Redis();
$redis->connect('11.10.1.121', 6379); $message = 'send msg'; #测试并发处理 for ($i = 1; $i <= 1000; $i++) { $ret = $redis->publish('subscribe', $message); }
服务器端
<?php //订阅端 常驻进程 ini_set('default_socket_timeout', -1); //不超时 $redis = new Redis(); $redis->connect('11.10.1.121', 6379); $result = $redis->subscribe(array('subscribe'), 'callback'); function callback($instance, $channelName, $message) { # 回调函数内只能使用 SUBSCRIBE、PSUBSCRIBE、UNSUBSCRIBE、PUNSUBSCRIBE 4 条命令 # 事件驱动 接到信息后执行业务逻辑 如 发送短信 、邮件等 //访问接口 点赞数+1 $curl = curl_init(); curl_setopt($curl, CURLOPT_URL, 'http://www.layui.test/home/article/giveLike'; curl_setopt($curl, CURLOPT_HEADER, 1); curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); $data = curl_exec($curl); echo curl_getinfo($curl, CURLINFO_HTTP_CODE); curl_close($curl); }
点赞接口
public function giveLike() { $model = M("test"); $model->where('id=4')->setInc('num', 1); // 点赞+1 }
将id =4 的num 重置为0
运行服务器端 ,在运行客户端后
总结:redis 默认是单线程处理高并发很友好,经常用来处理抢购、秒杀等高并发业务逻辑。