DefaultMQPushConsume消费者

DefaultMQPushConsumer,由系统控制拉取操作,即由rocket源码从Broker,将消息拉取到消费者本地。消费者收到消息后,rocket源码会自动调用传人的处理方法来处理消息。

1.1 创建DefaultMQPushConsume消费者对象

// 指定组名
DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("please_rename_unique_group_name");

创建消费者对象的时候,一般会指定消费者组名groupName。下面是DefaultMQPushConsumer的各种配置属性。

1.1.1 groupName和messageModel属性

创建消费者对象的时候,一般会指定消费者组名。这个祖名groupName也就是订阅组。一般情况下,假如有多个消费者,每一个消费者都使用相同的groupName,那么这些消费者构成的就属于一个组也就是订阅组。Consumer的groupName用于把多个Consumer组织到一起,形成一个订阅组,这样订阅组里的每个消费者都会收到Topic里面的消息。订阅组里的每一个消费者如何接收topic的消息则有messageModel决定。

//set to broadcast mode
consumer.setMessageModel(MessageModel.BROADCASTING);

RocketMQ 支持两种消息模式: Clustering 和Broadcasting 。

  • 在Clustering 模式下,同一个ConsumerGroup(GroupName相同)里的每个Consumer只消费所订阅消息的一部分内容,同一个ConsumerGroup里所有的Consumer 消费的内容合起来才是所订阅Topic 内容的整体,从而达到负载均衡的目的。
  • 在Broadcasting模式下,同一个ConsumerGroup里的每个Consumer都能消费到所订阅Topic的全部消息,也就是一个消息会被多次分发,被多个Consumer 消费。

1.1.2 ​​​​​​​consumerFromWhere属性

consumer.setConsumeFromWhere(ConsumeFromWhere.CONSUME_FROM_FIRST_OFFSET);

public enum ConsumeFromWhere {
// 一个新的订阅组第一次启动从队列的最后位置开始消费,后续再启动接着上次消费的进度开始消费
    CONSUME_FROM_LAST_OFFSET,
    /** @deprecated */
    @Deprecated
    CONSUME_FROM_LAST_OFFSET_AND_FROM_MIN_WHEN_BOOT_FIRST,
    /** @deprecated */
    @Deprecated
    CONSUME_FROM_MIN_OFFSET,
    /** @deprecated */
    @Deprecated
    CONSUME_FROM_MAX_OFFSET,
// 一个新的订阅组第一次启动从队列的最前位置开始消费,后续再启动接着上次消费的进度开始消费
    CONSUME_FROM_FIRST_OFFSET,
// 一个新的订阅组第一次启动从指定时间点开始消费,后续再启动接着上次消费的进度开始消费
//时间点设置参照DefaultPushConsumer.consumeTimestamp参数
    CONSUME_FROM_TIMESTAMP;

    private ConsumeFromWhere() {
    }
}

这个参数只对一个新的consumeGroup第一次启动时有效,就是说,如果是一个consumerGroup重启,他只会从自己上次消费到的offset,继续消费。这个参数是没用的。

1.1.3 ​​​​​​​topic和tag属性

consumer.subscribe("TopicTest", "Tag1 || Tag2 || Tag3");

Topic名称用来标识消息类型,需要提前创建。如果不需要消费某个Topic 下的所有消息,可以通过指定消息的Tag 进行消息过滤,比如:consumer.subscribe(”Topic Test”J ’tagl 11 tag2 11 tag3 ”),表示这个consumer 要消费“ TopicTest ”下带有tagl 或tag2 或tag3 的消息( Tag 是在发送消息时设置的标签)。在填写Tag 参数的位置,用null 或者“*” 表示要消费这个Topic的所有消息。

1.1.4 ​​​​​​​consumerThreadMin和consumerThreadMax属性

消费者使用一个 ThreadPoolExecutor 来处理内部的消费,因此您可以通过设置setConsumeThreadMin或setConsumeThreadMax来更改它,它的默认值为20。这个属性能够增加消费者服务器的处理线程数,提高消费速度。

