RocketMQ——顺序消费(代码)

关于rocketmq顺序消费的理解和图示可以查看该博文:RocketMQ——顺序消费和重复消费

本博客主要是以代码示例来了解顺序消费的相关内容,建议在此之前先了解下顺序消费的原理。

注:RocketMQ可以严格的保证消息有序,但这个顺序,不是全局顺序,只是分区(queue)顺序,如果想要全局顺序,那么需要保证只有一个分区。

顺序消费简介

1.普通顺序消费

顺序消费的一种,正常情况下可以保证完全的顺序消息,但是一旦发生通信异常,Broker重启,由于队列总数法还是能变化,哈希取模后定位的队列会变化,产生短暂的消息顺序不一致。

2.严格顺序消息

顺序消息的一种,无论正常异常情况都能保证顺序,但是牺牲了分布式failover特性,即broker集群中要有一台机器不可用,则整个集群都不可用,服务可用性大大降低。如果服务器部署为同步双写模式,此缺陷可通过备机自动切换为主避免,不过仍然会存在几分钟的服务不可用。

目前已知的应用只有数据库binlog同步强依赖严格顺序消息,其他应用绝大部分都可以容忍短暂乱序,推荐使用普通的顺序消息。

1.producer

package com.gwd.rocketmq;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import com.alibaba.rocketmq.client.exception.MQBrokerException;
import com.alibaba.rocketmq.client.exception.MQClientException;
import com.alibaba.rocketmq.client.producer.DefaultMQProducer;
import com.alibaba.rocketmq.client.producer.MessageQueueSelector;
import com.alibaba.rocketmq.client.producer.SendResult;
import com.alibaba.rocketmq.common.message.Message;
import com.alibaba.rocketmq.common.message.MessageQueue;
import com.alibaba.rocketmq.remoting.exception.RemotingException;

/** 
* @FileName Producer.java
* @Description:
* @author gu.weidong
* @version V1.0
* @createtime 2018年7月3日 上午9:59:38 
* 修改历史:
* 时间           作者          版本        描述
*====================================================  
*
*/
/**
 * Producer,发送顺序消息
 */
public class Producer {
	
