org.apache.activemq.ActiveMQConnection 类中有个参数:

protected boolean dispatchAsync=true;

这个参数的含义到底是什么?

使用这个参数的调用栈如下:

org.apache.activemq.broker.region.PrefetchSubscription.dispatch

protected boolean dispatch(final MessageReference node) throws IOException {
final Message message = node.getMessage();
if (message == null) {
return false;
} okForAckAsDispatchDone.countDown(); // No reentrant lock - Patch needed to IndirectMessageReference on method lock
MessageDispatch md = createMessageDispatch(node, message);
// NULL messages don't count... they don't get Acked.
if (node != QueueMessageReference.NULL_MESSAGE) {
dispatchCounter++;
dispatched.add(node);
} else {
while (true) {
int currentExtension = prefetchExtension.get();
int newExtension = Math.max(0, currentExtension - 1);
if (prefetchExtension.compareAndSet(currentExtension, newExtension)) {
break;
}
}
}
if (info.isDispatchAsync()) {
md.setTransmitCallback(new TransmitCallback() { @Override
public void onSuccess() {
// Since the message gets queued up in async dispatch, we don't want to
// decrease the reference count until it gets put on the wire.
onDispatch(node, message);
} @Override
public void onFailure() {
Destination nodeDest = (Destination) node.getRegionDestination();
if (nodeDest != null) {
if (node != QueueMessageReference.NULL_MESSAGE) {
nodeDest.getDestinationStatistics().getDispatched().increment();
nodeDest.getDestinationStatistics().getInflight().increment();
LOG.trace("{} failed to dispatch: {} - {}, dispatched: {}, inflight: {}", new Object[]{ info.getConsumerId(), message.getMessageId(), message.getDestination(), dispatchCounter, dispatched.size() });
}
}
}
});
context.getConnection().dispatchAsync(md);
} else {
context.getConnection().dispatchSync(md);
onDispatch(node, message);
}
return true;
}

异步和同步分别对应 TransportConnection 类的2个方法:dispatchAsync,dispatchSync

先分析同步代码:

public void dispatchSync(Command message) {
try {
processDispatch(message);
} catch (IOException e) {
serviceExceptionAsync(e);
}
}

很干脆,直接调用 processDispatch 方法。

再分析异步发送:

