ActiveMQ高级特性:虚拟Destinations实现消费者分组

ActiveMQ高级特性:虚拟Destinations实现消费者分组与简单路由 ActiveMQ支持的虚拟Destinations分为有两种,分别是 Ø 虚拟主题(Virtual Topics) Ø 组合 Destinations(CompositeDestinations) 这两种虚拟Destinations可以看做对简单的topic和queue用法的补充,基于它们可以实现一些简单有用的EIP功能,虚拟主题类似于1对多的分支功能+消费端的cluster+failover,组合Destinations类似于简单的destinations直接的路由功能。 阅读详情

虚拟Destinations可以看做对简单的topic和queue用法的补充,基于它们可以实现一些简单有用的EIP功能,虚拟主题类似于1对多的分支功能+消费端的cluster+failover

虚拟主题(Virtual Topics)

ActiveMQ中,topic只有在持久订阅(durablesubscription)下是持久化的。存在持久订阅时,每个持久订阅者,都相当于一个持久化的queue的客户端,它会收取所有消息。这种情况下存在两个问题:

1.同一应用内consumer端负载均衡的问题:同一个应用上的一个持久订阅不能使用多个consumer来共同承担消息处理功能。因为每个都会获取所有消息。queue模式可以解决这个问题,broker端又不能将消息发送到多个应用端。所以,既要发布订阅,又要让消费者分组,这个功能jms规范本身是没有的。

2.同一应用内consumer端failover的问题:由于只能使用单个的持久订阅者,如果这个订阅者出错,则应用就无法处理消息了,系统的健壮性不高。

为了解决这两个问题,ActiveMQ中实现了虚拟Topic的功能。使用起来非常简单。

对于消息发布者来说,就是一个正常的Topic,名称以VirtualTopic.开头。例如VirtualTopic.TEST。

对于消息接收端来说,是个队列,不同应用里使用不同的前缀作为队列的名称,即可表明自己的身份即可实现消费端应用分组。例如Consumer.A.VirtualTopic.TEST,说明它是名称为A的消费端,同理Consumer.B.VirtualTopic.TEST说明是一个名称为B的客户端。可以在同一个应用里使用多个consumer消费此queue,则可以实现上面两个功能。又因为不同应用使用的queue名称不同(前缀不同),所以不同的应用中都可以接收到全部的消息。每个客户端相当于一个持久订阅者,而且这个客户端可以使用多个消费者共同来承担消费任务。

Virtual Topics使用示例如下

[java] view plaincopy

package kk;  

import java.util.concurrent.atomic.AtomicInteger;  

import javax.jms.Message;  

import javax.jms.MessageConsumer;  

import javax.jms.MessageListener;  

import javax.jms.MessageProducer;  

import javax.jms.Queue;  

import javax.jms.Session;  

import javax.jms.TextMessage;  

  

import org.apache.activemq.ActiveMQConnection;  

import org.apache.activemq.ActiveMQConnectionFactory;  

import org.apache.activemq.command.ActiveMQQueue;  

import org.apache.activemq.command.ActiveMQTopic;  

  

public class TestVirtualTopic {  

  

    public static void main(String[] args) {  

        try {  

  

            ActiveMQConnectionFactory factoryA = new ActiveMQConnectionFactory(  

                    "tcp://127.0.0.1:61616");  

  

            Queue queue = new ActiveMQQueue(getVirtualTopicConsumerNameA());  

            ActiveMQConnection conn = (ActiveMQConnection) factoryA  

                    .createConnection();  

            conn.start();  

            Session session = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);  

  

            MessageConsumer consumer1 = session.createConsumer( queue );  

            MessageConsumer consumer2 = session.createConsumer( queue );  

            MessageConsumer consumer3 = session.createConsumer( new ActiveMQQueue(getVirtualTopicConsumerNameB()) );  

            final AtomicInteger aint1 = new AtomicInteger(0);  

            MessageListener listenerA = new MessageListener() {  

                public void onMessage(Message message) {  

                    try {  

                        System.out.println(aint1.incrementAndGet()  

                                + " => receive from "+ getVirtualTopicConsumerNameA() +": " + message);  

                    } catch (Exception e) {  

                        e.printStackTrace();  

                    }  

                }  

            };  

            consumer1.setMessageListener(listenerA);  

            consumer2.setMessageListener(listenerA);  

            final AtomicInteger aint2 = new AtomicInteger(0);  

            MessageListener listenerB = new MessageListener() {  

                public void onMessage(Message message) {  

                    try {  

                        System.out.println(aint2.incrementAndGet()  

                                + " => receive from "+ getVirtualTopicConsumerNameB() +": " + message);  

                    } catch (Exception e) {  

                        e.printStackTrace();  

                    }  

                }  

            };  

            consumer3.setMessageListener(listenerB);  

              

            MessageProducer producer = session.createProducer(new ActiveMQTopic(getVirtualTopicName()));  

            int index = 0;  

            while (index++ < 100) {  

                TextMessage message = session.createTextMessage(index  

                        + " message.");  

                producer.send(message);  

            }  

  

        } catch (Exception e) {  

            e.printStackTrace();  

        }  

    }  

      

      protected static String getVirtualTopicName() {  

            return "VirtualTopic.TEST";  

        }  

  

        protected static String getVirtualTopicConsumerNameA() {  

            return "Consumer.A.VirtualTopic.TEST";  

        }  

          

        protected static String getVirtualTopicConsumerNameB() {  

            return "Consumer.B.VirtualTopic.TEST";  

        }  

  

}  

 

