欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 新闻 > 会展 > 使用Redis防止重复发送RabbitMQ消息

使用Redis防止重复发送RabbitMQ消息

2025/1/24 5:46:22 来源:https://blog.csdn.net/weixin_52093727/article/details/145107551  浏览:    关键词:使用Redis防止重复发送RabbitMQ消息

问题

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

方法

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

检验是否已经发送

在发送消息之前根据相关信息组合成keyRedis中查找,找到后检测值是否为存在并且是否为设定的值,若存在且与设定的值一样,则返回false,说明该消息已经发送过了。

    public boolean isSend(String messageType, Long bizId, int hashCode) {// 根据消息类型、业务id和哈希值组合成keyString key = this.genKey(messageType, bizId, hashCode);Long value = super.get(key);if (value != null && value.equals(DEFAULT_VALUE)) {return false;}return true;}/**get方法*/public V get(K key) {if (key == null) {return null;} else {try {// 在key前添加前缀和名字,并将原来的key进行json序列化String realKey = this.genRealKey(key);String content = (String)this.redisTemplate.opsForValue().get(realKey);// 若get到的值不为null则进行json反序列化return content == null ? null : this.valueSerializer.deserialize(content);} catch (Exception e) {CACHE.error("", key.toString(), "", "0", e);return null;}}}

以上就是检验消息是否重复的方法,需要注意的是JSON序列化,因为Redis默认使用的是JDK序列化,这种序列化后的内容不仅多而且不易于阅读,因此将其改为Json序列化。

发送后添加缓存

在发送消息的时候会先在Redisput一个以相关信息组合为keyvalue为默认值的记录,过期时间为5min

    public void sendMessage(String messageType, Long bizId, int hashCode) {super.put(genKey(messageType, bizId, hashCode), DEFAULT_VALUE);}/**put方法*/public void put(K key, V value) {try {if (key != null && null != value) {// 进行json序列化String content = this.valueSerializer.serialize(value);this.redisTemplate.opsForValue().set(this.genRealKey(key), content, this.expires, this.timeUnit);}} catch (Throwable e) {e.printStackTrace();}}

发送消息方法

最后的发送消息方法大致代码如下:

    public void sendMQMessage(Long bizId, String messageTemplateCode, String msg, int msgHashCode, String exchange, String routingKey) {//加入缓存boolean send = true;//String messageType = MessageTypeUtil.getMessageType(messageTemplateCode);if (bizId != null) {// 检测是否已经发送send = sendMessageCache.isSend(messageTemplateCode, bizId, msgHashCode);}//发送mq消息if (send) {if (bizId != null) {// 加入缓存sendMessageCache.sendMessage(messageTemplateCode, bizId, msgHashCode);}// 发送消息messageSender.send(exchange, routingKey, msg);}}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com