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. 树莓派 无屏幕 安装Ubuntu系统 无头安装 无显示器 用网线

    能看到此篇博客的人说明都尝试失败了,会发现内存卡刷入Ubuntu后,无法通过ssh操作树莓派.是因为官方的ubuntu系统在初次运行时需要设定一些东西,类似windows第一次启动也需要设置那样,如果 ...

  2. _event_worldstate

    EventId 事件ID ID WorldStateUI.dbc第10列数字部分 StartValue 起始值 Entry 更新世界状态需要击杀生物或摧毁物体的entry,正数为生物,负数为物体 St ...

  3. 关于UTC时间和本地时间

    收藏了个类Publics  可以实现本地时间和UTC时间的转换 UCT时间=本地时间-8    本地时间比UTC时间快8小时 element-ui的日期选择器上  选择的时间显示的是本地时间   但实 ...

  4. EditText取消焦点

    EditText取消焦点: 在父容器添加: android:focusable="true" android:focusableInTouchMode="true&quo ...

  5. 《HTTP 权威指南》笔记:第十三章 摘要认证体制

    前言 基本认证存在缺陷,摘要认证为了解决基本认知的一些缺陷,进行了进一步的完善,更加安全. 流程 摘要认证的特点是:永远不会以明文方式在网络上发送密码原理:通过发送一个「指纹」或者「密码的摘要」来验证 ...

  6. jquey 小记

    1. $.each(array, [callback]) 遍历[常用] 解释: 不同于例遍jQuery对象的$().each()方法,此方法可用于例遍任何对象. 回调函数拥有两个参数: 第一个为对象的 ...

  7. 雷林鹏分享:jQuery EasyUI 扩展

    jQuery EasyUI 扩展 Portal(制作图表.列表.球形图等) 数据网格视图(DataGrid View) 可编辑的数据网格(Editable DataGrid) 可编辑的树(Editab ...

  8. OnSen UI结合AngularJs打造”美团"APP"订单”页面 --Hybrid App

    1.页面效果图: 演示链接地址:http://www.nxl123.cn/bokeyuan/meiTuanDemo_order/ 2.核心代码 order.html: <ons-page id= ...

  9. c# HTML中提取图片地址

    public class HtmlHelper    {        /// <summary>        /// HTML中提取图片地址        /// </summa ...

  10. ionic更换加载页面和logo

    将你准备要更替的加载页面的图片和logo图片分别重名名为splash.png和icon.png 将这两个图片文件放到项目中的resources目录下,覆盖原有的这两个文件 在cmd或终端进入项目 分别 ...