使用同样queue名称的消费者会平分所有消息。

从queue接收到的消息,message.getJMSDestination().toString()为topic://VirtualTopic.TEST,即原始的destination。消息的persistent属性为true,即每个相当于一个持久订阅。

Virtual Topic这个功能特性在broker上有个总开关,useVirtualTopics属性,默认为true,设置为false即可关闭此功能。

当此功能开启,并且使用了持久化的存储时,broker启动的时候会从持久化存储里拿到所有的destinations的名称,如果名称模式与Virtual Topics匹配,则把它们添加到系统的Virtual Topics列表中去。当然,没有显式定义的Virtual Topics,也可以直接使用的,系统会自动创建对应的实际topic。

当有consumer访问此VirtualTopics时,系统会自动创建持久化的queue,并在每次Topic收到消息时,分发到具体的queue。

消费端使用的queue名称前缀的Consumer是可以修改的。示例如下:

[java] view plaincopy

<beans  

  xmlns="http://www.springframework.org/schema/beans"  

  xmlns:amq="http://activemq.apache.org/schema/core"  

  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  

  xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd  

  http://activemq.apache.org/schema/core http://activemq.apache.org/schema/core/activemq-core.xsd">  

   

<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer" />  

   

  <broker xmlns="http://activemq.apache.org/schema/core">  

    <destinationInterceptors>  

      <virtualDestinationInterceptor>  

        <virtualDestinations>  

          <virtualTopic name=">"prefix="VirtualTopicConsumers.*."selectorAware="false"/>  

        </virtualDestinations>  

      </virtualDestinationInterceptor>  

    </destinationInterceptors>  

   

  </broker>  

</beans>  


前缀修改成了VirtualTopicConsumers。

其实也可以使用postfix属性设置后缀(貌似一般没有必要)。

selectorAware属性则表明如果consumer端有selector,则只有匹配selector的消息才会分派到对应的queue中去。

ActiveMQ高级特性:基于虚拟Destinations的消费者分组与简单路由 通过创建虚拟Destination,并将消费者注册到它上面,我们可以实现多个消费者同时处理来自同一个源的消息。此外,通过设置消息的特定属性,我们可以将消息路由到合适的目标消费者。其中,虚拟Destinations是ActiveMQ的一个高级特性,它可以实现消费者分组和简单路由,为消息传递提供了更灵活和可扩展的方式。接下来,我们将创建一个虚拟Destination,并使用它来实现消费者分组和简单路由。通过以上代码,我们实现了消息的发送和接收,并且通过虚拟Destinations实现了消费者分组和简单路由。 阅读详情

相关推荐

ActiveMQ高级特性:虚拟目标实现消费者分组与简单路由 编程

其中之一就是虚拟目标(Virtual Destinations),通过虚拟目标,我们可以实现消费者分组和简单的路由功能。本文将介绍如何在ActiveMQ中使用虚拟目标来实现消费者分组和简单路由,并提供相应的源代码。通过使用ActiveMQ的虚拟目标功能,我们可以实现消费者分组和简单的路由。消费者分组可以帮助我们实现负载均衡和并行处理,而简单路由则可以根据消息的属性或路由规则决定消息发送给哪些消费者。希望本文能对您有所帮助!它允许消息发布者将消息发送到一个虚拟目标上,然后由不同的消费者从该虚拟目标订阅消息。

