Redis做消息队列的好处在于它的轻量级,高并发,延迟敏感,应用场景有 即时数据分析、秒杀计数器、缓存等

Redis做消息队列待解决的问题:

  1、消息的可靠性: 没有相应的机制保证消息的消费,当消费者消费失败的时候,消息体丢失,需要手动处理。生产者只管向队列中插入数据,不管消费者是否成功消费。

  2、消费者挂掉消息不会丢失,但是需要重新触发一下消费者,才能够继续消费消息。

代码如下:

  lib.php 是工具文件,里面有数据库的连接、Redis的连接:

<?php
/*** 获取数据库连接** @param $host* @param $username* @param $password* @param $database* @return mysqli*/
function getDBConnection($host, $username, $password, $database){$connection = new mysqli('p:'.$host, $username, $password, $database);if (!$connection) {echo "Error: Unable to connect to MySQL." . PHP_EOL;echo "Debugging errno: " . mysqli_connect_errno() . PHP_EOL;echo "Debugging error: " . mysqli_connect_error() . PHP_EOL;exit;}mysqli_query($connection, "set names 'utf8'");return $connection;
}/*** 获取Redis连接** @param $host* @param $port* @param string $password* @param int $database* @return Redis*/
function getRedis($host='127.0.0.1', $port='6379', $password=null, $database=0){$redis = new Redis();if(!$redis->connect($host, $port)){die("Redis连接失败:IP或端口有误");}if(!empty($password) && !$redis->auth($password)){die("Redis连接失败:密码错误");}if($database){$redis->select($database);}// work中 subscribe 如果一段时间没有接到消息,就会停掉然后停掉,所以加这个语句让其永不超时$redis->setOption(Redis::OPT_READ_TIMEOUT, -1);return $redis;
}/*** 打印消息日志** @param $msg*/
function stdout($msg=null){$msg = '['.date('Y-m-d H:i:s').']'.$msg.chr(10);;fwrite(STDOUT, $msg);
}

 

 register.php 是消息发布者,注释的是将消息存入数据库部分的代码。

  首先想消息存入 register_users 队列中,存入的 key是register_users;value是一个list,消息全部存入其中。用 redis-cli 查看数据的命令是:

LRANGE register_users 0 -1

  register.php:

<?php
require './lib.php';
$name = $argv[1];
$mobile = $argv[2];
if(empty($name) || empty($mobile)){die("参数错误");
}
// $connection = getDBConnection('localhost:3306', 'root', 'root', 'blog');
// // 开启事务
// mysqli_begin_transaction($connection);
// $sql = "insert into mq_user(name, mobile) values ('$name', '$mobile')";
// if(!mysqli_query($connection, $sql)){
//     die("写入用户信息失败,原因:".$connection->error);
// }
$redis = getRedis();
// 添加消息
$result = $redis->lpush('register_users', json_encode(array('name'=>$name, 'mobile'=>$mobile), JSON_UNESCAPED_UNICODE));
if($result === false){mysqli_rollback($connection);die("添加消息队列失败");
}
// 发布消息
$redis->publish('register_success', 'ok');
// 所有操作完成后提交事务
// mysqli_commit($connection);
// $connection->close();
$redis->close();

  

  work.php 做为消息的消费者

<?php
require './lib.php';
$redis = getRedis();
$redis->subscribe(['register_success'], function ($instance, $channelName, $message) {if($channelName == "register_success" && $message = "ok") {$redis = getRedis();while($redis->lsize("register_users")>0) {$arr = $redis->brPop(['register_users'], 20);if(count($arr)) {$userInfo = json_decode($arr[1], true);stdout("新注册用户信息:");stdout("姓名:".$userInfo['name']);stdout("手机号:".$userInfo['mobile']);stdout();sleep(3);}}}
});

  

  register.php将消息放入redis 的 register_users队列中,然后再使用 publish 将 register_success 消息发不出去。work.php 使用 subscribe 订阅 register_success 的消息。接收到 register_success 消息之后,读取 register_users 的消息进行处理。

我是按照这个github上面的代码做的参照,有些改动:

  https://github.com/jormin/php-redis-mq

转载于:https://www.cnblogs.com/Lyh1997/p/11491046.html

