RocketMQ使用教程及部分原理分析两种监听模式以及消费失败处理策略

RocketMQ由producer、NameServer、broker、consumer组成

Producer:

为生产者,消息的来源。需要与NameServer建立连接,从NameServer获取Topic对应的Message Queue的broker地址

NameServer:

相当于一个路由器,存着broker的地址信息和对应的topic信息。NameServer可以横向扩展,broker和每一台NameServer建立长连接

Broker:

Broker是RocketMQ的核心,提供了消息的接收,存储,拉取等功能。Broker可以配置主从,主从关系通过BrokerId来定义,0为主1为从。

Consumer

消费者,同样与NameServer建立连接,从NameServer获取Topic对应的Message Queue的broker地址。然后与Broker Master、Slave建立连接。

topic与message queue

发送消息时,需要指定msg的topic,每个topic可以设置多个queue,默认为4个
不同的topic对应的queue不同。

准备工作

安装RocketMQ,并启动NameServer和Broker,因为broker启动时要在Nameserver注册信息,所以要先启动NameServer再启动Broker

发送消息

消息发送使用Producer的send方法来发送消息。
DefaultMQProducer为rmq的默认producer类,我们创建DefaultMQProducer对象作为producer来发送消息,创建DefaultMQProducer对象时需要传入NameServer地址和producerGroup名字,其他参数可不填(有默认配置)

DefaultMQProducer producer = new DefaultMQProducer("group1");
        producer.setNamesrvAddr("106.53.xx.xxx:9876");

发送的消息为Message格式,里面有我们所要发送的信息body,消息绑定的tags和消息绑定的topic
topic可以在发送消息前创建,如果不主动创建,在发送消息的时候会自动创建

 public Message(String topic, String tags, byte[] body) {
        this(topic, tags, "", 0, body, true);
    }
producer发送消息有三种基本方式
  1. 同步

    2 . 异步
  2. 单向
/**
     * 同步发送
     * 需要返回结果
     */
    public SendResult sendNeedResult() throws InterruptedException, MQClientException, MQBrokerException {
        SendResult sendResult = producer.send(message);
    }
    /**
     * 异步发送
     * 回调方法中返回结果
     */
    public void sendNeedResultByCallBack() throws MQClientException, InterruptedException {
    
        producer.send(message, new SendCallback() {
            @Override
            public void onSuccess(SendResult sendResult) {
                //成功的处理
            }
            @Override
            public void onException(Throwable e) {
                //失败的处理
            }
        });
    }
 
    /**
     * 单向发送
     * 无需返回结果
     */
    public void sendNotNeedResul() throws MQClientException, InterruptedException {
        producer.sendOneway(message);
    }

消费消息

Consumer的基本的默认实现有两种DefaultMQPushConsumer、DefaultMQPullConsumer;push的底层也是pull。这里只介绍push

DefaultMQPushConsumer consumer =
      new DefaultMQPushConsumer("group1");
        consumer.setNamesrvAddr("106.xx.xx.xxx:9876");
        consumer.subscribe("OrderTopic","*");
		//非强制配置,默认为集群
        consumer.setMessageModel(MessageModel.CLUSTERING);
		//非强制配置,默认为CONSUME_FROM_FIRST_OFFSET
		consumer.setConsumeFromWhere();

使用consumer前需要设定nameserver地址、订阅主题、设置所在组名

CONSUME_FROM_LAST_OFFSET:第一次启动从队列最后位置消费,后续再启动接着上次消费的进度开始消费
CONSUME_FROM_FIRST_OFFSET:第一次启动从队列初始位置消费,后续再启动接着上次消费的进度开始消费
CONSUME_FROM_TIMESTAMP:第一次启动从指定时间点位置消费,后续再启动接着上次消费的进度开始消费
以上所说的第一次启动是指从来没有消费过的消费者,如果该消费者消费过,那么会在broker端记录该消费者的消费位置,如果该消费者挂了再启动,那么自动从上次消费的进度开始

广播消费、集群消费

BROADCASTING广播模式,CLUSTERING集群模式,默认的是 集群消费模式。

广播消费指的是:一条消息被多个consumer消费,即使这些consumer属于同一个ConsumerGroup,消息也会被ConsumerGroup中的每个Consumer都消费一次。

集群消费模式:一个ConsumerGroup中的Consumer实例平均分摊消费消息。例如某个Topic有9条消息,其中一个ConsumerGroup有3个实例(可能是3个进程,或者3台机器),那么每个实例只消费其中部分,消费完的消息不能被其他实例消费。

集群消费下的负载均衡

一旦有新的consumer连接到broker,broker会进行一次负载均衡,以queue为最小单位,订阅的所有queue分配给不同的consumer消费。任何时候一个队列只对应一个consumer
AllocateMessageQueueStrategy allocateMessageQueueStrategy
消息分配策略,用于集群模式下,消息平均分配给所有客户端
默认实现为AllocateMessageQueueAveragely

消息监听器、消费方式

监听器监听消息,收到消息后,就执行监听器的方法执行具体消费。
监听器分为两种:(并发消费)ConsumeMessageConcurrentlyService,(顺序消费)为ConsumeMessageOrderlyService

消费失败问题

并发消费返回的状态有两种:
ConsumeConcurrentlyStatus.RECONSUME_LATER、
ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
前者为消费失败稍后重试,后者为消费成功

若消费失败(抛出异常或者返回了失败)。为了保证消息是肯定被至少消费成功一次,RocketMQ会把这批消息重发回Broker(topic不是原topic而是这个消费租的RETRY topic),在延迟的某个时间点(默认是10秒,业务可设置)后,再次投递到这个ConsumerGroup。而如果一直这样重复消费都持续失败到一定次数(默认16次),就会投递到DLQ死信队列。应用可以监控死信队列来做人工干预。
在这里插入图片描述

顺序消费返回的状态有两种:
ConsumeOrderlyStatus.SUCCESS
SUSPEND_CURRENT_QUEUE_A_MOMENT
前者为消费成功,后者为消费失败
由于顺序消费是要前者消费成功才能继续消费,所以没有RECONSUME_LATER的这个状态,只有SUSPEND_CURRENT_QUEUE_A_MOMENT来暂停队列的其余消费,直到原消息不断重试成功为止才能继续消费。
顺序消费消费失败后,不会把该消息放入重试队列,而是保留在当前队列继续重试消费直到成功,才继续往下消费。所以顺序消费可能出现某个队列被卡住的现象。

顺序消费问题:

不管是顺序消费还是并发消费,comsumer会同时消费拥有的所有queue,而不是消费完queue1再去消费queue2,所以不同queue中消息的顺序性消费不能保证;
queue内的顺序:由于顺序消费是要前者消费成功才能继续消费所以顺序消费的queue内部的消费是有序的。

默认线程数
默认list中消息数
ConsumeFromWhere是干嘛的
MessageModel是干嘛的
send消息的整个流程
消费失败处理策略
是如何push和pull的
查看队列中的消息是否堆积或者消息剩余情况
顺序消费时的context.setAutoCommit(true);有什么含义
ClientConfig#clientCallbackExecutorThreads
consumer默认的线程池
RPCHook是什么
负载均衡

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值