SpringBoot+Redis實(shí)現(xiàn)消息的發(fā)布與訂閱的示例代碼
1.什么是redis的發(fā)布與訂閱
在官網(wǎng)的文檔介紹中有一行介紹:Redis是一個(gè)快速穩(wěn)定的發(fā)布/訂閱消息系統(tǒng)。
2.Redis發(fā)布訂閱
機(jī)制
Redis提供了發(fā)布與訂閱的功能,可以用于消息的傳輸,Redis的發(fā)布訂閱機(jī)制包括三部分,發(fā)布者、訂閱者和Channel(主題或者隊(duì)列)。

3.命令行實(shí)現(xiàn)功能
訂閱主題
Redis采用SUBSCRIBE channel命令訂閱某個(gè)主題,返回的參數(shù)subscribe表示已經(jīng)成功訂閱主題,第二個(gè)參數(shù)表示訂閱的主題名稱,第三個(gè)表示當(dāng)前訂閱數(shù)
127.0.0.1:6379> SUBSCRIBE ORDER-PAY-SUCCESS Reading messages... (press Ctrl-C to quit) 1) "subscribe" 2) "ORDER-PAY-SUCCESS" 3) (integer) 1
模式匹配訂閱
模式匹配功能是允許客戶端訂閱匹配某種模式的頻道,Redis采用PSUBSCRIBE channel命令訂閱匹配某種模式的所有頻道,用*表示模式,*可以被任意值代替。
127.0.0.1:6379> PSUBSCRIBE ORDER-PAY-* Reading messages... (press Ctrl-C to quit) 1) "psubscribe" 2) "ORDER-PAY-*" 3) (integer) 1
發(fā)布消息
Redis采用PUBLISH channel message命令在某個(gè)主題上發(fā)布消息,返回的參數(shù)是接收到消息的訂閱者個(gè)數(shù)
127.0.0.1:6379> PUBLISH ORDER-PAY-SUCCESS DD202109071525 (integer) 1
取消訂閱
Redis采用UNSUBSCRIBE channel或PUNSUBSCRIBE channel命令取消某個(gè)主題的訂閱,由于Redis的訂閱操作是阻塞式的,因此一旦客戶端訂閱了某個(gè)頻道或模式,就將會(huì)一直處于訂閱狀態(tài)直到退出。在 SUBSCRIBE,PSUBSCRIBE,UNSUBSCRIBE 和 PUNSUBSCRIBE 命令中,其返回值都包含了該客戶端當(dāng)前訂閱的頻道和模式的數(shù)量,當(dāng)這個(gè)數(shù)量變?yōu)?時(shí),該客戶端會(huì)自動(dòng)退出訂閱狀態(tài)。
127.0.0.1:6379> UNSUBSCRIBE ORDER-PAY-SUCCESS 1) "unsubscribe" 2) "ORDER-PAY-SUCCESS" 3) (integer) 0 127.0.0.1:6379> PUNSUBSCRIBE ORDER-PAY-SUCCESS 1) "punsubscribe" 2) "ORDER-PAY-SUCCESS" 3) (integer) 0
測(cè)試
首先三個(gè)訂閱者訂閱ORDER-PAY-SUCCESS主題,當(dāng)發(fā)送者在這個(gè)主題內(nèi)發(fā)送訂單號(hào)時(shí),所有的訂閱者都會(huì)收到這個(gè)主題的消息。

