高級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.pswp.cn/web/40371.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/40371.shtml
英文地址,請注明出處:http://en.pswp.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;讓你的每一筆消費都安全…