ActiveMQ中Consumer特性详解与优化

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

ActiveMQ中Consumer特性详解与优化

前⾔

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

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

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

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

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

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

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

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

Java代码

1. String brokerUrl = "tcp://localhost:61616?"

2. String queueName = "test-queue";

3. ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory(brokerUrl);

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

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

6. Destination queue = session.createQueue(queueName);

7. MessageConsumer consumer = session.createConsumer(queue);

8. consumer.setMessageListener(new MessageListener() {

9. @Override

10. public void onMessage(Message message) {

11. try{

12. ActiveMQMessage m = (ActiveMQMessage)message;

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

14. }catch(Exception e){

15. //

16. e.printStackTrace();

17. }

18. }

19. });

20. connection.start();

21.

22. //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和线程池),并启动线程池负责发送消息,那么转发线程即可⽴即返回。

相关文档
最新文档