4.SpringBoot實(shí)現(xiàn)功能
Springboot整合Redis
引入依賴包
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>2.2.10.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.2.10.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<version>2.4.1</version>
</dependency>
</dependencies>
配置yaml文件
server: ? port: 8888 spring: ? application: ? ? name: spring-boot-redis ? redis: ? ? host: 127.0.0.1 ? ? port: 6379
配置消息監(jiān)聽(tīng)
import com.demo.redis.listener.MessageListener;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.listener.PatternTopic;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.data.redis.listener.adapter.MessageListenerAdapter;
/**
?* @author Bai
?* @date 2021/4/29 上午 11:17
?* @description
?*/
@Configuration
public class RedisMessageConfig {
? ? /**
? ? ?* 監(jiān)聽(tīng)訂單支付完成主題
? ? ?*/
? ? private static final String ORDER_PAY_SUCCESS = "ORDER-PAY-SUCCESS";
? ? /**
? ? ?* 注入消息監(jiān)聽(tīng)適配器
? ? ?* @param messageListener
? ? ?* @return {@link MessageListenerAdapter}
? ? ?* @throws
? ? ?* @author Bai
? ? ?* @date 2021/9/7 下午 03:54
? ? ?*/
? ? @Bean
? ? public MessageListenerAdapter getMessageListenerAdapter(MessageListener messageListener){
? ? ? ? return new MessageListenerAdapter(messageListener, "onMessage");
? ? }
? ? /**
? ? ?* 注入消息監(jiān)聽(tīng)容器
? ? ?* @param redisConnectionFactory
? ? ?* @param messageListenerAdapter
? ? ?* @return {@link RedisMessageListenerContainer}
? ? ?* @throws
? ? ?* @author Bai
? ? ?* @date 2021/9/7 下午 03:54
? ? ?*/
? ? @Bean
? ? public RedisMessageListenerContainer getRedisMessageListenerContainer(RedisConnectionFactory redisConnectionFactory, MessageListenerAdapter messageListenerAdapter){
? ? ? ? RedisMessageListenerContainer redisMessageListenerContainer = new RedisMessageListenerContainer();
? ? ? ? redisMessageListenerContainer.setConnectionFactory(redisConnectionFactory);
? ? ? ? //訂閱訂單支付成功主題
? ? ? ? redisMessageListenerContainer.addMessageListener(messageListenerAdapter, new PatternTopic(ORDER_PAY_SUCCESS));
? ? ? ? return redisMessageListenerContainer;
? ? }
? ? /**
? ? ?* 處理內(nèi)容
? ? ?* @param connectionFactory
? ? ?* @return {@link StringRedisTemplate}
? ? ?* @throws
? ? ?* @author Bai
? ? ?* @date 2021/9/7 下午 04:01
? ? ?*/
? ? @Bean
? ? StringRedisTemplate template(RedisConnectionFactory connectionFactory) {
? ? ? ? return new StringRedisTemplate(connectionFactory);
? ? }
}接收消息
import org.springframework.stereotype.Component;
/**
?* @author Bai
?* @date 2021/9/7 下午 03:51
?* @description
?*/
@Component
public class MessageListener {
? ? public void onMessage(String message){
? ? ? ? System.out.println("接收消息:" + message);
? ? }
}測(cè)試
發(fā)送訂單支付成功的消息
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.test.context.junit4.SpringRunner;
import javax.annotation.Resource;
/**
?* @author Bai
?* @date 2021/9/7 下午 04:32
?* @description
?*/
@RunWith(value = SpringRunner.class)
@SpringBootTest
public class RedisPubTest {
? ? /**
? ? ?* 訂單支付完成主題
? ? ?*/
? ? private static final String ORDER_PAY_SUCCESS = "ORDER-PAY-SUCCESS";
? ? @Resource
? ? private StringRedisTemplate stringRedisTemplate;
? ? /**
? ? ?* 模擬發(fā)送5調(diào)訂單支付完成的消息
? ? ?* @throws
? ? ?* @author Bai
? ? ?* @date 2021/9/7 下午 04:57
? ? ?*/
? ? @Test
? ? public void sendMessage(){
? ? ? ? for (int i = 0; i < 5; i++) {
? ? ? ? ? ? stringRedisTemplate.convertAndSend(ORDER_PAY_SUCCESS,"DD" + System.currentTimeMillis());
? ? ? ? }
? ? }
}接收到訂單支付成功的消息
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.2.10.RELEASE)2021-09-07 16:56:54.729 INFO 3712 --- [ main] com.demo.redis.RedisSubPubApplication : Starting RedisSubPubApplication on DESKTOP-595LI4G with PID 3712 (D:\Bai\Sources\spring-boot-demo\redis-sub-pub\target\classes started by 1 in D:\Bai\Sources\spring-boot-demo)
2021-09-07 16:56:54.735 INFO 3712 --- [ main] com.demo.redis.RedisSubPubApplication : No active profile set, falling back to default profiles: default
2021-09-07 16:56:55.205 INFO 3712 --- [ main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode!
2021-09-07 16:56:55.207 INFO 3712 --- [ main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode.
2021-09-07 16:56:55.229 INFO 3712 --- [ main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 11 ms. Found 0 Redis repository interfaces.
2021-09-07 16:56:55.557 INFO 3712 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8888 (http)
2021-09-07 16:56:55.565 INFO 3712 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2021-09-07 16:56:55.565 INFO 3712 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.38]
2021-09-07 16:56:55.669 INFO 3712 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2021-09-07 16:56:55.669 INFO 3712 --- [ main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 895 ms
2021-09-07 16:56:56.032 INFO 3712 --- [ main] o.s.s.concurrent.ThreadPoolTaskExecutor : Initializing ExecutorService 'applicationTaskExecutor'
2021-09-07 16:56:56.950 INFO 3712 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8888 (http) with context path ''
2021-09-07 16:56:56.952 INFO 3712 --- [ main] com.demo.redis.RedisSubPubApplication : Started RedisSubPubApplication in 2.557 seconds (JVM running for 3.436)
接收消息:DD1631005025949
接收消息:DD1631005025964
接收消息:DD1631005025965
接收消息:DD1631005025967
接收消息:DD1631005025968
到此這篇關(guān)于SpringBoot+Redis實(shí)現(xiàn)消息的發(fā)布與訂閱的示例代碼的文章就介紹到這了,更多相關(guān)SpringBoot Redis消息發(fā)布與訂閱內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- SpringBoot集成Redis實(shí)現(xiàn)消息隊(duì)列的方法
- SpringBoot中使用Redis?Stream實(shí)現(xiàn)消息監(jiān)聽(tīng)示例
- springboot整合redis之消息隊(duì)列
- SpringBoot整合Redis實(shí)現(xiàn)消息發(fā)布與訂閱的示例代碼
- SpringBoot使用Redis實(shí)現(xiàn)消息隊(duì)列的方法小結(jié)
- springboot集成redis實(shí)現(xiàn)消息的訂閱與發(fā)布
- SpringBoot集成Redisson實(shí)現(xiàn)消息隊(duì)列的示例代碼
- Springboot3+Redis實(shí)現(xiàn)消息隊(duì)列的多種方法小結(jié)
相關(guān)文章
springboot2 生產(chǎn)部署注意事項(xiàng)及示例代碼
這篇文章主要介紹了springboot2 生產(chǎn)部署注意事項(xiàng)及示例代碼,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-04-04
Java求出任意數(shù)字的各個(gè)位數(shù)之和方式
這篇文章主要介紹了Java求出任意數(shù)字的各個(gè)位數(shù)之和方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-01-01
解決springboot?druid數(shù)據(jù)庫(kù)連接池連接失敗后一直重連問(wèn)題
這篇文章主要介紹了解決springboot?druid數(shù)據(jù)庫(kù)連接池連接失敗后一直重連問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-11-11
詳解Maven項(xiàng)目Dependencies常見(jiàn)報(bào)錯(cuò)及解決方案
這篇文章主要介紹了詳解Maven項(xiàng)目Dependencies常見(jiàn)報(bào)錯(cuò)及解決方案,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-11-11

