apollo 消息分发源代码分析
1。MessageDispatch消息分发信息
public static final byte DATA_STRUCTURE_TYPE = CommandTypes.MESSAGE_DISPATCH;
protected ConsumerId consumerId;
protected ActiveMQDestination destination;
protected Message message;
protected int redeliveryCounter;
protected transient long deliverySequenceId;
protected transient Object consumer;
protected transient Runnable transmitCallback;
protected transient Throwable rollbackCause;
2,自己主动确认。是再接受到消息,反馈给上层应用之前就给确认
在afterMessageIsConsumed方法中
先deliveredMessages.clear();接着 session.sendAck(ack);
3,在从tcp取到消息后放到unconsumedMessages等待消费
4,在从unconsumedMessages取出消息预处理后。在beforeMessageIsConsumed方法加消息加到deliveredMessages 里面。
unconsumedMessages; 消费者从mq接受到消息存储的位置,还没有消费
5,receive内部消费之前
private void beforeMessageIsConsumed(MessageDispatch md) throws JMSException {
md.setDeliverySequenceId(session.getNextDeliveryId());
lastDeliveredSequenceId = md.getMessage().getMessageId().getBrokerSequenceId();
if (!isAutoAcknowledgeBatch()) {
synchronized(deliveredMessages) {
deliveredMessages.addFirst(md);
}
if (session.getTransacted()) {
if (transactedIndividualAck) {
immediateIndividualTransactedAck(md);
} else {
ackLater(md, MessageAck.DELIVERED_ACK_TYPE);
}
}
}
}
6,receive内部消费之后
private void afterMessageIsConsumed(MessageDispatch md, boolean messageExpired) throws JMSException {
if (unconsumedMessages.isClosed()) {
return;
}
if (messageExpired) {
acknowledge(md, MessageAck.DELIVERED_ACK_TYPE);
stats.getExpiredMessageCount().increment();
} else {
stats.onMessage();
if (session.getTransacted()) {
// Do nothing.
} else if (isAutoAcknowledgeEach()) {
if (deliveryingAcknowledgements.compareAndSet(false, true)) {
synchronized (deliveredMessages) {
if (!deliveredMessages.isEmpty()) {
if (optimizeAcknowledge) {
ackCounter++;
// AMQ-3956 evaluate both expired and normal msgs as
// otherwise consumer may get stalled
if (ackCounter + deliveredCounter >= (info.getPrefetchSize() * .65) || (optimizeAcknowledgeTimeOut > 0 && System.currentTimeMillis() >= (optimizeAckTimestamp + optimizeAcknowledgeTimeOut))) {
MessageAck ack = makeAckForAllDeliveredMessages(MessageAck.STANDARD_ACK_TYPE);
if (ack != null) {
deliveredMessages.clear();
ackCounter = 0;
session.sendAck(ack);
optimizeAckTimestamp = System.currentTimeMillis();
}
// AMQ-3956 - as further optimization send
// ack for expired msgs when there are any.
// This resets the deliveredCounter to 0 so that
// we won't sent standard acks with every msg just
// because the deliveredCounter just below
// 0.5 * prefetch as used in ackLater()
if (pendingAck != null && deliveredCounter > 0) {
session.sendAck(pendingAck);
pendingAck = null;
deliveredCounter = 0;
}
}
} else {
MessageAck ack = makeAckForAllDeliveredMessages(MessageAck.STANDARD_ACK_TYPE);
if (ack!=null) {
deliveredMessages.clear();
session.sendAck(ack);
}
}
}
}
deliveryingAcknowledgements.set(false);
}
} else if (isAutoAcknowledgeBatch()) {
ackLater(md, MessageAck.STANDARD_ACK_TYPE);
} else if (session.isClientAcknowledge()||session.isIndividualAcknowledge()) {
boolean messageUnackedByConsumer = false;
synchronized (deliveredMessages) {
messageUnackedByConsumer = deliveredMessages.contains(md);
}
if (messageUnackedByConsumer) {
ackLater(md, MessageAck.DELIVERED_ACK_TYPE);
}
}
else {
throw new IllegalStateException("Invalid session state.");
}
}
}
apollo 消息分发源代码分析的更多相关文章
- kafka消息分发策略分析
当我们使用kafka向指定Topic发送消息时,如果该Topic具有多个partition,无论消费者有多少,最终都会保证一个partition内的消息只会被一个Consumer group中的一个C ...
- Memcached源代码分析 - Memcached源代码分析之消息回应(3)
文章列表: <Memcached源代码分析 - Memcached源代码分析之基于Libevent的网络模型(1)> <Memcached源代码分析 - Memcached源代码分析 ...
- RTMPdump(libRTMP) 源代码分析 10: 处理各种消息(Message)
===================================================== RTMPdump(libRTMP) 源代码分析系列文章: RTMPdump 源代码分析 1: ...
- RTMPdump(libRTMP) 源代码分析 9: 接收消息(Message)(接收视音频数据)
===================================================== RTMPdump(libRTMP) 源代码分析系列文章: RTMPdump 源代码分析 1: ...
- RTMPdump(libRTMP) 源代码分析 8: 发送消息(Message)
===================================================== RTMPdump(libRTMP) 源代码分析系列文章: RTMPdump 源代码分析 1: ...
- Hadoop源代码分析
http://wenku.baidu.com/link?url=R-QoZXhc918qoO0BX6eXI9_uPU75whF62vFFUBIR-7c5XAYUVxDRX5Rs6QZR9hrBnUdM ...
- Android应用程序进程启动过程的源代码分析
文章转载至CSDN社区罗升阳的安卓之旅,原文地址: http://blog.csdn.net/luoshengyang/article/details/6747696 Android 应用程序框架层创 ...
- Android应用程序绑定服务(bindService)的过程源代码分析
文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/6745181 Android应用程序组件Serv ...
- Android应用程序启动过程源代码分析
文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/6689748 前文简要介绍了Android应用程 ...
随机推荐
- 01-python进阶-拾遗
列表复习append(x)追交到链尾extend(L)追加一个列表 等价于 +=insert(i,x)在位置i处插入xremove(x) 删除一个值为x的元素 如果没有抛出异常sort() 直接修改列 ...
- Uiautomator学习笔记(2) 封装代码 报错误(NllPointerException)
.NullPointerException: Attempt to invoke virtual method 'boolean qq.test.UiautomatorAssistant.ClickB ...
- 九度oj 题目1392:排序生成最小的数
题目描述: 还记得陈博是个数字完美主义者么?^_^....这次,他又闹脾气了!我们知道计算机中常常要使用数组保存一组数字,但是今天他就要求把数组里的所有数字组成一个,并且这个数字是这些数字所能组成的所 ...
- 通过FEDERATED存储引擎同步两实例间的表数据
需求情景:实例1中A库中的三个视图是实例2中的B库所依赖的,B需要A库中三个视图的实时数据. 方案:通过FEDERATED来完成跨势力的查询FEDERATED存储引擎表只会创建表结构,不会存储表数据, ...
- js版本下拉菜单
<!doctype html> <html> <head> <meta charset="utf-8"> <title> ...
- Welcome-to-Swift-01基础部分
Swift 是 iOS 和 OS X 应用开发的一门新语言.然而,如果你有 C 或者 Objective-C 开发经验的话,你会发现 Swift 的很多内容都是你熟悉的. Swift 的类型是在 C ...
- 【bzoj2467】[中山市选2010]生成树 矩阵树定理
题目描述 有一种图形叫做五角形圈.一个五角形圈的中心有1个由n个顶点和n条边组成的圈.在中心的这个n边圈的每一条边同时也是某一个五角形的一条边,一共有n个不同的五角形.这些五角形只在五角形圈的中心的圈 ...
- setsockopt等高级使用
参考: setsockopt函数使用http://hi.baidu.com/yelangdefendou/item/74161d0f384abd3c4ac4a316http://blog.csdn.n ...
- 在vue路由当中使用keep-alive避免多次加载组件,减少消耗
今天在vue当中使用了full-page这个组件.但是发现在每次路由跳转完之后,再回到使用fullpage的这个页面,fullpage会报错,fullpage只能初始化一次. 这个时候给路由使用kee ...
- 挑战程序设计2 KD树
Range Query - Range Search (kD Tree) Time Limit : 1 sec, Memory Limit : 262144 KB Japanese version i ...