基于Redis實現(xiàn)訂閱發(fā)布功能
背景
業(yè)務(wù)發(fā)展過程中,希望做到異步解耦,但是又不想引入MQ中間件,在中小型服務(wù)中,就可以考慮使用redis自帶的訂閱發(fā)布來解決這個問題。使用 Redis 實現(xiàn)消息的訂閱和發(fā)布時,可以通過 Spring Boot 集成 Redis 來方便地實現(xiàn)。
引入redis依賴
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>配置 Redis
在 application.properties 文件中,添加 Redis 配置:
spring.redis.host=localhost spring.redis.port=6379
編寫代碼
Redis 配置
創(chuàng)建一個配置類來配置 Redis 的連接工廠和監(jiān)聽器:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.listener.ChannelTopic;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.data.redis.listener.adapter.MessageListenerAdapter;
import org.springframework.data.redis.core.StringRedisTemplate;
@Configuration
public class RedisConfig {
@Bean
public RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory,
MessageListenerAdapter listenerAdapter) {
RedisMessageListenerContainer container = new RedisMessageListenerContainer();
container.setConnectionFactory(connectionFactory);
container.addMessageListener(listenerAdapter, topic());
return container;
}
@Bean
public MessageListenerAdapter listenerAdapter(RedisMessageSubscriber subscriber) {
return new MessageListenerAdapter(subscriber, "onMessage");
}
@Bean
public ChannelTopic topic() {
return new ChannelTopic("messageQueue");
}
@Bean
public StringRedisTemplate template(RedisConnectionFactory connectionFactory) {
return new StringRedisTemplate(connectionFactory);
}
}創(chuàng)建消息訂閱者
編寫一個類來處理收到的消息:
import org.springframework.stereotype.Service;
@Service
public class RedisMessageSubscriber {
public void onMessage(String message, String channel) {
System.out.println("Received message: " + message + " from channel: " + channel);
}
}創(chuàng)建消息發(fā)布者
編寫一個發(fā)布者通過 Redis 模板發(fā)送消息:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.listener.ChannelTopic;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class MessagePublisher {
@Autowired
private StringRedisTemplate template;
@Autowired
private ChannelTopic topic;
@GetMapping("/publish")
public String publish(@RequestParam String message) {
template.convertAndSend(topic.getTopic(), message);
return "Message published: " + message;
}
}如果需要監(jiān)聽多個channel,可以通過RedisConfig中添加新的消息適配器。
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.listener.ChannelTopic;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.data.redis.listener.adapter.MessageListenerAdapter;
import org.springframework.data.redis.core.StringRedisTemplate;
@Configuration
public class RedisConfig {
@Bean
public RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory,
MessageListenerAdapter listenerAdapter1,
MessageListenerAdapter listenerAdapter2) {
RedisMessageListenerContainer container = new RedisMessageListenerContainer();
container.setConnectionFactory(connectionFactory);
container.addMessageListener(listenerAdapter1, topic1());
container.addMessageListener(listenerAdapter2, topic2());
return container;
}
@Bean
public MessageListenerAdapter listenerAdapter1(RedisMessageSubscriber subscriber) {
return new MessageListenerAdapter(subscriber, "onMessage");
}
@Bean
public MessageListenerAdapter listenerAdapter2(RedisMessageSubscriber subscriber) {
return new MessageListenerAdapter(subscriber, "onMessage");
}
@Bean
public ChannelTopic topic1() {
return new ChannelTopic("channelOne");
}
@Bean
public ChannelTopic topic2() {
return new ChannelTopic("channelTwo");
}
@Bean
public StringRedisTemplate template(RedisConnectionFactory connectionFactory) {
return new StringRedisTemplate(connectionFactory);
}
}同時RedisMessageSubscriber 也可以書寫多個來區(qū)分不同的業(yè)務(wù)場景下不同業(yè)務(wù)處理。
到此這篇關(guān)于Redis分布式系統(tǒng)的原理與實操的文章就介紹到這了,更多相關(guān)Redis分布式系統(tǒng)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- Java使用Redis實現(xiàn)消息訂閱/發(fā)布的幾種方式
- springboot集成redis實現(xiàn)消息的訂閱與發(fā)布
- Springboot使用redisson?+?自定義注解實現(xiàn)消息的發(fā)布訂閱(解決方案)
- redis發(fā)布訂閱模式的實現(xiàn)
- 探索Golang?Redis實現(xiàn)發(fā)布訂閱功能實例
- springboot+redis自定義注解實現(xiàn)發(fā)布訂閱的實現(xiàn)代碼
- Springboot整合redis實現(xiàn)發(fā)布訂閱功能介紹步驟
- Docker?Compose+Nestjs構(gòu)建Dapr?Redis發(fā)布訂閱分布式應(yīng)用
- redis實現(xiàn)隊列的阻塞、延時、發(fā)布和訂閱
相關(guān)文章
redis配置standAlone版的jedisPool示例
這篇文章主要為大家介紹了redis配置standAlone版的jedisPool示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-07-07
Redis+Caffeine實現(xiàn)雙層緩存的策略對比與詳細指南
在高并發(fā)場景下,緩存是提升系統(tǒng)性能和并發(fā)處理能力的關(guān)鍵手段,本文將基于Spring?Boot,從方案對比分析出發(fā),深入探討Redis、本地Caffeine與雙層緩存的實現(xiàn)與性能差異,并給出選型建議與實際效果驗證2025-07-07
Redis內(nèi)存碎片率調(diào)優(yōu)處理方式
Redis集群因內(nèi)存碎片率超過1.5觸發(fā)告警,分析發(fā)現(xiàn)內(nèi)因與外因?qū)е聝?nèi)存碎片,內(nèi)因為操作系統(tǒng)內(nèi)存分配機制,外因為Redis操作特性,使用Redis內(nèi)置內(nèi)存碎片清理機制可有效降低碎片率,但需注意可能影響性能,建議使用MEMORY命令診斷內(nèi)存使用情況,合理配置參數(shù)以優(yōu)化性能2024-09-09
Redis集群中節(jié)點更換IP后實現(xiàn)恢復(fù)集群且保留數(shù)據(jù)
本文介紹了如何在Redis集群中更改節(jié)點IP地址,并通過修改cluster-config-file文件中的IP地址并重啟所有節(jié)點,成功恢復(fù)集群2026-03-03