CyberFlare的博客 277

ActiveMQ之生产分组消息、消费分组消息

今天突然遇到一个需求,就是要求我的ActiveMQ队列消息需要多个线程消费者去消费,但是每个消费者,虽然MQ支持多个消费者但是,每个消费者消费的数量可能不同,有的线程跑的快的,就肯定会多消费一些,但是现在的需求是要每个线程消费的数量一样,这就需要用到MQ分组了, 首先是在消息生产的时候就就对每个消息进行分组 生产者工具类 @Component public c...

静风落叶的博客 3648

ActiveMQ整合Spring(多消费者)

ActiveMQ整合Spring(多消费者)

ActiveMQ学习十二-顺序消费和消息分组

1 消息分组 1.1 概述 从Apache官方文档的话说,是Exclusive Consumer功能的增强。逻辑上,可以看成是一种并发的Exclusive Consumer。JMS消息属性JMXGroupID被用来区分Message Group。Message Groups特性保证所有具有相同JMSGroupID的消息会被分发到相同的Consumer(只要这个Consumer保持Active)。另一方面,Message Groups也是一种负载均衡的机制。 在一个消息被分发到Consumer前,Brok

qq_35930102的博客 1051

OpenWrt南京电信PPPoE IPv6配置:从零搭建稳定双栈网络

本文详细指导如何在南京电信PPPoE宽带环境下,为OpenWrt路由器配置稳定的IPv6双栈网络。核心在于正确设置WAN6接口为DHCPv6客户端,并请求/60前缀,同时配置LAN口分发地址并放行防火墙关键流量,确保内网设备获得原生IPv6连接。

water的专栏 1339

对E-R模型向关系模式转换的认识

一:基本E-R图的转换 1     属性处理 派生属性:直接忽略。 复合属性:展平技术。 多值属性:单独建立一个关系表,关系名就是多值属性名,如果是实体集的多值属性,关系的属性就是实体集的码加上多值属性,如果是联系集的多值属性,关系的属性就是各个实体集的码加上多值属性,关系的码要具体情况具体分析。 2     基本E-R图转换为关系模式 强实体集:一个关系,关系名就是强实体集名,关系属

优快云_LYY的专栏 2731

ActiveMQ高级特性:虚拟Destinations实现消费者分组与简单路由 .

ActiveMQ支持的虚拟Destinations分为有两种,分别是 Ø  虚拟主题(Virtual Topics) Ø  组合 Destinations(CompositeDestinations) 这两种虚拟Destinations可以看做对简单的topic和queue用法的补充,基于它们可以实现一些简单有用的EIP功能,虚拟主题类似于1对多的分支功能+消费端的cluster+fail

Jacob 2000

UE5在Ubuntu22.04.4下的高效开发环境配置指南

本文详细介绍了在Ubuntu 22.04.4系统上配置UE5高效开发环境的完整指南,包括系统准备、显卡驱动安装、UE5引擎编译与配置、开发工具链设置以及性能优化技巧。通过逐步指导,帮助开发者快速搭建稳定的UE5开发环境,解决常见问题,提升开发效率。

weixin_29251131的博客 382

ActiveMQ高级特性_02

