昨天,在公司开发环境上尝试数据同步,涉及到两个服务,服务A发布主题,服务B监听消息,然后同步A表中的数据到B表;
由服务A通过activemq发布消息到一个topic:VirtualTopic.topic,发现服务A日志上显示发送消息成功,VirtualTopic.topic对应的Messages Enqueued数目增加了2,表明topic上也产生了相应数目消息队列;但是服务B日志上迟迟没有打印接收消息的日志,到服务B接收数据的表中查看也没有同步过来的数据,到activeMQ可视化界面上查看,果然没有消息被消费;
为了节省资源,公司的activeMQ是新安装在虚拟机上的,原来安装activeMQ的实体机服务器不再使用,于是猜测肯定安装过程出现了与之前不一致的现象;
排查原因:
1.猜测读取了重名的配置文件:我们使用的activemq.xml是放在一个公共jar包中引入的,更改mq服务器后,原来存放activemq.xml的文件夹被重命名为conf_old,新的配置文件还是放在conf路径下,这样jar包中就有了两个acrivemq.xml文件,于是猜测是不是程序在读取jar包中xml文件时读取到了老的配置,所以监听的activemq服务ip错误,但是到老的activemq上显示的消费者为0,新的activemq上显示消费者为2,除了我和服务器上之外没有别人启动服务B,自然这种可能就被排除了;
2.猜测由于activemq服务器时间与本地时间不一致导致没有接受到消息:网上查了几种原因,发现可能由于服务器时间与本地时间不一致导致的,检查本地时间,果然比服务器时间快5分钟,于是更改本地时间与服务器时间一致,再次尝试,依然没有接收到消息,这种可能也被排除;
3.发现A服务发送消息是用的topic模式,而服务B接收的只是队列(Queues)消息,没有监听对应的topic,会不会之前有什么设置让topic中的主题与queues中的队列做了关联:
于是求助公司的一位大佬,了解到在activemq的配置文件中可能有对虚拟主题的配置,于是拉取原来服务器的activemq.xml配置文件与现在使用的activemq服务器上的配置文件进行比对,果然发现了不同,之前文件多了一项配置:
<destinationInterceptors>
<virtualDestinationInterceptor>
<virtualDestinations>
<virtualTopic name=">" prefix="Prename.*." selectorAware="false"/>
</virtualDestinations>
</virtualDestinationInterceptor>
</destinationInterceptors>
关于这个配置涉及到ActiveMQ高级特性Destination,看了两篇文章讲解了此特性的用法:
ActiveMQ高级特性:VirtualTopic
https://blog.csdn.net/paul_wei2008/article/details/51252255
ActiveMQ Destination高级特性
https://blog.csdn.net/zhanglh046/article/details/52830624?locationNum=4
因为A服务发布的消息主题为VirtualTopic.topic,而B服务监听的队列为Prename.secname.VirtualTopic.topic,所以在配置中做了忽略前缀的设置后就可以监听到对应主题的消息了,而问题也解决了:
A服务发布消息:
B服务消费消息: