Redis PUBSUB Spring Data跨国可靠性/重试

时间:2017-12-31 20:45:17

标签: redis transactions spring-data-redis

我一直在使用spring-data-Redis来实现PUB / SUB服务。 我一直在研究和关注网络,并得到了一些工作正常。 我的问题是,当没有处理消息时,我需要绝对的可靠性(抛出异常或发生逻辑错误)。 在这种情况下,我需要消息返回主题以进行重试(由另一个订阅者甚至相同)。

我看过几个问题,特别是以下问题: Redis Pub/Sub with ReliabilityHow 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;
            }
        })  ;


    }

}
}

我的要求是,如果消息无法处理(我可以在没有运行时异常等情况下离开......严格的逻辑错误就足够了),它将返回到主题。

感谢任何帮助,谢谢!

0 个答案:

没有答案