    public static void main(String[] args) throws IOException {
        try {
            DefaultMQProducer producer = new DefaultMQProducer("sequence_producer");
 
            producer.setNamesrvAddr("192.168.159.128:9876;192.168.159.129:9876");
 
            producer.start();
 
            String[] tags = new String[] { "TagA", "TagC", "TagD" };
            
            // 订单列表
            List<OrderDO> orderList =  new Producer().buildOrders();
            
            Date date = new Date();
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String dateStr = sdf.format(date);
            for (int i = 0; i < 10; i++) {
                // 加个时间后缀
                String body = dateStr + " Hello RocketMQ " + orderList.get(i).getOrderId()+orderList.get(i).getDesc();
                Message msg = new Message("SequenceTopicTest", tags[i % tags.length], "KEY" + i, body.getBytes());
 
                SendResult sendResult = producer.send(msg, new MessageQueueSelector() {
                    @Override
                    public MessageQueue select(List<MessageQueue> mqs, Message msg, Object arg) {
                        Long id = Long.valueOf((String)arg);
                        long index = id % mqs.size();
                        return mqs.get((int)index);
                    }
                }, orderList.get(i).getOrderId());//通过订单id来获取对应的messagequeue
 
                System.out.println(sendResult + ", body:" + body);
            }
            
            producer.shutdown();
 
        } catch (MQClientException e) {
            e.printStackTrace();
        } catch (RemotingException e) {
            e.printStackTrace();
        } catch (MQBrokerException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.in.read();
    }
    
    /**
     * 生成模拟订单数据 
     */
    private List<OrderDO> buildOrders() {
    	List<OrderDO> orderList = new ArrayList<OrderDO>();
 
    	OrderDO OrderDO = new OrderDO();
        OrderDO.setOrderId("15103111039");
    	OrderDO.setDesc("创建");
    	orderList.add(OrderDO);
    	
    	OrderDO = new OrderDO();
    	OrderDO.setOrderId("15103111065");
    	OrderDO.setDesc("创建");
    	orderList.add(OrderDO);
    	
    	OrderDO = new OrderDO();
    	OrderDO.setOrderId("15103111039");
    	OrderDO.setDesc("付款");
    	orderList.add(OrderDO);
    	
    	OrderDO = new OrderDO();
    	OrderDO.setOrderId("15103117235");
    	OrderDO.setDesc("创建");
    	orderList.add(OrderDO);
    	
    	OrderDO = new OrderDO();
    	OrderDO.setOrderId("15103111065");
    	OrderDO.setDesc("付款");
    	orderList.add(OrderDO);
    	
    	OrderDO = new OrderDO();
    	OrderDO.setOrderId("15103117235");
    	OrderDO.setDesc("付款");
    	orderList.add(OrderDO);
    	
    	OrderDO = new OrderDO();
    	OrderDO.setOrderId("15103111065");
    	OrderDO.setDesc("完成");
    	orderList.add(OrderDO);
    	
    	OrderDO = new OrderDO();
    	OrderDO.setOrderId("15103111039");
    	OrderDO.setDesc("推送");
    	orderList.add(OrderDO);
    	
    	OrderDO = new OrderDO();
    	OrderDO.setOrderId("15103117235");
    	OrderDO.setDesc("完成");
    	orderList.add(OrderDO);
    	
    	OrderDO = new OrderDO();
    	OrderDO.setOrderId("15103111039");
    	OrderDO.setDesc("完成");
    	orderList.add(OrderDO);
    	return orderList;
    }
}
此处需要注意,producer.send(msg, new MessageQueueSelector()),如果需要全局有序,只需要使new MessageQueueSelector().select(List<MessageQueue> mqs, Message msg, Object arg)方法返回值唯一且不变,例如:
SendResult sendResult = producer.send(msg, new MessageQueueSelector() {
                    @Override
                    public MessageQueue select(List<MessageQueue> mqs, Message msg, Object arg) {
                        Long id = Long.valueOf((String)arg);
                        long index = id % mqs.size();
                        return mqs.get((int)index);
                    }
                }, orderList.get(0).getOrderId());//通过订单id来获取对应的messagequeue

这边获取到的queue永远都是唯一的且确定的(此处只是举个简单的例子,orderList.get(i).getOrderId()改为0亦可)

2.错误的Consumer

package com.gwd.rocketmq;

import java.util.List;
import java.util.Random;
import java.util.concurrent.TimeUnit;

import com.alibaba.rocketmq.client.consumer.DefaultMQPushConsumer;
import com.alibaba.rocketmq.client.consumer.listener.ConsumeConcurrentlyContext;
import com.alibaba.rocketmq.client.consumer.listener.ConsumeConcurrentlyStatus;
import com.alibaba.rocketmq.client.consumer.listener.MessageListenerConcurrently;
import com.alibaba.rocketmq.client.exception.MQClientException;
import com.alibaba.rocketmq.common.consumer.ConsumeFromWhere;
import com.alibaba.rocketmq.common.message.MessageExt;

/** 
* @FileName WrongConsumer.java
* @Description:
* @author gu.weidong
* @version V1.0
* @createtime 2018年7月3日 下午3:13:16 
* 修改历史:
* 时间           作者          版本        描述
*====================================================  
*
*/
public class WrongConsumer {
	public static void main(String[] args) throws MQClientException {
        DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("please_rename_unique_group_name_3");
        consumer.setNamesrvAddr("192.168.159.128:9876;192.168.159.129:9876");
        /**
         * 设置Consumer第一次启动是从队列头部开始消费还是队列尾部开始消费<br>
         * 如果非第一次启动,那么按照上次消费的位置继续消费
         */
        consumer.setConsumeFromWhere(ConsumeFromWhere.CONSUME_FROM_FIRST_OFFSET);
 
        consumer.subscribe("SequenceTopicTest", "TagA || TagC || TagD");
 
        consumer.registerMessageListener(new MessageListenerConcurrently() {
 
            Random random = new Random();
 
            @Override
            public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs, ConsumeConcurrentlyContext context) {
                System.out.print(Thread.currentThread().getName() + " Receive New Messages: " );
                for (MessageExt msg: msgs) {
                    System.out.println(msg + ", content:" + new String(msg.getBody()));
                }
                try {
                    //模拟业务逻辑处理中...
                    TimeUnit.SECONDS.sleep(random.nextInt(10));
                } catch (Exception e) {
                    e.printStackTrace();
                }
                return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
            }
        });
 
