redis发布订阅与stream类型

news2025/1/11 20:46:20

发布订阅

redis发布订阅(pub/sub)是一种消息通信模式;发送者(pub)发送消息,订阅者(sub)接收消息。redis客户端可以订阅任意数量的频道。

基础命令:
语法

redis publish命令基本语法如下:

redis 127.0.0.1:6379> PUBLISH channel massage

redis subscribe 命令基本语法如下:

redis 127.0.0.1:6379 > subscribe channel [channel ...]

返回值

接收到信息的订阅者数量。

接收到的消息。

redis-cli
​
subscribe xx
​
​
​
redis-cli
​
publish xx "hello"
​
publish xx "reids publish subscribe"
案例
touch publish.php
​
touch subscribe.php
curl http://192.168.80.21/publish.php?message=你好
**报错需要检查的地方
systemctl stop firewalld
service nginx start
/www/server/php/sbin/php-fpm
​
curl http://192.168.80.21/publish.php?message=你好

public.php

<?php
$redis = new Redis();
$redis->connect("127.0.0.1",6379);
//链接了redis之后,应该需要一个权限验证,密码验证,这里没有,跳过
//$redis->auth("root");
$message = $_GET["message"];
var_dump($message);
$restful = $redis->publish("new",$message);//向频道new发送一条消息
if ($restful){
    echo "消息发送成功";
    exit;
}
echo "发送失败";

subscribe.php

<?php
$redis = new Redis();
$redis->connect('127.0.0.1',6379);
//$redis->auth('root');

while (true){
    echo time();
    ini_set('default_socket_timeout',-1);//不超时
    $redis->subscribe(['new'],function ($redis,$chan,$message){
        echo ' chan'.$chan.'  message'.$message;
        var_dump($redis);
        sleep(1);
    });
}

  

广播案例

node-v16是开箱即用的,解压之后放在/www/server/node 中

vim /etc/profile
​
export NODE_HOME=/www/server/node
​
export PATH=$PATH:$NODE_HOME/bin
​
export NODE_PATH=$NODE_HOME/lib/node_modules
​
source /etc/profile
node -v
npm -v
cd /www/wwwroot
ll
cd php/
ll
cd blog/
ll
​
npm install http socket.io ioredis socket.io-client
​
npm run dev **更新js代码
node websocket **更新websocket代码
​
php artisan redis:publish

版本问题:

const {io} = require('socket.io-client');**4以上的要加{}
const io = require("socket.io-client");**4以下的不用加

Redis的Stream类型

1.削峰,减少响应时间

2.降低系统耦合性

1.Redis List类型实现

使用redis的lpush/rpop(rpush/lpop)命令简单实现左进右出或右进左出的list

列表。然后需要开启一个线程任务或者定时任务或者轮询方式,不停的调用rpop方法查看list中是否待处理消息。

2.发布/订阅

生产者和消费者通过相同的一个信道进行交互。信道其实也就是队列。通常会有多个消费者。多个消费者订阅同一个信道,当生产者向信道发布消息时,该信道会立即将消息逐一发布给每个消费者。所以该信道对于消费者是发散的信道,每个消费者都可以得到相同的消息。典型的一对多的关系。

Redis Stream主要用于消息队列(MQ,Message Queue),Redis本身是有一个Redis发布订阅(pub/sub)来实现消息队列的功能,但它有个缺点就是消息无法持久化,如果出现网络断开、Redis宕机等,消息就会被丢弃。

XADD:插入消息

xread:消费消息

ack:消费之后用于验证消息是否消费成功


Stream的使用

touch Stream.php
​
redis-cli
xadd stream * massage sky 
​
xadd stream * massage york
​
xadd stream * massage cara
​
xInfo GROUPS  sky
xGroup create sky a1 0
xInfo GROUPS sky
xInfo GROUPS jifen
XReadGroup GROUP a1 aa block 0 count 1 stream sky >
xInfo GROUPS sky
xack sky a1 1642165324727-0 
<?php
$redis = new Redis();
$redis->connect("127.0.0.1",6379);
//$redis->auth("root");
echo "开始下单".PHP_EOL;
$order = [
  "id" => 1,
  "price" => 12000,
    "product_id" => 1
];
//存储订单数据,表示下单成功
$restful = $redis ->hMSet('order:'.$order["id"],$order);
//通过消息队列异步增加用户积分
if ($restful){
    $redis->xAdd("jifen","*",$order);
}
echo "下单成功";
<?php
$redis = new Redis();
$redis->connect("127.0.0.1",6379);

const xKey = "jifen";
const groupName = 'sendMail';

