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应用程 ... 
随机推荐
- day01_04.变量
			变量的命名规则 变量名由字母小写a-z,大写A-Z,_下划线,数字0-9组成,php的变量名区分大小写;python的变量名也是区分大小写的 注意: PHP变量名必须以美元$符号开始; 变量名开头可以 ... 
- Numpy ndarray 的高级索引存在 "bug" ?
			Numpy ndarray 高级索引 "bug" ? 话说一天,搞事情,代码如下 import numpy as np tmp = [1, 2, 3, 4] * 2 a, b = ... 
- Welcome-to-Swift-11方法(Methods)
			方法是由特定类型关联起来的函数.类.结构体和枚举都能定义成实例方法.它封装了特定的任务和给定类型的实例的功能函数.类,结构体和方法也能定义类型方法,它只与类型的本身由关联.类型方法和Objective ... 
- 【Luogu】P2053修车(费用流)
			题目链接 早上状态不好,虚树搞崩只好来刷网络流了qwq. (然后我犹豫几秒之后看了题解) 使用拆点大法把工人拆成n*m个点,然后每个点代表每个时间段的工人, 然后从车到每个工人点连一条边,权值是耽误的 ... 
- [BZOJ3261] 最大异或和 (异或前缀和,可持久化Trie)
			Description 给定一个非负整数序列{a},初始长度为N. 有M个操作,有以下两种操作类型: 1.Ax:添加操作,表示在序列末尾添加一个数x,序列的长度N+1. 2.Q l r x:询问操作, ... 
- bzoj 3190 [JLOI2013]赛车 半平面交+细节处理
			题目大意 这里有一场赛车比赛正在进行,赛场上一共有N辆车,分别称为g1,g2--gn.赛道是一条无限长的直线.最初,gi位于距离起跑线前进ki的位置.比赛开始后,车辆gi将会以vi单位每秒的恒定速度行 ... 
- 【BZOJ2243】染色(树链剖分)
			题意: 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的颜色段数量(连续相同颜色被认为是同一段),如“112221”由 ... 
- CI调试应用程序
			该分析器将在页面下方显示基准测试结果,运行过的 SQL 语句,以及 $_POST 数据.这些信息有助于开发过程中的调试和优化. 在控制器中设置以下方法以激活该分析器: $this->output ... 
- django相关字段解释(slug)
			1.slug:用于生成一个有意义(valid, meaninful)URL 参考(http://stackoverflow.com/questions/427102/what-is-a-slug-in ... 
- 微信公众号手机端PC端多客服系统
			最近很多客户反应没有专门的客服坐在电脑面前,接收回复客户的问题:不能及时回复客户 咨询的问题,现在我们已经为此帮您解决烦恼!! 支持PC与手机端接收微信客户咨询与回复客户,让您随时随地及时回复客户咨询 ... 
