ICode9

精准搜索请尝试: 精确搜索
首页 > 数据库> 文章详细

使用Spring Data Redis的Redis Pub / Sub:消息以错误的顺序到达

2019-05-19 19:05:38  阅读:383  来源: 互联网

标签:java spring redis spring-data-redis


我正在尝试使用Redis发布/订阅Spring Data Redis来实现聊天.

我使用RedisTemplate发布消息,如下所示:

public class RedisPublisher {

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    public void publish(ChannelTopic channelTopic, Object channelMessage) {
        redisTemplate.convertAndSend(channelTopic.getTopic(), channelMessage);
    }
}

为了接收消息,我有一个MessageListener,如下所示:

public class RedisConsumer implements MessageListener {

MessageSerializer serializer = new MessageSerializer();
AtomicInteger atomicInteger = new AtomicInteger(0);

@Override
public void onMessage(Message message, byte[] pattern) {

    Object obj = serializer.deserialize(message.getBody());
    if(obj != null && obj instanceof RedisMessage) {
        System.err.println("Received message(" + atomicInteger.incrementAndGet() + ") " + obj.toString());
    }

}

消息的发布方式如下:

final ChannelTopic channelTopic=connectionManager.subscribe("topic");
    new Thread(new Runnable() {
        public void run() {                
            Thread.sleep(5000);                
            for (int i = 0; i < 10; i++) {
                redisPublisher.publish(channelTopic, new RedisMessage(i + 1));
            }
        }
    }).run();

但是,收到的消息似乎以错误的顺序传递:

Received message(1) message id: 3
Received message(2) message id: 2
Received message(3) message id: 1
Received message(4) message id: 4
Received message(5) message id: 5
Received message(6) message id: 6
Received message(7) message id: 7
Received message(8) message id: 8
Received message(9) message id: 9
Received message(10) message id: 10

是否可以使用Spring提供的RedisTemplate / MessageListener同步发送/接收消息?

目前的代码库很小,可以在GitHub查看.

解决方法:

众所周知,Redis PubSub按顺序传递消息(至少在使用一个连接并触发PUBLISH时保证.PUBLISH命令返回已通知的客户端数).无序的原因是Spring Data Redis默认调度消息的方式.通知是在不同的线程上处理的,这就是原因.感谢您的代码,它帮助我快速重现行为.

我可以想到两种可能的策略来解决这个问题:

>但是,您可以提供在RedisMessageListenerContainer中遵守订单的执行程序.现在,我正在考虑的任何形式的同步都会损害性能.
>在BinaryJedisPubSub之上实现自己的消息监听器.您可以控制消息,并且可以省略执行程序问题.

HTH,马克

标签:java,spring,redis,spring-data-redis
来源: https://codeday.me/bug/20190519/1136815.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有