redis?消息隊列完成秒殺過期訂單處理方法(一)
redis 高級應(yīng)用–使用 redis 消息隊列完成秒殺過期訂單處理(1)
一、redis 消息通知處理代金券過期問題–課程介紹
1、過期問題解決方案的分析
1.1 過期問題描述
1.2 常用解決方案分析
2.redis介紹及入門
2.1 redis的介紹與安裝
2.1.1 redis 介紹
2.1.2 redis 的安裝
2.2 redis的基本操作
2.3 redis中的訂閱與發(fā)布
3.redis整合SpringData Redis開發(fā)
3.1 RedisTemplate的介紹
3.2 搭建環(huán)境
4.在Java程序中監(jiān)聽redis消息
4.1 配置監(jiān)聽redis消息、
4.2 測試消息
5.結(jié)合redis的key失效機制和消,息完成過期優(yōu)惠券處理
5.1 模擬過期代金卷案例
二、redis 消息通知處理代金券過期問題–失效問題的分析
1、過期問題解決方案的分析–過期問題描述
在電商系統(tǒng)中,秒殺,搶購,紅包優(yōu)惠卷等操作,一般都會設(shè)置時問限制,比如訂單15分鐘不付款自動關(guān)閉,紅包有效期24小時等等。
2、過期問題解決方案的分析–常用解決方案分析
目前企業(yè)中最常見的解決方案大致分為兩種:
- 1.使用定時任務(wù)處理,定時掃描數(shù)據(jù)庫中過期的數(shù)據(jù),然后進行修改。但是為了更加精確的時間控制,定時任務(wù)的執(zhí)行時間會設(shè)置的很短,所以會造成很大的數(shù)據(jù)庫壓力。
- 2使用消息通知,當數(shù)據(jù)失效時發(fā)送消息,程序接收到失效消息后對響應(yīng)的數(shù)據(jù)進行狀態(tài)修改。此種方式不會對數(shù)據(jù)庫造成太大的壓力,
三、redis入門:安裝
1、redis 介紹
1)redis 是一個 key-value 存儲系統(tǒng)。和 Memcached 類似,它支持存儲的 value 類型相對更多,包括 string(字符串)、list(連表)、set(集合)、zset(sorted set-有序集合)和 hash(哈希類型)。這些數(shù)據(jù)類型都支持 push/pop、add/remove 及取交集并集和差集及更豐富的操作,而且這些操作都是原子性的。在此基礎(chǔ)上,redis 支持各種不同方式的排序。與 memcached 一樣,為了保證效率,數(shù)據(jù)都是緩存在內(nèi)存中。區(qū)別的是 redis 會周期性的把更新的數(shù)據(jù)寫入磁盤或者把修改操作寫入追加的記錄文件,并且在此基礎(chǔ)上實現(xiàn)了 master-slave(主從)同步。
2)Redis 是一個高性能的 key-value 數(shù)據(jù)庫。redis 的出現(xiàn),很大程度補償了 memcached這 類 key/value 存儲的不足,在部分場合可以對關(guān)系數(shù)據(jù) 庫起到很好的補充作用。它提供了 Java,C/C++,C#,PHP,JavaScnpt,Per,Obiect-C,Pvthon,RubyErlang 等客戶端,使用很方便。
3)Redis 支持主從同步。數(shù)據(jù)可以從主服務(wù)器向任意數(shù)量的從服務(wù)器上同步,從服務(wù)器可以是關(guān)聯(lián)其他從服務(wù)器的主服務(wù)器。這使得 Redis 可執(zhí)行單層樹復制。存盤可以有意無意的對數(shù)據(jù)進行寫操作。由于完全實現(xiàn)了發(fā)布/訂閱機制,使得從數(shù)據(jù)庫在任何地方同步樹時,可訂閱一個頻道并接收主服務(wù)器完整的消息發(fā)布記錄。同步對讀取操作的可擴展性和數(shù)據(jù)冗余很有幫助。
2、redis 的安裝
1)redis 下載地址(windows 版本)
下載地址:https://github.com/MSOpenTech/redis/tags
下載版本:Redis-x64-3.2.100.zip
2)redis 安裝:windows 系統(tǒng)下,解壓即安裝。
3)啟動 Redis(默認6379端口)
redis 安裝目錄下,雙擊運行:
# 服務(wù)器啟動命令 redis-server.exe # 命令行客戶端 redis-cli.exe
redis 安裝目錄下,打開 cmd 窗口,帶參數(shù)啟動 redis
# 啟動redis服務(wù)端(默認6379端口) redis-server.exe redis.windows.conf # 打開另一cmd窗口,啟動redis客戶端,連接redis服務(wù)端,默認6379端口。 redis-cli 127.0.0.1:6379>
四、redis入門:測試 redis
1、redis 的基本操作
1)key 操作
DEL: 刪除Key, del key1 key2
EXISTS: 檢查key是否存在,EXISTS key
EXPIRE: 設(shè)置或者更新到期時間,到期后自動清除,單位秒 設(shè)置為-1表示永不過期。EXPIRE key。
TTL: 以秒為單位,返回給定key的剩余生存時間。
KEYS: 查看所有 key
2)String 操作
Get: 獲取
SET: 設(shè)置(新增 修改)
SETNX: 只有在KEY不存在時設(shè)置value。就是新增一個(不包含更新)
3)Hash 操作
HMSET key field value [field value …]: 同時將多個 field-value (域-值)對設(shè)置到哈希表 key 中。
HSET key field value: 將哈希表 key 中的域 field 的值設(shè)為 value 。
HMGET key field [field …]: 返回哈希表 key 中,一個或多個給定域的值。
HGET key field: 返回哈希表 key 中給定域 field 的值。
4)List 操作
LINDEX keyindex: 通過索引獲取列表中的元素。
LPUSH key value1 [value2]: 將一個或多個值插入到列表頭部。
RPUSH key value1 [value2]: 在列表中添加一個或多個值。
LRANGE key start stop: 獲取列表指定范圍內(nèi)的元素。
5)Set 操作
SADD key member [member …]: 將一個或多個 member 元素加入到集合 key 當中。
SMEMBERS key: 返回集(At +A所有成員。
6)Zset 操作
ZADD key score1 member1 [score2 member2]:向有序集合添加一個或多個成員。
2、redis 基本操作演示
# 創(chuàng)建數(shù)據(jù) 127.0.0.1:6379> set name redis-test OK # 獲取數(shù)據(jù) 127.0.0.1:6379> get name "redis-test" # 查詢所有 key 127.0.0.1:6379> keys * 1) "name" # 刪除 key 127.0.0.1:6379> del name (integer) 1 # 再次查詢所有 key 為空 127.0.0.1:6379> keys * (empty list or set) 127.0.0.1:6379>
五、redis入門:pub,sub 模式消息通知的說明
1、redis 中的訂閱與發(fā)布
Redis 發(fā)布訂閱(pub/sub)是一種消息通信模式:發(fā)送者(pub)發(fā)送消息,訂閱者(sub)接收消息。
Redis 客戶端可以訂閱任意數(shù)量的頻道。
2、如圖展示:頻道ITCAST,以及訂閱了此頻道的兩個客戶端(客戶端A,客戶端B)
六、redis 入門:在 redis 中操作 pub-sub 消息
1、redis 通過兩個命令來實現(xiàn) pub/sub 模式的消息通知
1)publish 主題名稱 消息內(nèi)容 (向指定的主題中發(fā)送一條消息 )
2)subscribe 主題名稱(訂閱某一個主題 )
2、redis 命令 pub/sub 模式的消息通知 演示
# 打開一客戶端(A端),連接服務(wù)端,訂閱主題 127.0.0.1:6379> subscribe redis-pub-sub Reading messages... (press Ctrl-C to quit) 1) "subscribe" 2) "redis-pub-sub" 3) (integer) 1 # 打開另一客戶端(B端),連接服務(wù)端,發(fā)送消息 127.0.0.1:6379> publish redis-pub-sub "verygood" (integer) 1 # 觀察 客戶端(A端),接收到新消息 1) "message" 2) "redis-pub-sub" 3) "verygood"
七、redis 入門:redis 中的 key 失效機制
1、redis 中,當 key 失效的時候,會發(fā)送一些通知
可以通過訂閱某一個主題,接收 key 失效的消息通知(此逼知是 redis 內(nèi)部的事件處理機制)。
2、如何 訂閱主題,接收 key 失效的消息通知?
1)修改 redis 啟動的配置文件,開啟事件通知。
2)需要訂閱的主題名稱:
keyevent@dbindex:expired
:存入到的redis服務(wù)器:0號數(shù)據(jù)庫
如:訂閱的主題: keyevent@0:expired
3、redis 中的 key 失效機制 演示
# 記事本打開 redis 安裝目錄下的 redis.windows.conf 配置文件,修改如下: # notify-keyspace-events "" # 開啟事件通知 notify-keyspace-events Ex # 修改完配置文件,保存后,重啟 redis 服務(wù)端 # 打開一客戶端(A端),連接服務(wù)端,訂閱主題 127.0.0.1:6379> subscribe __keyevent@0__:expired Reading messages... (press Ctrl-C to quit) 1) "subscribe" 2) "__keyevent@0__:expired" 3) (integer) 1 # 打開另一客戶端(B端),連接服務(wù)端,創(chuàng)建數(shù)據(jù),有效時間為10秒 127.0.0.1:6379> set testKey "test" OK 127.0.0.1:6379> expire testKey 10 (integer) 1 127.0.0.1:6379> ttl testKey (integer) 3 127.0.0.1:6379> ttl testKey (integer) -2 127.0.0.1:6379> # 觀察 客戶端(A端),接收到新消息 1) "message" 2) "__keyevent@0__:expired" 3) "testKey"
4、redis 消息通知處理代金券過期問題分析:
我們可以借助 redis 的 key 失效通知,用戶獲取到一個優(yōu)惠券的時候,將優(yōu)惠券信息保存到 redis 服務(wù)器中,并且設(shè)置超時時間。
當 redis 數(shù)據(jù)失效時,會發(fā)送一條消息通知,接收到失效的消息通知后,在 java 代碼端可以進行處理。
八、springDataRedis 的介紹與基本操作
1、整合 SpringData Redis 開發(fā)
1)我們使用 redis 解決過期優(yōu)惠券和紅包等問題,并且在 java 環(huán)境中使用 redis 的消息通知。目前世面比較流行的 java 代碼操作 redis 的 AIP 有: jedis 和 RedisTemplate。
2)Jedis 是 Redis 官方推出的一款面向 Java 的客戶端,提供了很多接口供 Java 語言調(diào)用。
3)SpringData Redis 是 Spring 官方推出,可以算是 Spring 框架集成 Redis 操作的一個子框架,封裝了 Redis 的很多命令,可以很方便的使用 Spring 操作 Redis 數(shù)據(jù)庫。由于現(xiàn)代企業(yè)開發(fā)中都使用 Spring 整合項目,所以在 API 的選擇上我們使用 Spring 提供的 SpringData Redis 是比較明智的選擇。
2、SpringData Redis 的介紹:
SpringData Redis 是一個開源框架,旨在簡化 Java 應(yīng)用程序與 Redis 數(shù)據(jù)庫的集成。它提供了對 Redis 的高層抽象,使得開發(fā)者能夠更方便地使用 Redis 的各種功能,而無需深入了解 Redis 的底層實現(xiàn)細節(jié)。SpringData Redis 的主要特點包括:
1)簡化集成:通過簡單的配置,SpringData Redis 允許開發(fā)者將Redis集成到 Spring 應(yīng)用程序中,無需編寫大量的底層代碼。它實現(xiàn)了 Spring 框架的緩存抽象層,為 Redis 提供了緩存實現(xiàn),從而減少了開發(fā)工作量。
2)高性能:通過使用連接池和高度封裝的 RedisTemplate 類,SpringData Redis 提供了高性能的數(shù)據(jù)訪問,同時支持多種數(shù)據(jù)序列化方式,以滿足不同的性能需求。
3)支持多種數(shù)據(jù)結(jié)構(gòu):SpringData Redis 支持 Redis 的所有數(shù)據(jù)結(jié)構(gòu)類型,包括 String、List、Set、Hash 和 ZSet 等,使得開發(fā)者能夠靈活地處理各種數(shù)據(jù)結(jié)構(gòu)。
4)易于擴展:SpringData Redis 支持 Lettuce 和 Jedis 兩種客戶端實現(xiàn),提供了靈活的配置選項,便于根據(jù)項目需求進行選擇和配置。
5)文檔和社區(qū)支持:SpringData Redis 擁有豐富的文檔和活躍的社區(qū)支持,為開發(fā)者提供了解決問題的資源和途徑。
通過使用 SpringData Redis,開發(fā)者可以更加專注于業(yè)務(wù)邏輯的實現(xiàn),而不必過多關(guān)注底層數(shù)據(jù)存儲和訪問的復雜性。此外,SpringData Redis 還支持 Spring Boot 的集成,使得在 Spring Boot 項目中集成 Redis 變得更加簡單和方便。
3、打開 idea,創(chuàng)建 spring-data-redis-test 的 maven 工程。
--> idea --> File --> New --> Project --> Maven Project SDK: ( 1.8(java version "1.8.0_131" ) --> Next --> Groupld : ( djh.it ) Artifactld : ( spring-data-redis-test ) Version : 1.0-SNAPSHOT --> Name: ( spring-data-redis-test ) Location: ( ...\spring-data-redis-test\ ) --> Finish
4、 在工程 spring-data-redis-test (模塊)中的 pom.xml 中導入依賴
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>djh.it</groupId> <artifactId>spring-data-redis-test</artifactId> <version>1.0-SNAPSHOT</version> <packaging>war</packaging> <properties> <spring.version>4.2.4.RELEASE</spring.version> <slf4j.version>1.6.6</slf4j.version> <log4j.version>1.2.12</log4j.version> <springdataredis.version>1.7.4.RELEASE</springdataredis.version> <mysql.version>5.1.6</mysql.version> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>2.6.2</version> </dependency> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-pool2</artifactId> <!-- <version>2.2</version>--> <version>2.4.2</version> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.6.8</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aop</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-orm</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>${log4j.version}</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>${slf4j.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>4.2.4.RELEASE</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.10</version> </dependency> <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-redis</artifactId> <version>${springdataredis.version}</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.46</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.1.9</version> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.4.5</version> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>1.3.1</version> </dependency> </dependencies> <build> <finalName>spring-data-redis-test</finalName> <pluginManagement> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.2</version> <configuration> <source>1.8</source> <target>1.8</target> <encoding>UTF-8</encoding> <showWarnings>true</showWarnings> </configuration> </plugin> </plugins> </pluginManagement> </build> </project> <!-- D:\java-test\idea2019\spring-data-redis-test\pom.xml -->
5、在工程 spring-data-redis-test (模塊)中,創(chuàng)建配置文件 applicationContext-redis.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:task="http://www.springframework.org/schema/task" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd "> <bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate"> <!-- 設(shè)置key序列化方式 --> <property name="keySerializer"> <bean class="org.springframework.data.redis.serializer.StringRedisSerializer"></bean> </property> <!-- 設(shè)置value序列化方式 --> <property name="valueSerializer"> <bean class="org.springframework.data.redis.serializer.StringRedisSerializer"></bean> </property> <!-- 注入連接工廠 --> <property name="connectionFactory" ref="connectionFactory"></property> </bean> <!-- 創(chuàng)建connectionFactory交給spring容器管理 --> <bean id="connectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"> <property name="hostName" value="127.0.0.1"></property> <property name="port" value="6379"></property> <property name="database" value="0"></property> <property name="poolConfig" ref="poolConfig"></property> </bean> <!-- 創(chuàng)建連接池的基本配置 --> <bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig"> <!-- 最大連接數(shù) --> <property name="MaxTotal" value="10"></property> </bean> </beans>
6、在工程 spring-data-redis-test (模塊)中,創(chuàng)建測試類 RedisTest.java,進行測試。
/** * D:\java-test\idea2019\spring-data-redis-test\src\test\java\djh\it\redis\test\RedisTest.java * * 2024-7-23 測試類 RedisTest.java */ package djh.it.redis.test; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = "classpath:applicationContext-redis.xml") public class RedisTest { @Autowired private RedisTemplate<String, String> redisTemplate; @Test public void testRedis(){ redisTemplate.opsForValue().set("redisTest001", "redisTest001"); } }
7、打開一客戶端(A端),連接服務(wù)端,嘗試獲取數(shù)據(jù)
127.0.0.1:6379> keys * 1) "redisTest001" 127.0.0.1:6379> get redisTest001 "redisTest001" 127.0.0.1:6379>
到此這篇關(guān)于redis 消息隊列完成秒殺過期訂單處理方法(一)的文章就介紹到這了,更多相關(guān)redis秒殺過期內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- Springboot3+Redis實現(xiàn)消息隊列的多種方法小結(jié)
- 一文詳解消息隊列中為什么不用redis作為隊列
- SpringBoot集成Redisson實現(xiàn)消息隊列的示例代碼
- 如何使用?redis?消息隊列完成秒殺過期訂單處理操作(二)
- Redis高階使用消息隊列分布式鎖排行榜等(高階用法)
- Redis消息隊列的三種實現(xiàn)方式
- Redis使用ZSET實現(xiàn)消息隊列的項目實踐
- Redis使用ZSET實現(xiàn)消息隊列使用小結(jié)
- python使用redis實現(xiàn)消息隊列(異步)的實現(xiàn)完整例程
- 詳解Redis Stream做消息隊列
- 基于Redis實現(xiàn)消息隊列的示例代碼
相關(guān)文章
使用redis實現(xiàn)延遲通知功能(Redis過期鍵通知)
這篇文章主要介紹了使用redis實現(xiàn)延遲通知功能(Redis過期鍵通知)的相關(guān)知識,本文通過實例代碼圖文相結(jié)合給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友參考下吧2021-09-09Redis?生成分布式業(yè)務(wù)單號的實現(xiàn)
在業(yè)務(wù)系統(tǒng)中很多場景下需要生成不重復的ID,本文主要介紹了Redis生成分布式業(yè)務(wù)單號的實現(xiàn),具有一定的參考價值,感興趣的可以了解一下2024-04-04Redis數(shù)據(jù)導入導出以及數(shù)據(jù)遷移的4種方法詳解
這篇文章主要介紹了Redis數(shù)據(jù)導入導出以及數(shù)據(jù)遷移的4種方法詳解,需要的朋友可以參考下2020-02-02Windows系統(tǒng)設(shè)置Redis服務(wù)使其開機自啟動
Redis是一種鍵值對數(shù)據(jù)庫,也稱為內(nèi)存數(shù)據(jù)庫,因為它可以將數(shù)據(jù)存儲在內(nèi)存中,而不是在磁盤上,下面這篇文章主要給大家介紹了關(guān)于Windows系統(tǒng)設(shè)置Redis服務(wù)使其開機自啟動的相關(guān)資料,需要的朋友可以參考下2024-01-01Redis遍歷海量數(shù)據(jù)的實現(xiàn)示例
本文主要介紹了 Redis遍歷海量數(shù)據(jù)的實現(xiàn)示例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2025-04-04