function initGroup(){
    global $redis;
    $groups = $redis->xInfo('GROUPS',xKey);//这里我们会得到一个数组,数组中的数据就是消息队列的详细信息
    //因为此处需要判断队列是否有创建消费组,如果有就创建,默认为没有,下面在根据上面xinfo查询的消息来判断队列是否有消费组
    $exisGroups = false;
    if ($groups){
        foreach ($groups as $group){
            if ($group[1] === groupName){
                $exisGroups = true;
                break;
            }
        }
    }
    if ($exisGroups){
        //判断消费组是否已经创建,如果没有那么就使用xGroup创建消费组,并从0开始进行消费,消费组名称为groupName
        $redis->xGroup('create',xKey,groupName,"0");//表示从0开始消费
        echo "init Group:".groupName.PHP_EOL;
    }
}
initGroup();
while (true){
    $getRestful = $redis -> xReadGroup(groupName,'c1',[xKey=>'>'],1,2000);
    if ($getRestful && isset($getRestful[xKey])){
        $sendMail = $getRestful[xKey];//取出消费的消息信息
        foreach ($sendMail as $id =>$fieldList){
            $redis->xAck(xKey,groupName,[$id]);
            echo "sendMail with id = ".$fieldList["id"].PHP_EOL;
        }
    }
    usleep(5);
}

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1524349.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

若你有才能,最好能遇上识才之人,高俅发迹的故事很好诠释了千里马与伯乐的关系

若你有才能&#xff0c;最好能遇上识才之人&#xff0c;高俅发迹的故事很好诠释了千里马与伯乐的关系 其实&#xff0c;“千里马”和“伯乐”都是中国古代传说里的角色。伯乐是古代一个善于相马&#xff08;识别马的好坏&#xff09;的人&#xff0c;而“千里马”则是指一匹能跑…

解决:由于找不到xinput1_3.dll,无法继续执行代码问题的方法

xinput1_3.dll文件的丢失是一个常见的问题&#xff0c;它会导致一些游戏应用程序无法正常运行或出现错误。为了解决这个问题&#xff0c;我们可以采取多种方法。下面将介绍几种常用的xinput1_3.dll丢失的解决方法&#xff0c;通过采用合适的方法&#xff0c;我们可以轻松解决该…

跳绳计数,YOLOV8POSE

跳绳计数&#xff0c;YOLOV8POSE 通过计算腰部跟最初位置的上下波动&#xff0c;计算跳绳的次数

Redis数据结构对象之字符串对象

字符串对象 字符串对象的编码可以是int、raw或者embstr 如果一个字符串对象保存的是整数值&#xff0c;并且这个整数值可以用long类型来表示&#xff0c;那么字符串对象会将整数值保存在字符串对象结构的ptr属性里面(将void *转换成long)&#xff0c;并且将字符串对象的编码设…

zookeeper快速入门四:在java客户端中操作zookeeper

系列文章&#xff1a; zookeeper快速入门一&#xff1a;zookeeper安装与启动-CSDN博客 zookeeper快速入门二&#xff1a;zookeeper基本概念-CSDN博客 zookeeper快速入门三&#xff1a;zookeeper的基本操作 先启动zookeeper服务端。 在maven引入zookeeper依赖。 <depende…

代码算法训练营day10 | 232.用栈实现队列、225. 用队列实现栈

day10: 232.用栈实现队列225. 用队列实现栈 232.用栈实现队列 题目链接 状态&#xff1a; 文档&#xff1a;programmercarl.com 思路&#xff1a; 用栈实现队列。要先明白两者的区别。 栈&#xff1a;单开门&#xff0c;先进后出&#xff0c;只有一端能进出。 队列&#xff1a;…

【晴问算法】入门篇—贪心算法—区间不相交问题

题目描述 给定n个开区间&#xff0c;从中选择尽可能多的开区间&#xff0c;使得这些开区间两两没有交集。 输入描述 输出描述 输出一个整数&#xff0c;表示最多选择的开区间个数。 样例1输入 4 1 3 2 4 3 5 6 7 输出 3 解释 最多选择(1,3)、(3,5)、(6,7)三个区间&#xff0c;它…

从零到一构建短链接系统(三)

1.根据数据库表&#xff0c;利用在线网站https://jully.top/generator/ 根据数据库Info自动生成代码 2.在entity中创建UserDO Data TableName("t_user") public class UserDO { /** * id */ private Long id; /** * 用户名 */ private String username; /** * 密码…

图解Kafka架构学习笔记(一)

本文参考尚硅谷大数据技术之Kafka。 消息队列 &#xff08;1&#xff09;点对点模式&#xff08;一对一&#xff0c;消费者主动拉取数据&#xff0c;消息收到后消息清除&#xff09; 点对点模型通常是一个基于拉取或者轮询的消息传送模型&#xff0c;这种模型从队列中请求信息…

