高级Redis之Stream的用法示例

不想自己搭建一个mq怎么办?Redis的Stream 来帮你,Redis Stream 是 Redis 5.0 引入的一种新的数据结构,用于处理实时的、可持久化的、基于时间序列的数据流。它非常适合处理事件流、日志、消息队列等场景。下面是一个使用 Redis Stream 的具体应用场景:简单的消息队列系统。

应用场景:实时消息队列

假设你正在构建一个实时消息通知系统,多个服务需要向某个队列写入消息,多个消费者服务需要从这个队列中读取消息执行相应操作。这个消息队列需要有高性能和高可用性,并且能够应对突发流量。

以下是如何使用 Redis Stream 实现完成订单后通知会员服务加积分这个应用场景的步骤:

步骤 1: 添加必要的依赖

在你的 pom.xml 文件中添加 LettuceSpring Data Redis 依赖:

<dependencies><!-- Spring Boot Starter Web --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- Spring Data Redis --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency><!-- Lettuce dependency for Redis interaction --><dependency><groupId>io.lettuce.core</groupId><artifactId>lettuce-core</artifactId><version>6.1.5</version></dependency>
</dependencies>

步骤 2: 配置 Redis 连接

在你的 application.propertiesapplication.yml 文件中配置 Redis 连接:

spring:redis:host: localhostport: 6379

步骤 3: 创建订单服务 (生产者)

订单服务在订单完成后将订单信息写入 Redis Stream。可以使用 Lettuce 库来与 Redis 进行交互。

import io.lettuce.core.RedisClient;
import io.lettuce.core.api.StatefulRedisConnection;
import io.lettuce.core.api.sync.RedisCommands;
import org.springframework.stereotype.Service;import java.util.HashMap;
import java.util.Map;@Service
public class OrderService {private static final String STREAM_KEY = "order_stream";private RedisClient redisClient;private StatefulRedisConnection<String, String> connection;private RedisCommands<String, String> commands;public OrderService() {this.redisClient = RedisClient.create("redis://localhost:6379");this.connection = redisClient.connect();this.commands = connection.sync();}public void completeOrder(String orderId, String userId, int points) {Map<String, String> orderData = new HashMap<>();orderData.put("orderId", orderId);orderData.put("userId", userId);orderData.put("points", String.valueOf(points));String messageId = commands.xadd(STREAM_KEY, orderData);System.out.println("Order completed with messageId: " + messageId);}public void close() {connection.close();redisClient.shutdown();}
}

步骤 4: 创建会员服务 (消费者)

会员服务从 Redis Stream 中读取消息,并处理用户积分的增加。

import io.lettuce.core.RedisClient;
import io.lettuce.core.api.StatefulRedisConnection;
import io.lettuce.core.api.sync.RedisCommands;
import io.lettuce.core.StreamMessage;
import org.springframework.stereotype.Service;import java.util.List;
import java.util.Map;@Service
public class MemberService {private static final String STREAM_KEY = "order_stream";private static final String CONSUMER_GROUP = "member_group";private static final String CONSUMER_NAME = "member_service";private RedisClient redisClient;private StatefulRedisConnection<String, String> connection;private RedisCommands<String, String> commands;public MemberService() {this.redisClient = RedisClient.create("redis://localhost:6379");this.connection = redisClient.connect();this.commands = connection.sync();// 创建消费组try {commands.xgroupCreate(STREAM_KEY, CONSUMER_GROUP, io.lettuce.core.StreamOffset.from("0"), true);} catch (Exception e) {System.out.println("Consumer group already exists");}}public void consumeMessages() {while (true) {List<StreamMessage<String, String>> messages = commands.xreadgroup(io.lettuce.core.Consumer.from(CONSUMER_GROUP, CONSUMER_NAME),io.lettuce.core.XReadArgs.StreamOffset.lastConsumed(STREAM_KEY));for (StreamMessage<String, String> message : messages) {Map<String, String> body = message.getBody();String orderId = body.get("orderId");String userId = body.get("userId");int points = Integer.parseInt(body.get("points"));// 处理用户积分增加逻辑System.out.println("Processing order: " + orderId + " for user: " + userId + ", adding points: " + points);// 确认处理完成commands.xack(STREAM_KEY, CONSUMER_GROUP, message.getId());}try {Thread.sleep(1000);} catch (InterruptedException e) {Thread.currentThread().interrupt();break;}}}public void close() {connection.close();redisClient.shutdown();}
}

步骤 5: 调整 Spring Boot 启动类

在 Spring Boot 启动类中启动订单服务和会员服务,演示消息的生产和消费:

import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;@SpringBootApplication
public class RedisStreamDemoApplication {public static void main(String[] args) {SpringApplication.run(RedisStreamDemoApplication.class, args);}@Beanpublic CommandLineRunner demo(OrderService orderService, MemberService memberService) {return args -> {// 模拟订单完成orderService.completeOrder("order123", "user1", 100);// 启动会员服务,处理消息new Thread(() -> memberService.consumeMessages()).start();// 等待一段时间,确保消息处理完成Thread.sleep(5000);orderService.close();memberService.close();};}
}

6. 优点

使用 Redis Stream 实现消息队列有以下几个优点:

