activemq控制发送频率_ActiveMQ中Consumer特性详解与优化

前言从本文中你可以了解到如下内容:1) consumer端消息消费的模型,session的运作机制2) 如果提升broker和consumer端消息消费的速率3) selector,group,exclusive对消息消费的影响4) 如何让Priority更好的运行,提高消息的顺序性5) Slow Consumer的产生原因,以及如何调优。Consumer作为ActiveMQ的消费端,开起来简单,...
摘要由CSDN通过智能技术生成

前言

从本文中你可以了解到如下内容:

1) consumer端消息消费的模型,session的运作机制

2) 如果提升broker和consumer端消息消费的速率

3) selector,group,exclusive对消息消费的影响

4) 如何让Priority更好的运行,提高消息的顺序性

5) Slow Consumer的产生原因,以及如何调优。

Consumer作为ActiveMQ的消费端,开起来简单,不过还有很多隐藏的特性,值得我们去探索和调优。

如下为典型的Consumer端代码示例

Java代码 String brokerUrl = "tcp://localhost:61616?"

String queueName = "test-queue";

ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory(brokerUrl);

ActiveMQConnection connection = (ActiveMQConnection)factory.createConnection();

final Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);

Destination queue = session.createQueue(queueName);

MessageConsumer consumer = session.createConsumer(queue);

consumer.setMessageListener(new MessageListener() {

@Override

public void onMessage(Message message) {

try{

ActiveMQMessage m = (ActiveMQMessage)message;

System.out.println(m.toString());

}catch(Exception e){

//

e.printStackTrace();

}

}

});

connection.start();

//connection.close();

Consumer端涉及到众多的特性,其中包括:消息转发机制,session机制与多线程,消息ACK策略等,我们无法详解所有的原理,如下为Consumer端消息转发机制,仅供参考,[详细请参考]:

上图非常复杂,具体的原理,我们将会在下文中逐个解释。大概原理与过程:

通过Connection实例创建Session之后,将会把session实例保存在本地的list中,即connection持有session列表,并在底层开启transport,侦听数据。

Session创建Consumer之后,将会把Consumer实例添加到本地的list中,以便此后分拣消息,即session持有consumer列表;此外connection中也持有一个consumer集合(Map),其中Key为consumerId,value为session引用。

如果Session支持异步转发(asyncDispatch)或者使用了转发池(dispatchPool),将创建线程池用来转发消息。

当broker端有消息通过transport发送时,connection将会分拣消息,根据消息中指定的consumerId,从本地session列表中获取其对应的session实例;然后将消息交付session负责转发。

当session接受到消息后,会根据消息的consumerId,在本地consumer列表中找到对应的consumer实例;检测session的消息转发方式,如果是同步转发,则直接将消息交给consumer,即调用consumer.dispatch(message),此方法要么调用messageListener.onMessage(),要么将消息添加到本地的unconsumedMessages队列中(唤醒receive);如果是异步转发,则将消息添加到session级别的队列中并由线程池负责转发。

当consumer接受到消息之后,将会调用messageListener.onMessage方法或者从receive方法中返回。

当消息消费成功后,consumer将会根据指定的ACK_MODE负责向broker发送ACK指令,此后消息将会在broker端清除。

1. asyncDispatch

broker端是否允许使用“异步转发”。broker端处理connection、session、consumer的模型和Client端几乎一样;当通道中(Queue/Topic)有消息需要转发给consumer时,将会调用相应的Subscription的dispatch方法(在broker端负责与Consumer通讯的服务,称为Subscription,每个Consumer客户端对应broker端一个Subscription实例);如果asyncDispatch为false,那么将会阻塞转发线程(dispatchThread),直到底层的Transport将消息发送到Consumer客户端(如果底层transport正在发送消息,意味着阻塞);如果为true,则会将消息添加到transport本地的队列中(负责与Consumer客户端通信的每个transport都有一个本地的queue和线程池),并启动线程池负责发送消息,那么转发线程即可立即返回。

(参见代码:QueueStoreCursor/TopicStoreCursor --> broker端Queue/Topic(核心类)--->QueuePrefetchSubscription,QueueRegion,AbstractRegion,RoundRobinDispatchPolicy/StrictOrderDispatchPolicy)

由此可见,当前通道中所有的consumer都在brorker端开启了“异步转发”,可以大大提升broker转发消息的性能,此值默认为true。

Java代码 //在brokerUrl中设置

tcp://localhost:61616?jms.dispatchAsync=true

//在destinationUri中为当前通道设定

orderQueue?consumer.dispatchAsync=true

broker“异步转发”采用的是线程池模式,线程池的缺点即使当任务单元运行时间足够短时,线程切换的成本将变得很重要,这也意味着

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值