ActiveMQ异步分发消息
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异步分发消息的更多相关文章
- ActiveMQ producer同步/异步发送消息
http://activemq.apache.org/async-sends.html producer发送消息有同步和异步两种模式,可以通过代码配置: ((ActiveMQConnection)co ...
- 【原创】JMS生产者和消费者【PTP异步接收消息】
PTP模式下,异步接收消息需要定义一个MessageListener来监听,当生产者有消息要发送时会主动通知Listener去处理该消息,会调用监听的onMessage方法去处理. 首先看生产者(和同 ...
- 实战Spring4+ActiveMQ整合实现消息队列(生产者+消费者)
引言: 最近公司做了一个以信息安全为主的项目,其中有一个业务需求就是,项目定时监控操作用户的行为,对于一些违规操作严重的行为,以发送邮件(ForMail)的形式进行邮件告警,可能是多人,也可能是一个人 ...
- php 利用activeMq+stomp实现消息队列
php 利用activeMq+stomp实现消息队列 一.activeMq概述 ActiveMQ 是Apache出品,最流行的,能力强劲的开源消息总线.ActiveMQ 是一个完全支持JMS1.1和J ...
- 【ActiveMQ】持久化消息队列的三种方式
1.ActiveMQ消息持久化方式,分别是:文件.mysql数据库.oracle数据库 2.修改方式: a.文件持久化: ActiveMQ默认的消息保存方式,一般如果没有修改过其他持久化方式的话可以不 ...
- kafka7 探索生产者同步or异步发送消息
1.生产者:在发送完消息后,收到回执确认. 主要是在SimpleProducer.java中修改了发送消息的2行代码,用到了回调函数,修改如下: //发送消息 ProducerRecord<St ...
- php 事务处理,ActiveMQ的发送消息,与处理消息
可以通过链式发送->处理->发送...的方式处理类似事务型业务逻辑 比如 发送一个注册消息,消息队列处理完注册以后,紧接着发送一个新手优惠券赠送,赠送完再发一个其它后续逻辑处理的消息等待后 ...
- Yarn源码分析之事件异步分发器AsyncDispatcher
AsyncDispatcher是Yarn中事件异步分发器,它是ResourceManager中的一个基于阻塞队列的分发或者调度事件的组件,其在一个特定的单线程中分派事件,交给AsyncDispatch ...
- ActiveMQ发布-订阅消息模式(同点对点模式的区别)
点对点与发布订阅最初是由JMS定义的.这两种模式主要区别或解决的问题就是发送到队列的消息能否重复消费(多订阅) 点对点: 消息生产者生产消息发送到queue中,然后消息消费者从queue中取出并且消费 ...
随机推荐
- mysql联合主键自增、主键最大长度小记
前言 一. 联合主键自增问题 今天上午闲来无事翻看了下数据库分类表的设计,看到这样一幕: 当时我好奇的是怎么cateId自增会存在重复值的问题,然后翻看了下主键是由siteId和cateId组成.所以 ...
- CSS垂直居中查询宝典
一.垂直居中的用处 设计稿需求 当我们抱怨设计反复不定的时候,试着理解一下.每一位开发者也会是一位用户,请多多用'用户'的角色去开发.就比如下面这图,你会更稀饭哪种格式呢? 如果我们使用一个webap ...
- JaveWeb 公司项目(4)----- Easyui的表单验证
前面三篇博文讲述的是界面的搭建和数据的传输,可以看出目前我做的这个小项目已经有了一个大体的雏形,剩下的就是细节部分的打磨和一些友好的人机交互设计,今天做的是表单的验证,作为初学者,着实花了一番功夫,所 ...
- linq to sql and linq to object 总结
Enumable类型是linq to object 是一个很特殊的类型 这个类型的数据源都是在程序的内存中 Queryable类型是 Linq to sql 对数据库进行操作都是这个类型 ...
- 人脸识别最新开发经验demo分享
本来打算做个C#版demo,但没用成功,基于虹软的免费人脸识别技术 过程如下: 1. 传入一张单人脸照片: 2.调用检测人脸函数ASFDetectFaces,成功返回人脸信息的指针: 3.使用 Mar ...
- 学习笔记27—python中numpy.ravel() 和 flatten()函数
简介 首先声明两者所要实现的功能是一致的(将多维数组降位一维).这点从两个单词的意也可以看出来,ravel(散开,解开),flatten(变平).两者的区别在于返回拷贝(copy)还是返回视图(vie ...
- EOJ Monthly 2018.11 D. 猜价格
猜价格 分两种情况讨论: k≤n,先猜至多 k 次 1,由于回答 <1 肯定是假的,所以可以把剩余系下是哪次错试出来,然后用至多 n 次搞定. k>n,每个数都猜两次,如果两次结果不一样, ...
- Python 列表复制
Python 列表复制 关于Python 列表的复制,有多种方法,常用的 有 赋值.切片.list.copy,copy.deepcopy等. 但是 实际用时 又有区别,不小心可能就用错了. 接下来 简 ...
- Asp.net core 学习笔记 ( upload/download files 文件上传与下载 )
更新 : 2018-01-22 之前漏掉了一个 image 优化, 就是 progressive jpg refer : http://techslides.com/demos/progressi ...
- Nginx的安装和使用(Linux)
关于什么是Nginx,Nginx的优势和使用范围这里就不多说了.其实它就是一个web服务器.这篇文章主要是说Nginx的安装和使用. 安装方式有yum安装和源码安装,这里主要讲源码安装 1.安装依赖, ...