我一直在使用spring-data-Redis来实现PUB / SUB服务。 我一直在研究和关注网络,并得到了一些工作正常。 我的问题是,当没有处理消息时,我需要绝对的可靠性(抛出异常或发生逻辑错误)。 在这种情况下,我需要消息返回主题以进行重试(由另一个订阅者甚至相同)。
我看过几个问题,特别是以下问题: Redis Pub/Sub with Reliability 和 How to implement Redis Multi-Exec by using Spring-data-Redis
我已经明白我应该使用multi,exec来管理事务,但我无法让它工作。
以下是我的代码的简化版
@Configuration
@PropertySource(value = { "classpath:application.properties" })
public class RedisConfig {
@Autowired
Environment env;
@Bean
public MessageListenerAdapter messageListener() {
MyMessageListenerAdapter messageListeneradapter = new MyMessageListenerAdapter(new RedisMessageSubscriber());
messageListeneradapter.afterPropertiesSet();
return messageListeneradapter;
}
@Bean(name="RedisMessagePublisherBean")
public RedisMessagePublisher messagePublisher() {
return new RedisMessagePublisher();
}
@Bean
public RedisTemplate<String, Object> redisTemplate() {
RedisTemplate<String , Object> template = new RedisTemplate<>();
template.setValueSerializer(new GenericToStringSerializer<Object>(Object.class));
template.setEnableTransactionSupport(true);
template.setConnectionFactory(lettuceConnectionFactory());
return template;
}
@Bean
public RedisMessageListenerContainer redisContainer() {
RedisMessageListenerContainer container
= new RedisMessageListenerContainer();
container.setConnectionFactory(lettuceConnectionFactory());
container.addMessageListener(messageListener(), topic());
return container;
}
@Bean
public LettuceConnectionFactory lettuceConnectionFactory() {
LettuceConnectionFactory factory = new LettuceConnectionFactory();
factory.setValidateConnection(true);
factory.setDatabase(1);
factory.afterPropertiesSet();
return factory;
}
@Bean
public ChannelTopic topic() {
return new ChannelTopic("MQ_TOPIC");
}
public class MyMessageListenerAdapter extends MessageListenerAdapter{
public MyMessageListenerAdapter(RedisMessageSubscriber redisMessageSubscriber) {
super(redisMessageSubscriber);
}
@Override
public void onMessage(Message message, byte[] pattern) {
RedisTemplate<?, ?> template = redisTemplate();
template.execute(new SessionCallback<String>() {
@Override
public <K, V> String execute(RedisOperations<K, V> operations) throws DataAccessException {
operations.multi();
System.out.println("got message");
String result = doSomeLogic(message);
if (result == null)
operations.discard();
else
operations.exec();
return null;
}
}) ;
}
}
}
我的要求是,如果消息无法处理(我可以在没有运行时异常等情况下离开......严格的逻辑错误就足够了),它将返回到主题。
感谢任何帮助,谢谢!