问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

使用RabbitMq清除本地多节点缓存

发布网友 发布时间:2024-10-01 17:31

我来回答

1个回答

热心网友 时间:2024-10-17 20:18

场景

服务是多节点部署的,配置由于很少改动又经常被查询,所以将配置数据放入本地缓存中,修改配置后,更新缓存,但是只能更新当前访问节点的缓存,无法修改其他节点的缓存,导致查询数据出现问题。

分析

如何在其中一个节点更新缓存也同时更新其他节点的缓存呢?消息队列是否可以解决此问题呢?

解决

使用Rabbit的广播模式,可以实现,使用交换机绑定队列,而队列在每一个服务节点启动后都生成一个唯一队列和交换机绑定,这样就实现了当发现消息给交换机,会有多个不同的队列对消息进行处理

实现

创建配置,声明交换机,动态队列,绑定交换机队列,绑定监听

/***@author子羽*@Description广播模式清除本地缓存*@Date2021/8/27*/@ConfigurationpublicclassCacheRabbitConfig{publicstaticfinalStringMY_FANOUTEXCHANGE_NAME="local-cache-exchange";/***用UUID来生成一个queue名称,也可以用服务器IP端口作为queue名称*/publicstaticfinalStringMY_QUEUE_NAME=UUID.randomUUID().toString();@AutowiredRabbitTemplaterabbitTemplate;/***创建动态queue自动删除队列,不然会造成队列堆积*@return*/@BeanpublicQueuemyQueue(){returnnewQueue(MY_QUEUE_NAME,true,false,true);}/***创建Exchange*@return*/@BeanpublicFanoutExchangefanoutExchange(){returnnewFanoutExchange(MY_FANOUTEXCHANGE_NAME,true,false);}/***绑定当前queue到Exchange*@return*/@BeanpublicBindingbindingExchangeMyQueue(){returnBindingBuilder.bind(myQueue()).to(fanoutExchange());}/***设置消息处理*@return*/@BeanpublicSimpleMessageListenerContainermqMessageContainer(ClearCacheListenerclearCacheListener){SimpleMessageListenerContainercontainer=newSimpleMessageListenerContainer(rabbitTemplate.getConnectionFactory());container.setQueueNames(MY_QUEUE_NAME);container.setExposeListenerChannel(true);//设置每个消费者获取的最大的消息数量container.setPrefetchCount(1);//消费者个数container.setConcurrentConsumers(1);//设置确认模式为手工确认container.setAcknowledgeMode(AcknowledgeMode.MANUAL);//消息处理类container.setMessageListener(clearCacheListener);returncontainer;}}

设置监听实现

/***@author子羽*@Description监听删除缓存*@Date2021/8/27*/@ComponentpublicclassClearCacheListenerimplementsChannelAwareMessageListener{privatestaticfinalLoggerlog=LoggerFactory.getLogger(ClearCacheListener.class);@AutowiredprivateSysConfigServicesysConfigService;@OverridepublicvoidonMessage(Messagemessage,Channelchannel){try{log.info("接收删除系统配置缓存消息,correlationId:[{}]",newString(message.getMessageProperties().getCorrelationId()));//删除本地缓存sysConfigService.cleanLocal();channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);}catch(Exceptione){log.error("处理清除缓存消息失败",e);}}}

建立消息生产者

/***@author子羽*@descript清除内外部多节点缓存*/@ComponentpublicclassClearCacheProducerextendsAbstractRabbitProducer{protectedstaticfinalLoggerlogger=LogManager.getCurrentClassLogger();publicClearCacheProducer(RabbitTemplaterabbitTemplate){super(rabbitTemplate,MQConstant.APP_ID);}publicvoidsendDelSystemCacheMessage(){CorrelationDatacorrelationData=getCorrelationData();logger.info("发送消息至缓存队列,correlationId:{}消息:[{}]",correlationData.getId(),"清除系统配置缓存");this.sendMsg("local-cache-exchange","","",correlationData);logger.info("发送消息成功correlationId:{}",correlationData.getId());}}

调用清除节点缓存

/***<清空缓存>**@see[类#方法]*/publicvoidclean(){//先清除本节点缓存this.cache.clean();//清除内外部节点系统配置缓存clearCacheProducer.sendDelSystemCacheMessage();}结语

整体实现还是比较简单的,主要的一个比较难想到的是,每个节点会创建出不同的队列,也就是不同节点会产生不同的结果,另外注意的是队列一定要动态队列。

returnnewQueue(MY_QUEUE_NAME,true,false,true);

```/***Constructanewqueue,givenaname,durability,exclusiveandauto-deleteflags.*@paramnamethenameofthequeue.*@paramdurabletrueifwearedeclaringadurablequeue(thequeuewillsurviveaserverrestart)*@paramexclusivetrueifwearedeclaringanexclusivequeue(thequeuewillonlybeusedbythedeclarer's*connection)*@paramautoDeletetrueiftheservershoulddeletethequeuewhenitisnolongerinuse*/publicQueue(Stringname,booleandurable,booleanexclusive,booleanautoDelete){this(name,durable,exclusive,autoDelete,null);}```

durable代表是否持久化队列,如果持久化,那么服务重启队列中的数据还在exclusive排他队列,如果设定为true,那么这个队列仅对这个连接可见autoDelete自动删除,这个自动删除并不是执行一段时间字段删除,而是失去监听后自动删除,这次我设定就是自动删除,因为如果不设定自动删除,重启节点后,会生成一个新节点而原有节点也不会删除,会导致rabbitmq出现队列堆积。

作者:千云

热心网友 时间:2024-10-17 20:16

场景

服务是多节点部署的,配置由于很少改动又经常被查询,所以将配置数据放入本地缓存中,修改配置后,更新缓存,但是只能更新当前访问节点的缓存,无法修改其他节点的缓存,导致查询数据出现问题。

分析

如何在其中一个节点更新缓存也同时更新其他节点的缓存呢?消息队列是否可以解决此问题呢?

解决

使用Rabbit的广播模式,可以实现,使用交换机绑定队列,而队列在每一个服务节点启动后都生成一个唯一队列和交换机绑定,这样就实现了当发现消息给交换机,会有多个不同的队列对消息进行处理

实现

创建配置,声明交换机,动态队列,绑定交换机队列,绑定监听

/***@author子羽*@Description广播模式清除本地缓存*@Date2021/8/27*/@ConfigurationpublicclassCacheRabbitConfig{publicstaticfinalStringMY_FANOUTEXCHANGE_NAME="local-cache-exchange";/***用UUID来生成一个queue名称,也可以用服务器IP端口作为queue名称*/publicstaticfinalStringMY_QUEUE_NAME=UUID.randomUUID().toString();@AutowiredRabbitTemplaterabbitTemplate;/***创建动态queue自动删除队列,不然会造成队列堆积*@return*/@BeanpublicQueuemyQueue(){returnnewQueue(MY_QUEUE_NAME,true,false,true);}/***创建Exchange*@return*/@BeanpublicFanoutExchangefanoutExchange(){returnnewFanoutExchange(MY_FANOUTEXCHANGE_NAME,true,false);}/***绑定当前queue到Exchange*@return*/@BeanpublicBindingbindingExchangeMyQueue(){returnBindingBuilder.bind(myQueue()).to(fanoutExchange());}/***设置消息处理*@return*/@BeanpublicSimpleMessageListenerContainermqMessageContainer(ClearCacheListenerclearCacheListener){SimpleMessageListenerContainercontainer=newSimpleMessageListenerContainer(rabbitTemplate.getConnectionFactory());container.setQueueNames(MY_QUEUE_NAME);container.setExposeListenerChannel(true);//设置每个消费者获取的最大的消息数量container.setPrefetchCount(1);//消费者个数container.setConcurrentConsumers(1);//设置确认模式为手工确认container.setAcknowledgeMode(AcknowledgeMode.MANUAL);//消息处理类container.setMessageListener(clearCacheListener);returncontainer;}}

设置监听实现

/***@author子羽*@Description监听删除缓存*@Date2021/8/27*/@ComponentpublicclassClearCacheListenerimplementsChannelAwareMessageListener{privatestaticfinalLoggerlog=LoggerFactory.getLogger(ClearCacheListener.class);@AutowiredprivateSysConfigServicesysConfigService;@OverridepublicvoidonMessage(Messagemessage,Channelchannel){try{log.info("接收删除系统配置缓存消息,correlationId:[{}]",newString(message.getMessageProperties().getCorrelationId()));//删除本地缓存sysConfigService.cleanLocal();channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);}catch(Exceptione){log.error("处理清除缓存消息失败",e);}}}

建立消息生产者

/***@author子羽*@descript清除内外部多节点缓存*/@ComponentpublicclassClearCacheProducerextendsAbstractRabbitProducer{protectedstaticfinalLoggerlogger=LogManager.getCurrentClassLogger();publicClearCacheProducer(RabbitTemplaterabbitTemplate){super(rabbitTemplate,MQConstant.APP_ID);}publicvoidsendDelSystemCacheMessage(){CorrelationDatacorrelationData=getCorrelationData();logger.info("发送消息至缓存队列,correlationId:{}消息:[{}]",correlationData.getId(),"清除系统配置缓存");this.sendMsg("local-cache-exchange","","",correlationData);logger.info("发送消息成功correlationId:{}",correlationData.getId());}}

调用清除节点缓存

/***<清空缓存>**@see[类#方法]*/publicvoidclean(){//先清除本节点缓存this.cache.clean();//清除内外部节点系统配置缓存clearCacheProducer.sendDelSystemCacheMessage();}结语

整体实现还是比较简单的,主要的一个比较难想到的是,每个节点会创建出不同的队列,也就是不同节点会产生不同的结果,另外注意的是队列一定要动态队列。

returnnewQueue(MY_QUEUE_NAME,true,false,true);

```/***Constructanewqueue,givenaname,durability,exclusiveandauto-deleteflags.*@paramnamethenameofthequeue.*@paramdurabletrueifwearedeclaringadurablequeue(thequeuewillsurviveaserverrestart)*@paramexclusivetrueifwearedeclaringanexclusivequeue(thequeuewillonlybeusedbythedeclarer's*connection)*@paramautoDeletetrueiftheservershoulddeletethequeuewhenitisnolongerinuse*/publicQueue(Stringname,booleandurable,booleanexclusive,booleanautoDelete){this(name,durable,exclusive,autoDelete,null);}```

durable代表是否持久化队列,如果持久化,那么服务重启队列中的数据还在exclusive排他队列,如果设定为true,那么这个队列仅对这个连接可见autoDelete自动删除,这个自动删除并不是执行一段时间字段删除,而是失去监听后自动删除,这次我设定就是自动删除,因为如果不设定自动删除,重启节点后,会生成一个新节点而原有节点也不会删除,会导致rabbitmq出现队列堆积。

作者:千云
声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
"电话机响起,你要说话了,还以为你对我又想念了"这句歌词是哪一首歌的... ...电话响起了,你要说话了”,“是你变了”这首歌是什么 关于职业的英语单词小学2o个 ...的英语单词有哪些?要20个以上!人物,其实就是职业什么的,比如医生... 剑网3指尖江湖哪个料理好_性价比高的料理菜肴推荐 剑网3指尖江湖菜谱大全介绍_剑网3指尖江湖菜谱大全是什么 剑网3指尖江湖菜谱大全 我耳朵里长了疙瘩,黑色的,不痛不痒,医生说交界痣,建议我做手术,但现... 耳朵里有耳屎抠出来中间是黑的,抠的时候抠不出来,不动痒痒 微信登不上了 苹果现在允许第三方软件在设备上下载,自己开发的手机应用,怎样可以不通 ... 手机qq语音通话有回音怎么办啊? 德国城市风景随拍高清桌面壁纸2560x160018P 湖南衡阳是哪个省 湖南衡阳有哪些 日本寿司的简易做法 日本寿司的简易做法是什么样的 衡阳是什么省的城市 湖南衡阳有哪些景点值得一去? 衡阳市在哪个市 日本正宗寿司的做法 大家好,我的oppor11被小孩玩忘记密码了,现在如何能解锁呢?谢谢大家给... 为什么要做羊水穿刺 哪些孕妇需要做羊水穿刺 怎么做正宗的佛跳墙? 怎样做出正宗的佛跳墙? ...罗宾逊这样一个强力中锋,会被奥拉朱旺打得那么惨?_百度知... ...生涯共得到28596分,那奥拉朱旺、尤因、罗宾逊多少分呢? 抢票成功是不是就不用付钱了啊? 九十年代 NBA四大中锋之外的四大中锋 在NBA四大中锋里谁的生涯首秀数据最让人惊艳?为何 找首歌词,里面应该有"你是我的爱恋,你是我的思念,温柔的缠绵",女生... RocketMQBinder集成消息订阅 穿越火线手游别人加的我QQ为什么QQ上把这个人删掉之后游戏里QQ好友上... 怎么把电脑蓝色的背景弄回去? 29英寸彩电,显色缺少蓝色,怎么办? 麻烦问一下那个电脑蓝色怎么办 这个要怎么变回蓝色的?还有图标下面本来没有蓝色的要怎么办?? 电脑蓝色了怎么办 电脑出现蓝色空白怎么办?图标都不见了!主菜单那儿也找不到! 你好,请问我的驾驶证丢失有一个星期了,别人会拿我的驾驶证去做违章的... 我的驾驶证丢了.不知道有没有违章.要怎么查询 地效飞行器优点介绍 飞行器有什么作用 我的驾驶证丢了,我在补办时遇到了有一个异的违章,是现场罚款单(和罚款... 地效飞行器军事应用 今起未来三天重庆多云为主 明傍晚迎弱降水出行带伞 重庆今起三天阴或多云为主 后天最高气温可达16℃ 幼儿园里要布置植物角,不知道什么植物比较合适 22日-24日重庆未来三天雨水渐歇 明后天部分地区有大雾出没 一星期七天如何用英文表示? 星期1到7用英语怎么说