redis配置多数据源对消息进行发布订阅
准备redis环境
由于是测试,所以在虚拟机准备了两个数据源,数据源如下
- 192.168.198.139 6378
- 192.168.198.139 6379
均无密码
添加依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>
配置文件配置主数据源
spring:
redis:
host: 192.168.198.139
port: 6378
配置自定义数据源操作工具
import org.springframework.context.annotation.Bean;
import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.stereotype.Component;
@Component
public class RedisConfig {
/**配置自定义Template*/
@Bean(name = "diyRedisTemplate")
public RedisTemplate<String, Object> diyRedisTemplate() {
RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration("192.168.198.139",6379);
//密码配置,没有可不配
//redisStandaloneConfiguration.setPassword(RedisPassword.of(""));
JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory(redisStandaloneConfiguration);
jedisConnectionFactory.afterPropertiesSet();
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setDefaultSerializer(new StringRedisSerializer());
redisTemplate.setConnectionFactory(jedisConnectionFactory);
return redisTemplate;
}
}
配置监听回调
自定义监听
import lombok.RequiredArgsConstructor;
import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.connection.MessageListener;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
/**
* @author wzx
* @date 2023-06-29 11:35
* @return 消息订阅的回调方法
*/
@Component
@RequiredArgsConstructor
public class RedisMessageListener implements MessageListener {
/**自定义操作工具*/
private final RedisTemplate<String,Object> diyRedisTemplate;
@Override
public void onMessage(Message message, byte[] pattern) {
// 获取消息
byte[] messageBody = message.getBody();
// 使用值序列化器转换
Object msg = diyRedisTemplate.getValueSerializer().deserialize(messageBody);
// 获取监听的频道
byte[] channelByte = message.getChannel();
// 使用字符串序列化器转换
Object channel = diyRedisTemplate.getStringSerializer().deserialize(channelByte);
//队列名称转换
String patternStr = new String(pattern);
System.out.println("自定义通道名称"+patternStr);
System.out.println("自定义通道名称:" + channel);
System.out.println("自定义消息内容: " + msg);
}
}
主监听
import lombok.RequiredArgsConstructor;
import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.connection.MessageListener;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
@Component
@RequiredArgsConstructor
public class RedisMessageListener1 implements MessageListener {
/**原生操作工具*/
private final RedisTemplate<String,String> redisTemplate;
@Override
public void onMessage(Message message, byte[] pattern) {
// 获取消息
byte[] messageBody = message.getBody();
// 使用值序列化器转换
Object msg = redisTemplate.getValueSerializer().deserialize(messageBody);
// 获取监听的频道
byte[] channelByte = message.getChannel();
// 使用字符串序列化器转换
Object channel = redisTemplate.getStringSerializer().deserialize(channelByte);
//队列名称转换
String patternStr = new String(pattern);
System.out.println("原生通道名称"+patternStr);
System.out.println("原生通道名称:" + channel);
System.out.println("原生消息内容: " + msg);
}
}
监听回调添加
import com.redis.listen.RedisMessageListener;
import com.redis.listen.RedisMessageListener1;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Bean;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.listener.ChannelTopic;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.stereotype.Component;
/**
* 订阅配置类,绑定不同的监听并指定监听channel
* @author wzx
* @date 2023-06-29 13:45
*/
@Component
@RequiredArgsConstructor
public class RedisListenerConfig {
private final RedisMessageListener redisMessageListener;
private final RedisMessageListener1 redisMessageListener1;
@Bean
public RedisMessageListenerContainer container(RedisConnectionFactory factory) {
RedisMessageListenerContainer container = new RedisMessageListenerContainer();
container.setConnectionFactory(factory);
//订阅频道自定义diy
container.addMessageListener(redisMessageListener, new ChannelTopic("diy"));
//订阅频道原生配置primary
container.addMessageListener(redisMessageListener1, new ChannelTopic("primary"));
return container;
}
}
功能测试
写了一个controller
import lombok.RequiredArgsConstructor;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
@RestController
@RequestMapping("/redis")
@RequiredArgsConstructor
public class RedisController {
private final RedisTemplate<String,Object> diyRedisTemplate;
private final RedisTemplate<String,String> redisTemplate;
@PostMapping("add")
public String add(String key,String value,Long time){
if (Objects.nonNull(time)){
diyRedisTemplate.opsForValue().set(key, value,time, TimeUnit.MILLISECONDS);
redisTemplate.opsForValue().set(key, value,time, TimeUnit.MILLISECONDS);
}else {
redisTemplate.opsForValue().set(key, value);
diyRedisTemplate.opsForValue().set(key, value);
}
return "OK";
}
@PostMapping("delete")
public String delete(String key){
if (diyRedisTemplate.hasKey(key)){
diyRedisTemplate.delete(key);
}
return "OK";
}
/**使用原生的发送,会根据topic发送到不同的监听订阅*/
@PostMapping("send")
public String send(String topic,String value){
redisTemplate.convertAndSend(topic,value);
return "OK";
}
测试结果
调取增加,测试多数据源是否配置成功


数据两个库里面都有,说明多数据源配置成功。
测试发布订阅功能
请求示例:

使用不同的topic进行测试,先请求了diy,后请求了primary,请求结果如下

这里有个问题,那就是只要是RedisTemplate的类型是RedisTemplate<String,String>,使用任意一个bean发布消息,效果是一样的,会根据不同的订阅channel,结果回调到不同的监听器,但其它类型的发布后,消息接收不到;
需要源代码或技术交流可添加 Q:1343314118
1万+

被折叠的 条评论
为什么被折叠?