  1. 高性能:Redis Stream 提供了高性能的读写操作,适用于高吞吐量的场景。
  2. 持久化:Redis Stream 支持数据持久化,不会因为 Redis 重启而丢失数据。
  3. 消费组:支持创建消费者组,多消费者可以协同工作,提高消费效率。
  4. 自动化管理:Redis 可以自动管理消息的 ID、时间戳等,简化开发。

7. 缺点

  • 内存占用:Redis 是内存数据库,若消息量过大,可能会占用大量内存。
  • 学习曲线:Stream API 的使用相对于其他简单数据结构较为复杂,需要一定的学习成本。

总结

通过上述示例,我们展示了如何使用 Redis Stream 实现一个简单的消息队列系统,包括生产者发布消息、消费者读取消息和处理以及消费组的管理。Redis Stream 的高性能、持久化和自动管理特性使其非常适合处理实时数据流、消息队列等场景。希望这个示例能够帮助你更好地理解如何使用 Redis Stream 应对实际开发中的问题。

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

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

相关文章

web基础与HTTP协议(企业网站架构部署与优化)

补充&#xff1a;http服务首页文件在/var/www/html下的&#xff0c;一定是index.html命名的文件。才会显示出来。 如果该路径下没有相应的文件&#xff0c;会显示/usr/share/httpd/noindex下的index.html文件。 如果/usr/share/httpd/noindex没有index.html文件&#xff0c;会…

BSI 第七届万物互联智慧高峰论坛:主题:拥抱AI时代,标准赋能组织实现可持续发展

BSI 第七届万物互联智慧高峰论坛&#xff1a;主题&#xff1a;拥抱AI时代&#xff0c;标准赋能组织实现可持续发展 主要收到 BSI 温女士的邀请参加的本次论坛。还是学到的很多 。 在科技日新月异的时代背景下&#xff0c;BSI 第七届万物互联智慧高峰论坛于[时间&#xff1a;6…

Object 类中的公共方法详解

Object 类中的公共方法详解 1、clone() 方法2、equals(Object obj) 方法3、hashCode() 方法4、getClass() 方法5、wait() 方法6、notify() 和 notifyAll() 方法 &#x1f496;The Begin&#x1f496;点点关注&#xff0c;收藏不迷路&#x1f496; 在 Java 中&#xff0c;Object…

AI 驱动的数据中心变革与前景

文章主要探讨了AI计算时代数据中心的转型&#xff0c;涉及计算技术的多样性、规格尺寸和加速器的发展、大型语言模型&#xff08;LLM&#xff09;的发展、功耗和冷却趋势、基准测试的重要性以及数据中心的发展等方面。为大家提供深入了解AI基础设施发展的视角。 计算技术的多样…

Ubuntu(通用)—网络加固—ufw+防DNS污染+ARP绑定

1. ufw sudo ufw default deny incoming sudo ufw deny in from any to any # sudo ufw allow from any to any port 5353 protocol udp sudo ufw enable # 启动开机自启 # sudo ufw reload 更改后的操作2. 防ARP欺骗 华为云教程 arp -d删除dns记录arp -a显示arp表 ipconfi…

PTrade常见问题系列3

量化允许同时运行回测和交易的策略个数配置。 量化允许同时运行回测和交易的策略个数在哪里查看&#xff1f; 在量化服务器/home/fly/config/custom_config_conf文件中&#xff0c;其中运行回测的策略个数由backtest_switch&#xff08;是否限制普通回测个数&#xff09;及ba…

Qt 日志输出的选择方案有多少

Qt 日志输出的选择方案主要包括以下几种&#xff1a; 使用内置的日志函数&#xff1a; qDebug()&#xff1a;用于输出调试信息。qInfo()&#xff1a;用于输出一般信息。qWarning()&#xff1a;用于输出警告信息。qCritical()&#xff1a;用于输出关键错误信息&#xff0c;表明…

详细设计与概要设计区别-慧哥充电桩开源系统

概要设计更侧重于系统的整体构架和模块划分&#xff0c;而详细设计则关注具体模块的实现细节。在软件开发过程中&#xff0c;这两个阶段虽然紧密相关&#xff0c;但它们各自有着不同的目标和方法。以下是具体分析&#xff1a; 目标 概要设计&#xff1a;概要设计关注系统整体架…

matlab 绘制高等数学中的二维函数示例

matlab 绘制高等数学中的二维函数示例 绘制高等数学中的二维函数示例绘制结果 绘制高等数学中的二维函数示例 clc,clear,close all; % 定义方程 eqn (x, y) (x.^2 y.^2).^3 - y.^4;% 绘制方程曲线和坐标轴 ezplot(eqn, [-2, 2, -2, 2]) hold on % 在同一图形中保持绘图% 绘…

S7-1200PLC学习记录

文章目录 前言一、S7-12001.数字量输入模块2. PNP接法和NPN接法 二、博图软件1. 位逻辑运算Part1. 添加新设备&#xff08;添加PLC&#xff09;Part2. 添加信号模块Part3. 添加信号板中模块Part4. 添加新块Part5. Main编程文件案例1案例2 -( S )- 和 -( R )-完整操作过程&#…

昇思25天学习打卡营第8天|ResNet50迁移学习

一、迁移学习定义 迁移学习&#xff08;Transfer Learning&#xff09;&#xff1a;在一个任务上训练得到的模型包含的知识可以部分或全部地转移到另一个任务上。允许模型将从一个任务中学到的知识应用到另一个相关的任务中。适用于数据稀缺的情况&#xff0c;可减少对大量标记…

掌握Linux网络:深入理解TC —— 你的流量控制利器

目录 简单概述&#xff1a; qdisc(队列)&#xff1a; 举例&#xff1a; Bash 整形队列算法&#xff1a; FIFO (First-In-First-Out) PFIFO (Priority FIFO) SFQ (Stochastic Fair Queuing) RED (Random Early Detection) HTB (Hierarchical Token Bucket) TBF…

谷粒商城笔记-04-项目微服务架构图简介

文章目录 一&#xff0c;网络二&#xff0c;网关1&#xff0c;网关选型2&#xff0c;认证鉴权3&#xff0c;动态路由4&#xff0c;限流5&#xff0c;负载均衡6&#xff0c;熔断降级 三&#xff0c;微服务四&#xff0c;存储层五&#xff0c;服务治理六&#xff0c;日志系统七&a…

前端面试题3-浅谈http协议及常见的面试题

1、浅谈http协议 HTTP&#xff08;Hypertext Transfer Protocol&#xff09;超文本传输协议&#xff0c;是互联网上应用最为广泛的一种网络协议&#xff0c;所有的WWW文件都必须遵守这个标准。它是基于TCP/IP通信协议来传递数据&#xff08;HTML文件、图片文件、查询结果等&am…

在Apache HTTP服务器上配置 TLS加密

安装mod_ssl软件包 [rootlocalhost conf.d]# dnf install mod_ssl -y此时查看监听端口多了一个443端口 自己构造证书 [rootlocalhost conf.d]# cd /etc/pki/tls/certs/ [rootlocalhost certs]# openssl genrsa > jiami.key [rootlocalhost certs]# openssl req -utf8 -n…

OLED示波器的实现

OLED示波器是一种使用有机发光二极管&#xff08;OLED&#xff09;显示屏来显示波形的仪器。它可以实时显示电压、电流、频率等信号的波形。 OLED显示屏具有高对比度、高亮度、广视角和快速响应时间等优点&#xff0c;使得OLED示波器在波形显示方面具有更好的表现。与传统的液…

鸿蒙开发设备管理:【@ohos.usb (USB管理)】

USB管理 本模块主要提供管理USB设备的相关功能&#xff0c;包括查询USB设备列表、批量数据传输、控制命令传输、权限控制等。 说明&#xff1a; 本模块首批接口从API version 8开始支持。后续版本的新增接口&#xff0c;采用上角标单独标记接口的起始版本。 导入模块 import …

【JavaScript脚本宇宙】优化你的Web色彩:精选JavaScript颜色工具对比

万能色彩助手&#xff1a;详解最受欢迎的JavaScript颜色库 前言 在现代Web开发中&#xff0c;颜色处理和转换是一个不可忽视的环节。无论是网站设计、数据可视化还是用户界面开发&#xff0c;都离不开对颜色的精确控制和转换。为了满足这一需求&#xff0c;众多JavaScript库应…

Toocaa Studio已开发的功能

2024年07月01日 Toocaa Studio 一个激光切割雕刻机的上位机&#xff0c; 未来会对标Xtool的xTool Creative Space和LightBurn&#xff0c;同时它也是一款图形编辑器&#xff0c;矢量图形编辑器。 工具类 鼠标画矩形或正方形 鼠标画椭圆或画圆 鼠标画直线或轨迹路径 往画布中…

你的机器人购物新体验——安全、高效、无忧

如果你跟我一样&#xff0c;对找到那些“恰到好处”的商品充满渴望&#xff0c;那么&#xff0c;让我来告诉你为什么BFT会成为你的下一个购物“心头好”。 BFT的优势 高效安全的支付体系&#xff1a;BFT交易系统保障了交易的安全性和透明性&#xff0c;让你的每一笔消费都安全…