• 设为首页
  • 收藏本站
  • 积分充值
  • VIP赞助
  • 手机版
  • 微博
  • 微信
    微信公众号 添加方式:
    1:搜索微信号(888888
    2:扫描左侧二维码
  • 快捷导航
    福建二哥 门户 查看主题

    使用Redis防止重复发送RabbitMQ消息的方法详解

    发布者: 福建二哥 | 发布时间: 2025-6-19 12:45| 查看数: 121| 评论数: 0|帖子模式

    问题

    今天遇到一个问题,发送
    1. MQ
    复制代码
    消息的时候需要保证不会重复发送,注意不是可靠到达(可靠到达可以通过消息确认机制和回调接口保证),这里保证的是不会生产多条一样的消息。

    方法

    综合讨论下来决定使用
    1. Redis
    复制代码
    缓存来解决,因为相比于将记录插入数据库
    1. Redis
    复制代码
    更为高效和便捷。

    检验是否已经发送

    在发送消息之前根据相关信息组合成
    1. key
    复制代码
    1. Redis
    复制代码
    中查找,找到后检测值是否为存在并且是否为设定的值,若存在且与设定的值一样,则返回
    1. false
    复制代码
    ,说明该消息已经发送过了。
    1.     public boolean isSend(String messageType, Long bizId, int hashCode) {
    2.         // 根据消息类型、业务id和哈希值组合成key
    3.         String key = this.genKey(messageType, bizId, hashCode);
    4.         Long value = super.get(key);

    5.         if (value != null && value.equals(DEFAULT_VALUE)) {
    6.             return false;
    7.         }

    8.         return true;
    9.     }
    10.    
    11.    /**get方法*/
    12.     public V get(K key) {
    13.         if (key == null) {
    14.             return null;
    15.         } else {
    16.             try {
    17.                 // 在key前添加前缀和名字,并将原来的key进行json序列化
    18.                 String realKey = this.genRealKey(key);
    19.                 String content = (String)this.redisTemplate.opsForValue().get(realKey);
    20.                 // 若get到的值不为null则进行json反序列化
    21.                 return content == null ? null : this.valueSerializer.deserialize(content);
    22.             } catch (Exception e) {
    23.                 CACHE.error("", key.toString(), "", "0", e);
    24.                 return null;
    25.             }
    26.         }
    27.     }
    复制代码
    以上就是检验消息是否重复的方法,需要注意的是JSON序列化,因为Redis默认使用的是JDK序列化,这种序列化后的内容不仅多而且不易于阅读,因此将其改为Json序列化。

    发送后添加缓存

    在发送消息的时候会先在Redis中put一个以相关信息组合为key,value为默认值的记录,过期时间为5min。
    1.     public void sendMessage(String messageType, Long bizId, int hashCode) {
    2.         super.put(genKey(messageType, bizId, hashCode), DEFAULT_VALUE);
    3.     }
    4.    
    5.     /**put方法*/
    6.     public void put(K key, V value) {
    7.         try {
    8.             if (key != null && null != value) {
    9.                 // 进行json序列化
    10.                 String content = this.valueSerializer.serialize(value);
    11.                 this.redisTemplate.opsForValue().set(this.genRealKey(key), content, this.expires, this.timeUnit);
    12.             }
    13.         } catch (Throwable e) {
    14.             e.printStackTrace();
    15.         }
    16.     }
    复制代码
    发送消息方法

    最后的发送消息方法大致代码如下:
    1.     public void sendMQMessage(Long bizId, String messageTemplateCode, String msg, int msgHashCode, String exchange, String routingKey) {
    2.         //加入缓存
    3.         boolean send = true;
    4.         //String messageType = MessageTypeUtil.getMessageType(messageTemplateCode);
    5.         if (bizId != null) {
    6.             // 检测是否已经发送
    7.             send = sendMessageCache.isSend(messageTemplateCode, bizId, msgHashCode);
    8.         }

    9.         //发送mq消息
    10.         if (send) {
    11.             if (bizId != null) {
    12.                 // 加入缓存
    13.                 sendMessageCache.sendMessage(messageTemplateCode, bizId, msgHashCode);
    14.             }
    15.             // 发送消息
    16.             messageSender.send(exchange, routingKey, msg);
    17.         }
    18.     }
    复制代码
    到此这篇关于使用Redis防止重复发送RabbitMQ消息的方法详解的文章就介绍到这了,更多相关Redis防止重复发送RabbitMQ内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

    来源:https://www.jb51.net/database/334531yv7.htm
    免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

    最新评论

    QQ Archiver 手机版 小黑屋 福建二哥 ( 闽ICP备2022004717号|闽公网安备35052402000345号 )

    Powered by Discuz! X3.5 © 2001-2023

    快速回复 返回顶部 返回列表