rocketmq问题汇总-如何将特定消息发送至特定queue,消费者从特定queue消费

原创 2016年04月20日 11:56:05
  1. 业务描述

    由于业务需要这样一种场景,将消息按照id(业务id)尾号发送到对应的queue中,并启动10个消费者(单jvm,10个消费者组),从对应的queue中集群消费,如下图1所示(假设有两个broker组成的集群):
    图1

  2. producer如何实现

    producer只需发送消息时调用如下方法即可

    /**
     * 发送有序消息
     *
     * @param messageMap 消息数据
     * @param selector   队列选择器,发送时会回调
     * @param order      回调队列选择器时,此参数会传入队列选择方法,提供配需规则
     * @return 发送结果
     */
    public Result<SendResult> send(Message msg, MessageQueueSelector selector, Object arg)

    关键是如何实现MessageQueueSelector:

    class IDHashMessageQueueSelector implements MessageQueueSelector{
        public MessageQueue select(List<MessageQueue> mqs, Message msg,
                Object arg) {
            int id = Integer.parseInt(arg.toString());
            int size = mqs.size();
            int index = id%size;
            return mqs.get(index);
        }
    }

    这样,所有的消息会根据消息的尾号,轮询的落到相应的queue上。参考图2,假设id=10001231,由于一共有20个queue,所以10001231%20=11,故消息会落到broker-b queue-1上。
    图2

  3. consumer端如何实现

    针对consumer由于没有限制是顺序消费,故可以采用集群消费模式的DefaultMQPushConsumer,由于一个消费者消费一类queue,故需要10个consumer group,比如consumer group0需要消费的queue为broker-a queue-0和broker-b queue-0,如下图的概示:
    这里写图片描述
    那么需要自己实现一个AllocateMessageQueueStrategy进行queue的分配,我们假设consumer group的名字格式需要提前定好,如xxx{queueid}ConsumerGroup,那么实现如下:

    public class AllocateMessageQueueByHashAveragely extends AllocateMessageQueueAveragely{
    private final Logger log = ClientLogger.getLog();
    @Override
    public String getName() {
        return super.getName()+"ByIDHash";
    }
    
    @Override
    public List<MessageQueue> allocate(String consumerGroup, String currentCID,
            List<MessageQueue> mqAll, List<String> cidAll) {
        //解析queue id
        char idChar = consumerGroup.charAt(consumerGroup.length() - "ConsumerGroup".length() - 1);
        int id = Integer.parseInt(idChar+"");
        List<MessageQueue> submq = new ArrayList<MessageQueue>();
        //根据queue id分配相应的MessageQueue
        for(MessageQueue mq : mqAll) {
            if(mq.getQueueId() == idChar || mq.getTopic().startsWith(MixAll.RETRY_GROUP_TOPIC_PREFIX)) {
                submq.add(mq);
            }
        }
        if(submq.size() == 0) {
            log.warn("allocate err:"+consumerGroup+","+currentCID+","+cidAll+","+mqAll);
        }
        return super.allocate(consumerGroup, currentCID, submq, cidAll);
    }
    }

    借助AllocateMessageQueueAveragely来实现,以便有多个jvm的消费者时,能够进行集群消费,但是针对上面这个例子,消费者jvm实例不能超过2个,至于为什么,参照下图:
    这里写图片描述

  4. over
版权声明:本文为博主原创文章,未经博主允许不得转载。

RocketMQ(三)如何解决消息的顺序&重复两大硬伤?

备注: 1.如果您此前未接触过RocketMQ,请先阅读附录部分,以便了解RocketMQ的整体架构和相关术语 2.文中的MQServer与Broker表示同一概念 分布式消息系统作为实现...
  • dreamsunday
  • dreamsunday
  • 2016年06月28日 16:29
  • 16938

分布式消息队列RocketMQ与Kafka架构上的巨大差异之2 -- CommitLog与ConsumeQueue

在前面Rocket与Kafka的对比之“拨乱反正”续篇中,我们已经提到了RocketMQ和Kafka在架构上面的一个巨大差异:Kafka是每个partition对应一个文件,而RocketMQ是把所有...
  • chunlongyu
  • chunlongyu
  • 2017年01月16日 19:01
  • 2412

分布式消息队列RocketMQ与Kafka架构上的巨大差异之1 -- 为什么RocketMQ要去除ZK依赖?

我们知道,在早期的RocketMQ版本中,是有依赖ZK的。而现在的版本中,是去掉了对ZK的依赖,转而使用自己开发的NameSrv。 并且这个NameSrv是无状态的,你可以随意的部署多台,其代码也非常...
  • gh670011677
  • gh670011677
  • 2017年07月14日 09:03
  • 936

rocketmq学习笔记 二 官方实例<消息顺序>

所谓消息顺序,是指在一些业务场景下, 消息是有先后顺序的 在rocketmq中, 如何保持消息顺序? 把所要保持顺序的消息,放到同一个消息队列即可。实现MessageQueueSelector接口...
  • akfly
  • akfly
  • 2016年12月08日 22:15
  • 2487

《RocketMq》五、Consumer消费者

Consumer-集群Push模式-简介: 0、背景介绍          Consumer主要用于向Broker请求Producer产生的消息,对其进行消费;对于RocketMQ,我们一定很好奇,如...
  • xxxxxx91116
  • xxxxxx91116
  • 2015年12月23日 23:18
  • 17493

RocketMQ原理解析-consumer 2.消费端负载均衡

消费端负载均衡
  • u010311445
  • u010311445
  • 2014年09月09日 00:08
  • 5003

RocketMQ——Producer篇:发送顺序消息

顺序消息主要是指局部顺序,即生产者通过将某一类消息发送至同一个队列来实现。与发生普通消息相比,在发送顺序消息时要对同一类型的消息选择同一个队列,即同一个MessageQueue对象。 目前Rocke...
  • meilong_whpu
  • meilong_whpu
  • 2017年08月09日 08:56
  • 275

Rocket学习小结

一:RocketMQ简介RocketMQ是分布式、队列模型的消息中间件, MetaQ 的 3.0 版本。 特点 数据可靠性 消费失败重试 严格的消息顺序 定时消息 消息查询 消息回溯 ...
  • qq_36569036
  • qq_36569036
  • 2016年11月15日 13:13
  • 735

深入理解 RocketMQ

本文对RocketMQ的仅做理论性阐述,以便更深入的理解RocketMQ的内部机制,遇到棘手的问题更容易入手解决。关于代码实战请参考鄙人的另一篇文章:RocketMQ 入门使用详解...
  • zhglance
  • zhglance
  • 2017年02月13日 22:42
  • 1280

RocketMQ批量消费、消息重试、消费模式、刷盘方式

C端先启动和C端后启动 消息重试机制:P端和C端2中重试
  • u010634288
  • u010634288
  • 2017年02月25日 19:41
  • 7256
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:rocketmq问题汇总-如何将特定消息发送至特定queue,消费者从特定queue消费
举报原因:
原因补充:

(最多只允许输入30个字)