        consumer.start();
 
        System.out.println("Consumer Started.");
    }
}

注意:要想要有顺序,那么这边吃监听器就不能是MessageListenerConcurrently了,其显示效果如下:



3.正确的Consumer

package com.gwd.rocketmq;

import java.util.List;
import java.util.Random;
import java.util.concurrent.TimeUnit;

import com.alibaba.rocketmq.client.consumer.DefaultMQPushConsumer;
import com.alibaba.rocketmq.client.consumer.listener.ConsumeOrderlyContext;
import com.alibaba.rocketmq.client.consumer.listener.ConsumeOrderlyStatus;
import com.alibaba.rocketmq.client.consumer.listener.MessageListenerOrderly;
import com.alibaba.rocketmq.client.exception.MQClientException;
import com.alibaba.rocketmq.common.consumer.ConsumeFromWhere;
import com.alibaba.rocketmq.common.message.MessageExt;

/** 
* @FileName Consumer.java
* @Description:
* @author gu.weidong
* @version V1.0
* @createtime 2018年7月3日 上午10:05:26 
* 修改历史:
* 时间           作者          版本        描述
*====================================================  
*
*/
/**
 * 顺序消息消费,带事务方式(应用可控制Offset什么时候提交)
 */
public class Consumer {
 
    public static void main(String[] args) throws MQClientException {
        DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("please_rename_unique_group_name_3");
        consumer.setNamesrvAddr("192.168.159.128:9876;192.168.159.129:9876");
        /**
         * 设置Consumer第一次启动是从队列头部开始消费还是队列尾部开始消费<br>
         * 如果非第一次启动,那么按照上次消费的位置继续消费
         */
        consumer.setConsumeFromWhere(ConsumeFromWhere.CONSUME_FROM_FIRST_OFFSET);
 
        consumer.subscribe("SequenceTopicTest", "TagA || TagC || TagD");
 
        consumer.registerMessageListener(new MessageListenerOrderly() {
 
            Random random = new Random();
 
            @Override
            public ConsumeOrderlyStatus consumeMessage(List<MessageExt> msgs, ConsumeOrderlyContext context) {
                context.setAutoCommit(true);
                System.out.print(Thread.currentThread().getName() + " Receive New Messages: " );
                for (MessageExt msg: msgs) {
                    System.out.println(msg + ", content:" + new String(msg.getBody()));
                }
                try {
                    //模拟业务逻辑处理中...
                    TimeUnit.SECONDS.sleep(random.nextInt(10));
                } catch (Exception e) {
                    e.printStackTrace();
                }
                return ConsumeOrderlyStatus.SUCCESS;
            }
        });
 
        consumer.start();
        System.out.println("Consumer Started.");
    }
}

这边的Consumer和上面的最明显的区别在于对应的监听器是MessageListenerOrderlyMessageListenerOrderly是能够保证顺序消费的。

显示结果:


4.多个消费者

那如果有多个消费者呢?因为消息发送时被分配到多个队列,这些队列又会被分别发送给消费者唯一消费,现在启动两个消费者,其消费情况如下图:



结论:多个消费者时,各个消费者的消息依旧是顺序消费,且不会重复消费


原文转自:https://blog.csdn.net/earthhour/article/details/78323026 ,在此基础上部分代码略作修改