public void dispatchAsync(Command message) {
if (!stopping.get()) {
if (taskRunner == null) {
dispatchSync(message);
} else {
synchronized (dispatchQueue) {
dispatchQueue.add(message);
}
try {
taskRunner.wakeup();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
} else {
if (message.isMessageDispatch()) {
MessageDispatch md = (MessageDispatch) message;
TransmitCallback sub = md.getTransmitCallback();
broker.postProcessDispatch(md);
if (sub != null) {
sub.onFailure();
}
}
}
}

先把消息加入到dispatchQueue中,然后唤醒taskRunner。

taskRunner线程的调用栈如下:

public boolean iterate() {
try {
if (pendingStop || stopping.get()) {
if (dispatchStopped.compareAndSet(false, true)) {
if (transportException.get() == null) {
try {
dispatch(new ShutdownInfo());
} catch (Throwable ignore) {
}
}
dispatchStoppedLatch.countDown();
}
return false;
}
if (!dispatchStopped.get()) {
Command command = null;
synchronized (dispatchQueue) {
if (dispatchQueue.isEmpty()) {
return false;
}
command = dispatchQueue.remove(0);
}
processDispatch(command);
return true;
}
return false;
} catch (IOException e) {
if (dispatchStopped.compareAndSet(false, true)) {
dispatchStoppedLatch.countDown();
}
serviceExceptionAsync(e);
return false;
}
}

最终调用的也是 processDispatch 方法。

ActiveMQ异步分发消息的更多相关文章

  1. ActiveMQ producer同步/异步发送消息

    http://activemq.apache.org/async-sends.html producer发送消息有同步和异步两种模式,可以通过代码配置: ((ActiveMQConnection)co ...

  2. 【原创】JMS生产者和消费者【PTP异步接收消息】

    PTP模式下,异步接收消息需要定义一个MessageListener来监听,当生产者有消息要发送时会主动通知Listener去处理该消息,会调用监听的onMessage方法去处理. 首先看生产者(和同 ...

  3. 实战Spring4+ActiveMQ整合实现消息队列(生产者+消费者)

    引言: 最近公司做了一个以信息安全为主的项目,其中有一个业务需求就是,项目定时监控操作用户的行为,对于一些违规操作严重的行为,以发送邮件(ForMail)的形式进行邮件告警,可能是多人,也可能是一个人 ...

  4. php 利用activeMq+stomp实现消息队列

    php 利用activeMq+stomp实现消息队列 一.activeMq概述 ActiveMQ 是Apache出品,最流行的,能力强劲的开源消息总线.ActiveMQ 是一个完全支持JMS1.1和J ...

  5. 【ActiveMQ】持久化消息队列的三种方式

    1.ActiveMQ消息持久化方式,分别是:文件.mysql数据库.oracle数据库 2.修改方式: a.文件持久化: ActiveMQ默认的消息保存方式,一般如果没有修改过其他持久化方式的话可以不 ...

  6. kafka7 探索生产者同步or异步发送消息

    1.生产者:在发送完消息后,收到回执确认. 主要是在SimpleProducer.java中修改了发送消息的2行代码,用到了回调函数,修改如下: //发送消息 ProducerRecord<St ...

  7. php 事务处理,ActiveMQ的发送消息,与处理消息

    可以通过链式发送->处理->发送...的方式处理类似事务型业务逻辑 比如 发送一个注册消息,消息队列处理完注册以后,紧接着发送一个新手优惠券赠送,赠送完再发一个其它后续逻辑处理的消息等待后 ...

  8. Yarn源码分析之事件异步分发器AsyncDispatcher

    AsyncDispatcher是Yarn中事件异步分发器,它是ResourceManager中的一个基于阻塞队列的分发或者调度事件的组件,其在一个特定的单线程中分派事件,交给AsyncDispatch ...

  9. ActiveMQ发布-订阅消息模式(同点对点模式的区别)

    点对点与发布订阅最初是由JMS定义的.这两种模式主要区别或解决的问题就是发送到队列的消息能否重复消费(多订阅) 点对点: 消息生产者生产消息发送到queue中,然后消息消费者从queue中取出并且消费 ...

随机推荐

  1. go 一波走起

    $ go run helloworld.go 运行 $ go build helloworld.go 编译 该命令生成一个名为helloworld的可执行的二进制文件,可以随时运行它 $ ./hell ...

  2. gulp的使用介绍及技巧

    gulp的使用介绍及技巧 转载: https://www.cnblogs.com/2050/p/4198792.html 1.gulp的安装 首先确保你已经正确安装了nodejs环境.然后以全局方式安 ...

  3. hdu 3836 Equivalent Sets trajan缩点

    Equivalent Sets Time Limit: 12000/4000 MS (Java/Others)    Memory Limit: 104857/104857 K (Java/Other ...

  4. Could not find com.android.tools.build:aapt2:3.2.1-4818971.

    Could not find com.android.tools.build:aapt2:-. Searched in the following locations: file:/H:/Androi ...

  5. Qt网络应用开发初步

      应用层的网络协议,如HTTP/FTP/SMTP等简称"应用协议",他们运行在TCP/UDP之上,从Qt5开始,已经不再分别提供QHttp类,QFtp类,应用层的编程使用QNet ...

  6. centos如何查看linux内核,版本号

    [root@localhost ~]# uname -a Linux localhost.localdomain -.el7.x86_64 # SMP Thu Nov :: UTC x86_64 x8 ...

  7. (转)c#反射

    1. 什么是反射2. 命名空间与装配件的关系3. 运行期得到类型信息有什么用4. 如何使用反射获取类型5. 如何根据类型来动态创建对象6. 如何获取方法以及动态调用方法7. 动态创建委托 1.什么是反 ...

  8. PC端、移动端的页面适配及兼容处理

    转自 一.关于移动端兼容性 目前针对跨终端的方案,主要分为两大阵营:一套资源Vs两套资源. 第一种是通过响应式或页面终端判断去实现一套资源适配所有终端: 第二种是通过终端判断分别调取两套资源以适配所有 ...

  9. p1460 Healthy Holsteins

    列举所有的子集找最优就行. #include <iostream> #include <cstdio> #include <cmath> #include < ...

  10. python3—列表

    列表是什么 name = ["jim", "lilei", "lucy"] #方括号表示,逗号分隔 print(name) print(na ...