PHP + Redis 实现消息队列相关推荐

  1. Redis做消息队列,香吗?

    来自:架构师修行之路 菜菜哥,我刚做完了一个订单系统,感觉很简单呀 说说看,大量的订单状态怎么处理的? 我设计的时候可是考虑了这一点,所以用了异步处理,采用了MQ 那用的什么MQ呢,透露一下呗 我用的 ...

  2. 【springboot】【redis】springboot+redis实现发布订阅功能,实现redis的消息队列的功能...

    springboot+redis实现发布订阅功能,实现redis的消息队列的功能 参考:https://www.cnblogs.com/cx987514451/p/9529611.html 思考一个问 ...

  3. ​redis实现消息队列

    redis是一个开源的key-value存储系统.与Memcached类似,Redis将大部分数据存储在内存中,支持的数据类型包括:字符串.哈希表.链表.集合.有序集合以及基于这些数据类型的相关操作. ...

  4. 用redis实现消息队列(实时消费+ack机制)【转】

    用redis实现消息队列(实时消费+ack机制) java queue 消息队列 redis 消息队列 首先做简单的引入. MQ主要是用来: 解耦应用. 异步化消息 流量削峰填谷 目前使用的较多的有A ...

  5. 使用Redis 实现消息队列

    一 .为什么要用Redis实现轻量级MQ? MQ的主要作用: 应用解耦 异步化消息 流量削峰填谷 目前使用比较多的是ActiveMQ . RabbitMQ . ZeroMQ . Kafka . Met ...

  6. 【BCVP】实现基于 Redis 的消息队列

    聆听自己的声音 如果自己学不动了,或者感觉没有动力的时候,看看书,听听音乐,跑跑步,休息两天,重新出发,偷懒虽好,可不要贪杯. 话说上回书我们说到了,Redis的使用修改<[BCVP更新]Sta ...

  7. 程序员过关斩将--redis做消息队列,香吗?

    菜菜哥,我刚做完了一个订单系统,感觉很简单呀 说说看,大量的订单状态怎么处理的? 我设计的时候可是考虑了这一点,所以用了异步处理,采用了MQ 那用的什么MQ呢,透露一下呗 我用的redis做的MQ,很 ...

  8. c#进阶(4)—— Redis 用于消息队列的存储

    1.参考的博文 a : http://www.cnblogs.com/lori/archive/2012/04/12/2443708.html -- 主要的实现思路 b:  http://www.cn ...

  9. Redis异步消息队列

    一.异步消息队列介绍 个人认为消息队列的主要特点是异步处理,主要目的是减少请求响应时间和解耦.所以主要的使用场景就是将比较耗时而且不需要即时(同步)返回结果的操作作为消息放入消息队列.同时由于使用了消 ...

最新文章

  1. 【Laravel】使用mews/captcha验证码图片不显示,报错 Call to undefined function Intervention\Image\Gd\imagettfbbox()
  2. 数据中心机房设计及各专业技术平衡
  3. ITM_win_agentCPU内存占用较高
  4. UVA11525 Permutation 逆康托展开
  5. Lua-Nginx-Module常用指令(下)
  6. Vim 命令常用功能详解
  7. 萌新的Python练习实例100例(三)一个整数,它加上100后是一个完全平方数,再加上168又是一个完全平方数
  8. python从入门到精通-小白如何系统学习python,从入门到精通?
  9. ComBox 绑定数据库
  10. Aiseesoft HEIC Converter如何在Mac上将HEIC转换为JPG/JPEG或PNG?
  11. Javascript - Cookie
  12. LeetCode:每日一题(2020.4.13)
  13. append()方法_python之append方法容易踩的坑
  14. 如何编写PMP项目管理中的项目立项书
  15. 一台主机接两个显示器并独立使用_一台电脑如何满足多人同时使用?试试这招!...
  16. 惠普打印机双击之后没有扫描_惠普打印机为什么扫描不了,显示这个,什么意思,怎么处理?急...
  17. 《 Python程序设计项目案例》—学生成绩(信息)管理系统普通版设计要求及部分参考代码(期末大作业、结课项目)
  18. Java进阶之路~适配器设计模式amp;字符串方法
  19. 一些名片上最常用的中英文称呼:
  20. mysql条件关键字查询有limt_MySQL使用Limit关键字限制查询结果的数量-Go语言中文社区...

热门文章

  1. 正则表达式过滤HTML危险脚本
  2. python软件是免费的吗-谁说程序员不懂浪漫?用Python每天自动给女朋友免费发短信...
  3. python自学教程读书导图-自学Python第一天:起点读书自动领取经验值(附思路讲解)...
  4. python处理数据的优势-【Python数据分析基础】: 数据缺失值处理
  5. python读取excel表格-python读写excel文件
  6. python读取excel-蜗牛笔记-文章-Python读取Excel文件
  7. python中文版-Python3.8.2下载
  8. 学python好找工作么-学完Python好找工作吗?为什么有人学完还找不到工作?
  9. python的none是什么-python中stream=None什么意思?
  10. python对象编程例子-python编程进阶之类和对象用法实例分析