ActiveMQ高级特性_02 本篇是我看ActiveMQ官方文档的笔记,主要涵盖以下方面: Composite Destinations;等内容。 Composite Destinations 在客户端层面,可以使用逗号分隔多个目的地: FOO.A,FOO.B,FOO.C 定义一个Queue或Topic来代表一系列destinations: Queue queue = new ActiveMQQueue("FOO.A,FOO.B,FOO.C"); producer.send(queue, someMes

村里的原振侠的博客 540

AMD 3D V-Cache技术解析:CPU缓存堆叠如何突破性能瓶颈

在半导体领域,缓存(Cache)是提升处理器性能的关键技术,其核心原理是在高速CPU核心与慢速主存之间建立数据中转站,以缓解“内存墙”问题。随着摩尔定律放缓,传统平面扩展缓存面临面积成本高、延迟增加等挑战。3D封装技术应运而生,通过垂直堆叠实现极致的互联密度与带宽,成为突破性能瓶颈的重要工程路径。这项技术的价值在于能以更优的功耗和延迟,显著提升缓存容量,从而改善游戏、科学计算等数据密集型应用的性能。以AMD 3D V-Cache为代表的Hybrid Bonding(混合键合)工艺,正是这一趋势的典型实践,它

weixin_30432579的博客 415

CISSP背书三次失败后的终极解决方案

本文分享了作者CISSP认证三次线上背书审核失败的经历与终极解决方案。针对(ISC)²官方审核的严格性,文章详细剖析了使用公积金证明、工作证明盖章签字等常见材料的误区,并最终提出了通过构建“官方邮件往来”证据链的核心策略,以动态、可验证的方式成功通过审核,为后来者提供了详实的避坑指南和实操清单。

weixin_29219539的博客 153

activemq的高级特性:集群实战

高级特性实战需求  当消费端是多个集群,集群A又包含多个服务。  当每个集群都要接受相同的一批消息,而集群内的每个服务都去分摊消息。   解决办法一:级联     增加一个中转者。但是不是特别的优化,而且性能也不是特别的好。   解决办法二:     1:虚拟主题      生产者       Destination destination = session.createTopi...

weixin_34319111的博客 112

遗传算法解整数规划IntCon

x = ga(fun,nvars,A,b,[],[],lb,ub,nonlcon,IntCon) IntCon就是代表整数的参量,描述的是哪几个自变量是0-1整数变量。比如navrs设置有4个变量,设置IntCon为[2 3],代表第2和第3个变量是整数。 再比如设置IntCon=2:2:nvars,代表偶数项的变量是整数。 值得注意的是一旦设置了非空的IntCon,则Aeqandbeqmust be an empty entry ([]), andnonlconmust re...

jianti9962的博客 9219

AMQ虚拟Destinations

转自:http://blog.csdn.net/kimmking/article/details/9773085 ActiveMQ支持的虚拟Destinations分为有两种,分别是 Ø  虚拟主题(Virtual Topics) Ø  组合 Destinations(CompositeDestinations) 这两种虚拟Destinations可以看做对简单的topic和queu

899

Rclone替代RaiDrive?零广告免费挂载Alist WebDAV到Windows资源管理器(含自启脚本)

本文详细介绍了如何使用开源工具Rclone替代RaiDrive,实现零广告、全免费的Alist WebDAV挂载方案。通过深入解析配置参数、提供完整的自启动解决方案和解决常见问题,帮助用户在Windows资源管理器中高效管理云存储,提升使用体验。

weixin_33709364的博客 631

Python 爬虫实战:手机应用商店评论数据爬取与分析

移动应用市场蓬勃发展,用户的评论数据包含了大量有价值的信息,如用户满意度、功能反馈、改进建议等。通过分析这些评论,我们可以挖掘应用的优缺点,甚至预测用户趋势。由于 Apple App Store 评论是动态加载的,我们使用。本篇博客将详细介绍如何使用 Python 爬取。爬取大量数据时,可能会遇到反爬机制。库获取 Google Play 评论。评论数据是动态加载的,需要使用。

2201_76125261的博客 2322

ActiveMQ之虚拟主题

ActiveMQ支持的虚拟Destinations分为有两种,分别是 1.虚拟主题(Virtual Topics) 2.组合 Destinations(CompositeDestinations) 这两种虚拟Destinations可以看做对简单的topic和queue用法的补充,基于它们可以实现一些简单有用的EIP功能,虚拟主题类似于1对多的分支功能+消费端的cluster+failover,组合Destinations类似于简单的destinations直接的路由功能。

任何技能都是从模仿开始,逐步升华。 3388

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

ActiveMQ学习笔记(14)----Destination高级特性(二)

1. Visual Destinations   1.1 概述   虚拟Destination用来创建逻辑Destinations,客户端可以通过它来产生和消费消息,它会把消息映射到物理Destinations。ActiveMQ支持两种方式:   1. 虚拟主题(Virtual Topics)   2. 组合Destinations (Composite Destinations...

Teddies10081008的博客 227

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

ActiveMQ 实战 - 顺序消费和消息分组

在Apache ActiveMQ中实现顺序消费和消息分组主要依赖于ActiveMQ的某些特定功能,例如Exclusive Consumer(独占消费者)以及Message Groups(消息分组)。

qq_33240556的博客 469

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

上一篇: ActiveMQ的使用
下一篇: ActiveMQ消费重试机制
架构师的清醒
博客等级 码龄14年 291粉丝 397原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值