Redis实现订阅发布
场景:如果服务提供者新提供了一些接口供消费者使用,这两个服务并不在一个模块下,怎么可以让消费者动态的感知到提供者新添加的接口。
为什么要使用 Redis 订阅发布?
使用 Redis 订阅发布的原因无非在于项目中已经引入了 Redis,不想再引入更多个组件(MQ),因此才使用 Redis 实现订阅发布
Redis 订阅发布的缺点
Redis 订阅发布适用于项目中对于订阅发布的信息的发送接收要求并不严格的情况下才可以使用,因为 Redis 中的订阅发布并不会对发布信息进行持久化,所以可能会造成数据丢失的风险,因为无法持久化,Redis 客户端必须在线才可以接收消息,且无法接收历史消息
订阅模块
订阅模块新建为 SpringBoot 项目,引入 jedis 依赖
引入依赖
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- 添加redis依赖模块 -->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<!-- <version>2.9.0</version>-->
<version>3.3.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<version>2.0.6.RELEASE</version>
</dependency>
</dependencies>
自动配置类
在这里配置 redis 的连接,以及 redis 订阅 topic,这里订阅 topic 为 test-redis-push
,并且指定接受方法为 Receiver 的 receiveMessage 方法
@Configuration
public class AutoConfig {
@Bean
public RedisConnectionFactory redisConnectionFactory() {
// 1. 拉取注册中心的 Redis 配置信息
Map<String, String> redisConfig = new HashMap<>();
redisConfig.put("host", "127.0.0.1");
redisConfig.put("port", "6379");
// 2. 构建 Redis 服务
RedisStandaloneConfiguration standaloneConfig = new RedisStandaloneConfiguration();
standaloneConfig.setHostName(redisConfig.get("host"));
standaloneConfig.setPort(Integer.parseInt(redisConfig.get("port")));
// 3. 默认配置信息;一般这些配置可以被抽取出来
JedisPoolConfig poolConfig = new JedisPoolConfig();
poolConfig.setMaxTotal(100);
poolConfig.setMaxWaitMillis(30 * 1000);
poolConfig.setMinIdle(20);
poolConfig.setMaxIdle(40);
poolConfig.setTestWhileIdle(true);
// 4. 创建 Redis 配置
JedisClientConfiguration clientConfig = JedisClientConfiguration.builder()
.connectTimeout(Duration.ofSeconds(2))
.clientName("api-gateway-assist-redis-nginx-test3")
.usePooling().poolConfig(poolConfig).build();
// 5. 实例化 Redis 链接对象
return new JedisConnectionFactory(standaloneConfig, clientConfig);
}
@Bean
public RedisMessageListenerContainer container(RedisConnectionFactory redisConnectionFactory, MessageListenerAdapter msgAgreementListenerAdapter) {
RedisMessageListenerContainer container = new RedisMessageListenerContainer();
container.setConnectionFactory(redisConnectionFactory);
// container.addMessageListener(msgAgreementListenerAdapter, new PatternTopic("api-gateway-g4"));
container.addMessageListener(msgAgreementListenerAdapter, new PatternTopic("test-redis-push"));
return container;
}
@Bean
public MessageListenerAdapter msgAgreementListenerAdapter(Receiver receiver) {
return new MessageListenerAdapter(receiver, "receiveMessage");
}
@Bean
public Receiver receiver() {
return new Receiver();
}
}
接收者
public class Receiver {
private Logger logger = LoggerFactory.getLogger(Receiver.class);
public void receiveMessage(Object message) {
logger.info("接受Redis推送消息 message:{}", message);
}
}
发布模块
引入依赖
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<version>2.0.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
</dependencies>
自动配置类
在这里 RedisConnectionFactory 回去读取 yaml 的 redis 配置,可以在 yaml 中配置 redis 地址
@Configuration
public class AutoConfig {
@Bean
public RedisTemplate<String, Object> redisMessageTemplate(RedisConnectionFactory connectionFactory) {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(connectionFactory);
template.setDefaultSerializer(new FastJsonRedisSerializer<>(Object.class));
return template;
}
}
yaml
server:
port: 8000
spring:
redis:
host: 127.0.0.1
port: 6379
发布者
@Service
public class Publisher {
private final RedisTemplate<String, Object> redisMessageTemplate;
@Autowired
public Publisher(RedisTemplate<String, Object> redisMessageTemplate) {
this.redisMessageTemplate = redisMessageTemplate;
}
public void pushMessage(String topic, Object message) {
redisMessageTemplate.convertAndSend(topic, message);
}
}
测试:发送消息
先启动接收者,并在 springboot 的测试模块中写入以下代码,可以观察接收者控制台打印。
@SpringBootTest
public class RedisPublishTest {
@Resource
private Publisher publisher;
@Test
public void test() {
publisher.pushMessage("test-redis-push", "data");
}
}
原文地址:https://blog.csdn.net/qq_45260619/article/details/134784598
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.7code.cn/show_42724.html
如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱:suwngjj01@126.com进行投诉反馈,一经查实,立即删除!
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。