public class DefaultMQPushConsumer extends ClientConfig implements MQPushConsumer {

    private final InternalLogger log = ClientLogger.getLog();

    //......

    /**
     * Minimum consumer thread number
     */
    private int consumeThreadMin = 20;

    /**
     * Max consumer thread number
     */
    private int consumeThreadMax = 20;

    public int getConsumeThreadMax() {
        return consumeThreadMax;
    }

    public int getConsumeThreadMin() {
        return consumeThreadMin;
    }

    //......
}

public class ConsumeMessageConcurrentlyService implements ConsumeMessageService {
    private static final InternalLogger log = ClientLogger.getLog();
    private final DefaultMQPushConsumerImpl defaultMQPushConsumerImpl;
    private final DefaultMQPushConsumer defaultMQPushConsumer;
    private final MessageListenerConcurrently messageListener;
    private final BlockingQueue<Runnable> consumeRequestQueue;
    private final ThreadPoolExecutor consumeExecutor;
    private final String consumerGroup;

    private final ScheduledExecutorService scheduledExecutorService;
    private final ScheduledExecutorService cleanExpireMsgExecutors;

    public ConsumeMessageConcurrentlyService(DefaultMQPushConsumerImpl defaultMQPushConsumerImpl,
        MessageListenerConcurrently messageListener) {
        this.defaultMQPushConsumerImpl = defaultMQPushConsumerImpl;
        this.messageListener = messageListener;

        this.defaultMQPushConsumer = this.defaultMQPushConsumerImpl.getDefaultMQPushConsumer();
        this.consumerGroup = this.defaultMQPushConsumer.getConsumerGroup();
        this.consumeRequestQueue = new LinkedBlockingQueue<Runnable>();
        // 创建线程池用来处理消息,consumeThreadMin、consumeThreadMax分别作为核心线程数和最大线程数
        this.consumeExecutor = new ThreadPoolExecutor(
            this.defaultMQPushConsumer.getConsumeThreadMin(),
            this.defaultMQPushConsumer.getConsumeThreadMax(),
            1000 * 60,
            TimeUnit.MILLISECONDS,
            this.consumeRequestQueue,
            new ThreadFactoryImpl("ConsumeMessageThread_"));

        this.scheduledExecutorService = Executors.newSingleThreadScheduledExecutor(new ThreadFactoryImpl("ConsumeMessageScheduledThread_"));
        this.cleanExpireMsgExecutors = Executors.newSingleThreadScheduledExecutor(new ThreadFactoryImpl("CleanExpireMsgScheduledThread_"));
    }

    //......

}

1.1.5 ​​​​​​​pullBatchSize和consumeMessageBatchMaxSize属性

pullBatchSize是consumer每次从broker拉取的消息最大数,拉取后新消息先存储到consumer内存中。而consumeMessageBatchMaxSize参数代表了,每次将内存中存储的新消息(pullBatchSize参数拉取的消息)传递给开发者自定义的处理方法的最多条数,也是为了提高消费速度的配置项。

consumer.setPullBatchSize(100);
consumer.setConsumeMessageBatchMaxSize(10);
consumer.registerMessageListener(new MessageListenerConcurrently() {
                // 使用list的方法
                public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs, ConsumeConcurrentlyContext context) {
                    for(MessageExt msg : msgs) {
                        System.out.println("-------->" + msg.getKeys());
                        System.out.println("-------->" + msg.getMsgId());
                        System.out.println("-------->" + msg.getQueueId());
                        System.out.println("-------->" + msg.getQueueOffset());
                        System.out.println("-------->" + msg.getBody().toString());
                        System.out.println("-------->" + msg.toString());
                    }
                    return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
                }
            });

1.1.6 instanceName属性

假如一个项目里面需要连接2个RocketMQ集群,则单个MQClientInstance无法支持这种场景,一定要手动指定InstanceName,这时底层会创建两个MQClientInstance对象。

consumer.setInstanceName()

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章