<p style="font-size:14px;color:#333333;"> <span style="color:#000000;">RocketMQ </span><span style="color:#000000;">是阿里巴巴在</span><span style="color:#000000;">2012</span><span style="color:#000000;">年开源的分布式消息中间件,目前已经捐赠给</span><span style="color:#000000;"> Apache </span><span style="color:#000000;">软件基金会,并于</span><span style="color:#000000;">2017</span><span style="color:#000000;">年</span><span style="color:#000000;">9</span><span style="color:#000000;">月</span><span style="color:#000000;">25</span><span style="color:#000000;">日成为</span><span style="color:#000000;">Apache </span><span style="color:#000000;">的顶级项目。作为经历过多次阿里巴巴双十一这种</span><span style="color:#000000;">“</span><span style="color:#000000;">超级工程</span><span style="color:#000000;">”</span><span style="color:#000000;">的洗礼并有稳定出色表现的国产中间件,以其高性能、低延时和高可靠等特性近年来已经也被越来越多的国内企业使用。其主要功能有</span><span style="color:#000000;">1.</span><span style="color:#000000;">灵活可扩展性、</span><span style="color:#000000;">2.</span><span style="color:#000000;">海量消息堆积能力、</span><span style="color:#000000;">3.</span><span style="color:#000000;">支持顺序消息、</span><span style="color:#000000;">4.</span><span style="color:#000000;">多种消息过滤方式、</span><span style="color:#000000;">5.</span><span style="color:#000000;">支持事务消息、</span><span style="color:#000000;">6.</span><span style="color:#000000;">回溯消费等常用功能。</span> </p> <p style="font-size:14px;color:#333333;"> <span style="color:#000000;">RocketMQ <span>核心的四大组件:</span>Name Server<span>、</span>Broker<span>、</span>Producer<span>、</span>Consumer <span>,每个组件都可以部署成集群进行水平扩展。</span></span> </p> <p style="font-size:14px;color:#333333;"> <strong><span style="color:#000000;">2、适应人群</span></strong> </p> <p style="font-size:14px;color:#333333;"> <span style="color:#000000;">有一定的Java基础,并且有分布式项目开发经验。</span> </p> <p style="font-size:14px;color:#333333;"> <strong><span style="color:#000000;">3、课程价值</span></strong> </p> <p style="font-size:14px;color:#333333;"> <span style="color:#000000;">可以让初学者对分布式系统解耦有一定认识,并且能够通过快速使用RocketMQ实现分布式服务的异步通信,同时本课程还会通过项目案例实战让学员对RocketMQ的应用场景有所体会,最后再通过源码角度让学员对RocketMQ的原理有所理解,不仅做到“知其然”,亦“知其所以然”。</span> </p> <p style="font-size:14px;color:#333333;"> <strong><span style="color:#000000;">4、课程收获</span></strong> </p> <p style="font-size:14px;color:#333333;"> <span style="color:#000000;">1. <span style="font-size:14px;">理解消息中间件MQ的优势和应用场景</span></span> </p> <p style="font-size:14px;color:#333333;"> <span style="color:#000000;">2. 掌握RocketMQ的核心功能,以及各种消息发送案例</span> </p> <p style="font-size:14px;color:#333333;"> <span style="color:#000000;">3. 通过电商项目深刻理解RocketMQ在使用项目中的落地应用</span> </p> <p style="font-size:14px;color:#333333;"> <span style="color:#000000;">4. 通过RocketMQ高级功能和源码学习,对RocketMQ的技术细节和原理有更加透彻的理解</span> </p> <p style="font-size:14px;color:#333333;"> <strong><span>5、课程亮点</span></strong> </p> <p style="font-size:14px;color:#333333;"> <span>l<span style="font-size:9px;">  </span></span><span style="font-size:17px;">核心功能</span> </p> <p style="font-size:14px;color:#333333;"> <span>n<span style="font-size:9px;">  </span></span><span>MQ介绍</span> </p> <p style="font-size:14px;color:#333333;"> <span>n<span style="font-size:9px;">  </span></span><span>环境准备</span> </p> <p style="font-size:14px;color:#333333;"> <span>n<span style="font-size:9px;">  </span></span><span>RocketMQ高可用集群搭建</span> </p> <p style="font-size:14px;color:#333333;"> <span>n<span style="font-size:9px;">  </span></span><span>各种消息发送样例</span> </p> <p style="font-size:14px;color:#333333;"> <span>l<span style="font-size:9px;">  </span></span><span>综合练习</span> </p> <p style="font-size:14px;color:#333333;"> <span>n<span style="font-size:9px;">  </span></span><span>项目背景介绍</span> </p> <p style="font-size:14px;color:#333333;"> <span>n<span style="font-size:9px;">  </span></span><span>功能分析</span> </p> <p style="font-size:14px;color:#333333;"> <span>n<span style="font-size:9px;">  </span></span><span>项目环境搭建</span> </p> <p style="font-size:14px;color:#333333;"> <span>n<span style="font-size:9px;">  </span></span><span>下单功能,保证各服务的数据一致性</span> </p> <p style="font-size:14px;color:#333333;"> <span>n<span style="font-size:9px;">  </span></span><span>确认订单功能,通过消息进行数据分发</span> </p> <p style="font-size:14px;color:#333333;"> <span>n<span style="font-size:9px;">  </span></span><span>整体联调</span> </p> <p style="font-size:14px;color:#333333;"> <span>l<span style="font-size:9px;">  </span></span><span>高级功能</span> </p> <p style="font-size:14px;color:#333333;"> <span>n<span style="font-size:9px;">  </span></span><span>消息的存储和发送</span> </p> <p style="font-size:14px;color:#333333;"> <span>n<span style="font-size:9px;">  </span></span><span>消息存储结构</span> </p> <p style="font-size:14px;color:#333333;"> <span>n<span style="font-size:9px;">  </span></span><span>刷盘机制</span> </p> <p style="font-size:14px;color:#333333;"> <span>n<span style="font-size:9px;">  </span></span><span>消息的同步复制和异步复制</span> </p> <p style="font-size:14px;color:#333333;"> <span>n<span style="font-size:9px;">  </span></span><span>负载均衡</span> </p> <p style="font-size:14px;color:#333333;"> <span>l<span style="font-size:9px;">  </span></span><span>源码分析</span> </p> <p style="font-size:14px;color:#333333;"> <span>n<span style="font-size:9px;">  </span></span><span>路由中心NameServer</span> </p> <p style="font-size:14px;color:#333333;"> <span>n<span style="font-size:9px;">  </span></span><span>消息生产者Producer</span> </p> <p style="font-size:14px;color:#333333;"> <span>n<span style="font-size:9px;">  </span></span><span>消息存储</span> </p> <p style="font-size:14px;color:#333333;"> <span>n<span style="font-size:9px;">  </span></span><span>消息消费Consumer</span> </p> <p style="font-size:14px;color:#333333;"> <strong><span>6、主讲内容</span></strong> </p> <p style="font-size:14px;color:#333333;"> <strong><span style="font-size:19px;">章节一:核心功能</span></strong> </p> <p style="font-size:14px;color:#333333;"> <span>1.<span style="font-size:9px;">     </span>快速入门</span> </p> <p style="font-size:14px;color:#333333;"> <span>a)<span style="font-size:9px;">     </span>MQ介绍</span> </p> <p style="font-size:14px;color:#333333;"> <span>b)<span style="font-size:9px;">     </span>作用</span> </p> <p style="font-size:14px;color:#333333;"> <span>c)<span style="font-size:9px;">      </span>注意事项</span> </p> <p style="font-size:14px;color:#333333;"> <span>d)<span style="font-size:9px;">     </span>各MQ产品比较</span> </p> <p style="font-size:14px;color:#333333;"> <span>2.<span style="font-size:9px;">     </span>RocketMQ环境搭建</span> </p> <p style="font-size:14px;color:#333333;"> <span>a)<span style="font-size:9px;">     </span>环境准备</span> </p> <p style="font-size:14px;color:#333333;"> <span>b)<span style="font-size:9px;">     </span>安装RocketMQ</span> </p> <p style="font-size:14px;color:#333333;"> <span>c)<span style="font-size:9px;">      </span>启动RocketMQ</span> </p> <p style="font-size:14px;color:#333333;"> <span>d)<span style="font-size:9px;">     </span>测试RocketMQ</span> </p> <p style="font-size:14px;color:#333333;"> <span>e)<span style="font-size:9px;">     </span>关闭RocketMQ</span> </p> <p style="font-size:14px;color:#333333;"> <span>3.<span style="font-size:9px;">     </span>RocketMQ高可用集群搭建</span> </p> <p style="font-size:14px;color:#333333;"> <span>a)<span style="font-size:9px;">     </span>集群各角色介绍</span> </p> <p style="font-size:14px;color:#333333;"> <span>b)<span style="font-size:9px;">     </span>集群搭建方式</span> </p> <p style="font-size:14px;color:#333333;"> <span>c)<span style="font-size:9px;">      </span>双主双从集群搭建</span> </p> <p style="font-size:14px;color:#333333;"> <span>d)<span style="font-size:9px;">     </span>集群监控平台</span> </p> <p style="font-size:14px;color:#333333;"> <span>4.<span style="font-size:9px;">     </span>各种消息发送样例</span> </p> <p style="font-size:14px;color:#333333;"> <span>a)<span style="font-size:9px;">     </span>同步消息</span> </p> <p style="font-size:14px;color:#333333;"> <span>b)<span style="font-size:9px;">     </span>异步消息</span> </p> <p style="font-size:14px;color:#333333;"> <span>c)<span style="font-size:9px;">      </span>单向消息</span> </p> <p style="font-size:14px;color:#333333;"> <span>d)<span style="font-size:9px;">     </span>顺序消息</span> </p> <p style="font-size:14px;color:#333333;"> <span>e)<span style="font-size:9px;">     </span>批量消息</span> </p> <p style="font-size:14px;color:#333333;"> <span>f)<span style="font-size:9px;">      </span>过滤消息</span> </p> <p style="font-size:14px;color:#333333;"> <span>g)<span style="font-size:9px;">     </span>事务消息</span> </p> <p style="font-size:14px;color:#333333;"> <strong><span style="font-size:19px;">章节二:项目实战</span></strong> </p> <p style="font-size:14px;color:#333333;"> <span>1.<span style="font-size:9px;">    </span>项目背景介绍</span> </p> <p style="font-size:14px;color:#333333;"> <span>(1)<span style="font-size:9px;">    </span>电商高可用MQ实战</span> </p> <p style="font-size:14px;color:#333333;"> <span>2.<span style="font-size:9px;">    </span>功能分析</span> </p> <p style="font-size:14px;color:#333333;"> <span>(1)<span style="font-size:9px;">    </span>下单功能</span> </p> <p style="font-size:14px;color:#333333;"> <span>(2)<span style="font-size:9px;">    </span>支付功能</span> </p> <p style="font-size:14px;color:#333333;"> <span>3.<span style="font-size:9px;">    </span>项目环境搭建</span> </p> <p style="font-size:14px;color:#333333;"> <span>(1)<span style="font-size:9px;">    </span>SpringBoot</span> </p> <p style="font-size:14px;color:#333333;"> <span>(2)<span style="font-size:9px;">    </span>Dubbo</span> </p> <p style="font-size:14px;color:#333333;"> <span>(3)<span style="font-size:9px;">    </span>Zookeeper</span> </p> <p style="font-size:14px;color:#333333;"> <span>(4)<span style="font-size:9px;">    </span>RocketMQ</span> </p> <p style="font-size:14px;color:#333333;"> <span>(5)<span style="font-size:9px;">    </span>Mysql</span> </p> <p style="font-size:14px;color:#333333;"> <span>4.下单功能,保证各服务的数据一致性</span> </p> <p style="font-size:14px;color:#333333;"> <span>5.确认订单功能,通过消息进行数据分发</span> </p> <p style="font-size:14px;color:#333333;"> <strong><span style="font-size:19px;">章节三:高级功能</span></strong> </p> <p style="font-size:14px;color:#333333;"> <span>1. 消息的存储和发送</span> </p> <p style="font-size:14px;color:#333333;"> <span>2. 消息存储结构</span> </p> <p style="font-size:14px;color:#333333;"> <span>3. 刷盘机制</span> </p> <p style="font-size:14px;color:#333333;"> <span>(1)<span style="font-size:9px;">    </span>同步刷盘</span> </p> <p style="font-size:14px;color:#333333;"> <span>(2)<span style="font-size:9px;">    </span>异步刷盘</span> </p> <p style="font-size:14px;color:#333333;"> <span>4. 消息的同步复制和异步复制</span> </p> <p style="font-size:14px;color:#333333;"> <span>5. 负载均衡</span> </p> <p style="font-size:14px;color:#333333;"> <span>(1)<span style="font-size:9px;">    </span>Producer负载均衡</span> </p> <p style="font-size:14px;color:#333333;"> <span>(2)<span style="font-size:9px;">    </span>Consumer负载均衡</span> </p> <p style="font-size:14px;color:#333333;"> <strong><span style="font-size:19px;">章节四:源码分析</span></strong> </p> <p style="font-size:14px;color:#333333;"> <span>1.<span style="font-size:9px;">     </span>路由中心NameServer</span> </p> <p style="font-size:14px;color:#333333;"> <span>a)<span style="font-size:9px;">     </span>NameServer架构设计</span> </p> <p style="font-size:14px;color:#333333;"> <span>b)<span style="font-size:9px;">     </span>NameServer启动流程</span> </p> <p style="font-size:14px;color:#333333;"> <span>c)<span style="font-size:9px;">      </span>NameServer路由注册和故障剔除</span> </p> <p style="font-size:14px;color:#333333;"> <span>2.<span style="font-size:9px;">     </span>消息生产者Producer</span> </p> <p style="font-size:14px;color:#333333;"> <span>a)<span style="font-size:9px;">     </span>生产者启动流程</span> </p> <p style="font-size:14px;color:#333333;"> <span>b)<span style="font-size:9px;">     </span>生产者发送消息流程</span> </p> <p style="font-size:14px;color:#333333;"> <span>c)<span style="font-size:9px;">      </span>批量发送</span> </p> <p style="font-size:14px;color:#333333;"> <span>3.<span style="font-size:9px;">     </span>消息存储</span> </p> <p style="font-size:14px;color:#333333;"> <span>a)<span style="font-size:9px;">     </span>消息存储流程</span> </p> <p style="font-size:14px;color:#333333;"> <span>b)<span style="font-size:9px;">     </span>存储文件与内存映射</span> </p> <p style="font-size:14px;color:#333333;"> <span>c)<span style="font-size:9px;">      </span>存储文件</span> </p> <p style="font-size:14px;color:#333333;"> <span>d)<span style="font-size:9px;">     </span>实时更新消息消费队列和存储文件</span> </p> <p style="font-size:14px;color:#333333;"> <span>e)<span style="font-size:9px;">     </span>消息队列与索引文件恢复</span> </p> <p style="font-size:14px;color:#333333;"> <span>f)<span style="font-size:9px;">      </span>刷盘机制</span> </p> <p style="font-size:14px;color:#333333;"> <span>4.<span style="font-size:9px;">     </span></span><span>过期文件删除机制</span> </p> <p style="font-size:14px;color:#333333;"> <span>a)<span style="font-size:9px;">     </span>消息消费Consumer</span> </p> <p style="font-size:14px;color:#333333;"> <span>b)<span style="font-size:9px;">     </span>消费者启动流程</span> </p> <p style="font-size:14px;color:#333333;"> <span>c)<span style="font-size:9px;">      </span>消息拉取</span> </p> <p style="font-size:14px;color:#333333;"> <span>d)<span style="font-size:9px;">     </span>消息队列负载均衡和重新分布机制</span> </p> <p style="font-size:14px;color:#333333;"> <span>e)<span style="font-size:9px;">     </span>消息消费过程</span> </p> <p style="font-size:14px;color:#333333;"> <span>f)<span style="font-size:9px;">      </span>定时消息机制</span> </p> <p style="font-size:14px;color:#333333;"> <span>g)<span style="font-size:9px;">     </span>顺序消息</span> </p>
相关推荐
©️2020 CSDN 皮肤主题: 精致技术 设计师:CSDN官方博客 返回首页