springboot整合redis实现消息发布和订阅
redis消息发布订阅的机制:
发布者将消息发布在一个channel(可认为是频道)上,可以供多个订阅者订阅查看信息,所以说channel是连接发布者和订阅者之间的桥梁。
- 实现消息发布者
package com.otitan.mc.otitanmcnews.controller;
import com.otitan.mc.otitanmcnews.service.RedisServices;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiModelProperty;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @Description: 实现发布者
* @Author: xuyb
* @CreateDate: 2021/5/13 0013 10:33
* @UpdateUser: xuyb
* @UpdateDate: 2021/5/13 0013 10:33
* @UpdateRemark: 修改内容
* @Version: 1.0
*/
@Slf4j
@Api(tags = "发送消息")
@RequestMapping("/redis")
@RestController
public class RedisController {
@Autowired
RedisTemplate<String,String> redisTemplate;
@Autowired
RedisServices redisServer;
@ApiModelProperty(value = "redis实现消息发布和订阅")
@GetMapping("/publish")
public String sendMessage(String msg){
return redisServer.sendMessage(msg);
}
}
- RedisServices类实现
package com.otitan.mc.otitanmcnews.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
/**
* @Auther: fengtingxu
* @Date: 2021/5/13 0013 *
* @Description: redis实现消息发布和订阅 *
* @version: 1.0
*/
@Service
public class RedisServices {
@Autowired
RedisTemplate<String,String> redisTemplate;
public String sendMessage(String msg){
try {
redisTemplate.convertAndSend("topic", msg);
System.out.println(msg);
return "消息发送成功";
} catch (Exception e) {
e.printStackTrace();
return "消息发送失败";
}
};
}
- 定义消息接受者(订阅者,实际业务中我们可以定义多个)
package com.otitan.mc.otitanmcnews.config;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.connection.MessageListener;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.stereotype.Component;
/**
* @Description: 消息接受者(消息订阅者)
* @Author: xuyb
* @CreateDate: 2021/5/13 0013 10:05
* @UpdateUser: xuyb
* @UpdateDate: 2021/5/13 0013 10:05
* @UpdateRemark: 修改内容
* @Version: 1.0
*/
@Component
public class MessageReceiver implements MessageListener {
@Autowired
private RedisTemplate redisTemplate;
private static Logger logger = LoggerFactory.getLogger(MessageReceiver.class);
@Override
public void onMessage(Message message, byte[] bytes) {
RedisSerializer<String> redisSerializer = redisTemplate.getStringSerializer();
String msg= redisSerializer.deserialize(message.getBody());
System.out.println("接收到的消息是:"+ msg);
logger.info("Received <" + msg + ">");
}
}
- 定义redis配置类(主要两部分:Redis消息监听器容器、消息监听器适配器)
package com.otitan.mc.otitanmcnews.config;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.listener.PatternTopic;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.data.redis.listener.adapter.MessageListenerAdapter;
/**
* @Description: redis消息监听器和适配器的配置
* @Author: xuyb
* @CreateDate: 2021/5/13 0013 10:20
* @UpdateUser: xuyb
* @UpdateDate: 2021/5/13 0013 10:20
* @UpdateRemark: 修改内容
* @Version: 1.0
*/
@Configuration
@AutoConfigureAfter({MessageReceiver.class})
public class MyRedisConfig {
/*
* Redis消息监听器容器
* 这个容器加载了RedisConnectionFactory和消息监听器
* 可以添加多个监听不同话题的redis监听器,只需要把消息监听器和相应的消息订阅处理器绑定,该消息监听器
* 通过反射技术调用消息订阅处理器的相关方法进行一些业务处理
*/
@Bean
public RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory, MessageListenerAdapter adapter) {
RedisMessageListenerContainer container = new RedisMessageListenerContainer();
container.setConnectionFactory(connectionFactory);
//可以添加多个 messageListener
container.addMessageListener(adapter,new PatternTopic("topic"));
return container;
}
/*
* 消息监听器适配器,绑定消息处理器,利用反射技术调用消息处理器的业务方法
* 将MessageReceiver注册为一个消息监听器,可以自定义消息接收的方法(handleMessage)
* 如果不指定消息接收的方法,消息监听器会默认的寻找MessageReceiver中的onMessage这个方法作为消息接收的方法
*/
@Bean
public MessageListenerAdapter adapter(MessageReceiver messageReceiver) {
return new MessageListenerAdapter(messageReceiver, "onMessage");
}
}
- 配置下端口和redis
# 端口
server:
port: 17758
#redis配置
redis:
# cluster:
# nodes:
# 192.168.0.10:7001
host: 127.0.0.1
password:
port: 6379
# 连接超时时间(毫秒)
timeout: 1000
jedis:
pool:
# 连接池最大连接数(使用负值表示没有限制)
max-active: 20
# 连接池最大阻塞等待时间(使用负值表示没有限制)
max-wait: -1
# 连接池中的最大空闲连接
max-idle: 20
# 连接池中的最小空闲连接
min-idle: 0
-
访问测试
例子:消息者发送一条1234的消息
http://localhost:17758/redis/publish?msg=“1234” -
消息发送成功
- 接受者接受到消息