[嵌入式系统-40]:龙芯1B 开发学习套件 -10-PMON启动过程start.S详解

目录 一、龙芯向量表与启动程序的入口&#xff08;复位向量&#xff09; 1.1 复位向量&#xff1a; 1.2 代码执行流程 1.3 计算机的南桥 VS 北桥 二、PMON代码执行流程 三、Start.S详解 3.1 CPU初始化时所需要的宏定义 &#xff08;1&#xff09;与CPU相关的一些宏定义…

node.js快速入门-day03

个人名片&#xff1a; &#x1f60a;作者简介&#xff1a;一名大二在校生 &#x1f921; 个人主页&#xff1a;坠入暮云间x &#x1f43c;座右铭&#xff1a;给自己一个梦想&#xff0c;给世界一个惊喜。 &#x1f385;**学习目标: 坚持每一次的学习打卡 文章目录 web服务器创建…

brpc之ResourcePool

简介 ResourcePool用于管理资源&#xff0c;负责资源的分配以及回收 结构 BlockGroup&#xff1a;资源池中包含多个BlockGroup&#xff0c;最多65536个 Block&#xff1a;一个BlockGroup中包含多个Block&#xff0c;最多(1<<16)个&#xff1b;1个Block中包含BLOCK_NITE…

代码随想录算法训练营第二十二天 | 235. 二叉搜索树的最近公共祖先, 701.二叉搜索树中的插入操作, 450.删除二叉搜索树中的节点

这道题和寻找二叉树的最近祖先可以用同一套解法&#xff0c;也就是说&#xff0c;考虑当你站在一个节点上的时候&#xff0c;应该干啥&#xff1a;看当前节点是不是指定的孩子p&#xff0c;q&#xff0c;然后检查左子树有无指定节点&#xff0c;检查右子树有无指定节点&#xf…

HashMap底层是如何实现的?

1、典型回答 不同的JDK 版本&#xff0c;HashMap 的底层实现是不一样的&#xff0c;总体来说&#xff1a;在JDK 1.8 之前(不包含JDK 1.8)&#xff0c;HashMap 使用的是数组 链表实现的&#xff0c;而JDK 1.8之后(包含JDK 1.8)使用的是数组 链表或红黑树实现的 HashMap 在JD…

鸿蒙Next 支持数据双向绑定的组件:Checkbox--Search--TextInput

Checkbox $$语法&#xff0c;$$绑定的变量发生变化时&#xff0c;会触发UI的刷新 Entry Component struct MvvmCase { State isMarry:boolean falseStatesearchText:string build() {Grid(){GridItem(){Column(){Text("checkbox 的双向绑定")Checkbox().select($$…

python学习笔记------函数进阶

函数多返回值 函数返回多个返回值格式 def 函数名(): return 1,2,......,n x,x1,......xn函数名&#xff08;&#xff09; 按顺序接受 函数的多种传参方式 位置参数&#xff1a;调用函数时根据函数定义的参数位置来传递参数 传递的参数和定义的参数的顺序及个数必须一致…

简介:项目管理九大知识五大过程

前言 项目管理&#xff08;Project Management,PM/Management by Projects,MBP&#xff09; 在有限的资源约束下&#xff0c;运用系统的观点、方法和理论&#xff0c;对项目涉及的全部工作进行有效地管理。即从项目的投资决策开始到项目结束的全过程进行计划、组织、指挥、协调…

WPF监控平台(科技大屏)[一]

跟着B站的视频敲了一个略微复杂的WPF界面,链接如下.在这里我详细的写一份博客进行设计总结. 系统介绍和配置及主窗口设计_哔哩哔哩_bilibilihttps://www.bilibili.com/video/BV1Wy421Y7QD?p1&vd_source4796b18a2e4c1ec8a310391a5644b6da 成果展示 实现过程 总体来说,我的…

打破数据孤岛,TDengine 与 Tapdata 实现兼容性互认证

当前&#xff0c;传统行业正面临着数字化升级的紧迫需求&#xff0c;但海量时序数据的处理以及数据孤岛问题却日益突出。越来越多的传统企业选择引入时序数据库&#xff08;Time Series Database&#xff0c;TSDB&#xff09;升级数据架构&#xff0c;同时&#xff0c;为了克服…

redis题库详解

1 什么是Redis Redis(Remote Dictionary Server) 是一个使用 C 语言编写的&#xff0c;开源的&#xff08;BSD许可&#xff09;高性能非关系型&#xff08;NoSQL&#xff09;的键值对数据库。 Redis 可以存储键和五种不同类型的值之间的映射。键的类型只能为字符串&#xff0c;…