解决redis序列化乱码问题
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.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;
@Configuration
public class RedisConfig {
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(redisConnectionFactory);
template.setKeySerializer(new StringRedisSerializer());
template.setValueSerializer(new StringRedisSerializer());
return template;
}
}
1.点对点方式
/**
* 测试redis队列
*/
@GetMapping("/senRedisMsgTest")
public void senRedisMsgTest() {
redisTemplate.opsForList().leftPush("username", "abcd");
redisTemplate.opsForList().leftPush("username", "efgh");
redisTemplate.opsForList().leftPush("username", "qwer");
String username = String.valueOf(redisTemplate.opsForList().rightPop("username"));
System.err.println(username);
}
缺点是用rightPop()从redis队列中获取放入的元素时,只会按顺序拿出一条,如果是频繁写入,会存在无法全量拉取的问题
2.发布订阅模式
1.定义发布者
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
@Service
public class RedisPublisher {
@Autowired
private RedisTemplate<String, Object> redisTemplate;
public void publish(String channel, String message) {
redisTemplate.convertAndSend(channel, message);
}
}
2.发布者测试代码
@Autowired
private RedisPublisher redisPublisher;
@GetMapping("/publish")
public String publish() {
redisPublisher.publish("user_channel", "testMsg");
return "Message published!";
}
3.配置订阅者配置类
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;
@Configuration
public class RedisSubscriberConfig {
@Bean
RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory,
MessageListenerAdapter listenerAdapter) {
RedisMessageListenerContainer container = new RedisMessageListenerContainer();
container.setConnectionFactory(connectionFactory);
container.addMessageListener(listenerAdapter, new ChannelTopic("user_channel"));
return container;
}
@Bean
MessageListenerAdapter listenerAdapter(RedisSubscriber receiver) {
return new MessageListenerAdapter(receiver, "onMessage");
}
}
4.订阅者接受处理消息
import org.springframework.stereotype.Component;
@Component
public class RedisSubscriber {
public void onMessage(String message, String pattern) {
System.err.println(message);
System.err.println("Received <" + pattern + "> message: " + message);
}
}
结果图:
发布订阅模式,在a服务写入时,b服务实时监听,进行处理,完美解决,需保证ab服务是同一个redis服务,且订阅者配置类中的channel和监听的方法名与发布者一致