All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.aliyun.openservices.ons.client.rocketmq.PushConsumer Maven / Gradle / Ivy

There is a newer version: 2.0.7.Final
Show newest version
package com.aliyun.openservices.ons.client.rocketmq;

import com.aliyun.openservices.ons.api.ExpressionType;
import com.aliyun.openservices.ons.api.MessageSelector;
import com.aliyun.openservices.ons.api.OffsetStore;
import com.aliyun.openservices.ons.api.PropertyKeyConst;
import com.aliyun.openservices.ons.api.PropertyValueConst;
import com.aliyun.openservices.ons.api.TopicPartition;
import com.aliyun.openservices.ons.api.exception.ONSClientException;
import com.aliyun.openservices.ons.client.ClientAbstract;
import com.aliyun.openservices.ons.client.utils.UtilAll;
import com.aliyun.openservices.ons.shaded.com.google.common.base.Optional;
import java.util.Properties;
import com.aliyun.openservices.ons.shaded.commons.lang3.StringUtils;
import com.aliyun.openservices.ons.shaded.org.apache.rocketmq.client.consumer.DefaultMQPushConsumer;
import com.aliyun.openservices.ons.shaded.org.apache.rocketmq.client.consumer.MessageModel;
import com.aliyun.openservices.ons.shaded.org.apache.rocketmq.client.exception.ClientException;
import com.aliyun.openservices.ons.shaded.org.apache.rocketmq.client.message.MessageQueue;
import com.aliyun.openservices.ons.shaded.org.slf4j.Logger;
import com.aliyun.openservices.ons.shaded.org.slf4j.LoggerFactory;

public class PushConsumer extends ClientAbstract {
    private static final Logger log = LoggerFactory.getLogger(PushConsumer.class);

    private static final int MAX_CACHED_MESSAGES_QUANTITY = 50000;
    private static final int MIN_CACHED_MESSAGES_QUANTITY = 100;
    private static final int DEFAULT_CACHED_MESSAGES_QUANTITY = 5000;

    private static final int MIN_CACHED_MESSAGE_MEMORY_IN_MIB = 16;
    private static final int MAX_CACHED_MESSAGE_MEMORY_IN_MIB = 2048;
    private static final int DEFAULT_CACHED_MESSAGE_MEMORY_IN_MIB = 512;

    private static final int DEFAULT_CONSUMPTION_THREADS_AMOUNT = 20;
    private static final int CONSUMPTION_THREADS_MAX_AMOUNT = 1000;
    private static final long DEFAULT_CONSUMPTION_TIMEOUT_MILLIS = 15 * 60 * 1000L;

    protected final DefaultMQPushConsumer defaultMQPushConsumer;

    public PushConsumer(final Properties properties) {
        super(properties);
        final String groupId = properties.getProperty(PropertyKeyConst.GROUP_ID);
        if (StringUtils.isBlank(groupId)) {
            throw new ONSClientException("Group id is blank, please set it.");
        }
        // group id.
        try {
            this.defaultMQPushConsumer = new DefaultMQPushConsumer(groupId);
        } catch (ClientException e) {
            throw new ONSClientException(e);
        }
        // provider.
        this.defaultMQPushConsumer.setCredentialsProvider(provider);
        // max delivery attempts.
        final String maxReconsumeTimes = properties.getProperty(PropertyKeyConst.MaxReconsumeTimes);
        if (StringUtils.isNoneBlank(maxReconsumeTimes)) {
            int maxDeliveryAttempts;
            try {
                maxDeliveryAttempts = 1 + Integer.parseInt(maxReconsumeTimes);
            } catch (NumberFormatException e) {
                throw new ONSClientException("Illegal format of " + PropertyKeyConst.MaxReconsumeTimes);
            }
            this.defaultMQPushConsumer.setMaxDeliveryAttempts(maxDeliveryAttempts);
        }
        try {
            // name server address.
            this.defaultMQPushConsumer.setNamesrvAddr(nameServerAddr);
        } catch (Throwable t) {
            throw new ONSClientException(t);
        }

        if (null != namespace) {
            this.defaultMQPushConsumer.setNamespace(namespace);
        }
        // message tracing enabled.
        this.defaultMQPushConsumer.setMessageTracingEnabled(messageTracingEnabled);
        // message model.
        final String messageModel = properties.getProperty(PropertyKeyConst.MessageModel,
                                                           PropertyValueConst.DEFAULT_MESSAGE_MODEL);
        this.defaultMQPushConsumer.setMessageModel(MessageModel.valueOf(messageModel));
        // max cached message quantity.
        final String maxCachedMessagesQuantityProp = properties.getProperty(PropertyKeyConst.MaxCachedMessageAmount);
        int maxCachedMessagesQuantity = DEFAULT_CACHED_MESSAGES_QUANTITY;
        if (StringUtils.isNoneBlank(maxCachedMessagesQuantityProp)) {
            maxCachedMessagesQuantity = Integer.parseInt(maxCachedMessagesQuantityProp);
            maxCachedMessagesQuantity = Math.max(MIN_CACHED_MESSAGES_QUANTITY, maxCachedMessagesQuantity);
            maxCachedMessagesQuantity = Math.min(MAX_CACHED_MESSAGES_QUANTITY, maxCachedMessagesQuantity);
        }
        defaultMQPushConsumer.setMaxTotalCachedMessagesQuantityThreshold(maxCachedMessagesQuantity);
        // max cached message bytes.
        final String maxCachedMessageSizeInMibProp = properties.getProperty(PropertyKeyConst.MaxCachedMessageSizeInMiB);
        int maxCachedMessageSizeInMib = DEFAULT_CACHED_MESSAGE_MEMORY_IN_MIB;
        if (StringUtils.isNoneBlank(maxCachedMessageSizeInMibProp)) {
            maxCachedMessageSizeInMib = Integer.parseInt(maxCachedMessageSizeInMibProp);
            maxCachedMessageSizeInMib = Math.max(MIN_CACHED_MESSAGE_MEMORY_IN_MIB, maxCachedMessageSizeInMib);
            maxCachedMessageSizeInMib = Math.min(MAX_CACHED_MESSAGE_MEMORY_IN_MIB, maxCachedMessageSizeInMib);
        }
        defaultMQPushConsumer.setMaxTotalCachedMessagesBytesThreshold(1024 * 1024 * maxCachedMessageSizeInMib);
        // consumption timeout millis.
        long consumptionTimeoutMillis = DEFAULT_CONSUMPTION_TIMEOUT_MILLIS;
        final String consumptionTimeoutMinutesProp = properties.getProperty(PropertyKeyConst.ConsumeTimeout);
        if (StringUtils.isNoneBlank(consumptionTimeoutMinutesProp)) {
            consumptionTimeoutMillis = Long.parseLong(consumptionTimeoutMinutesProp) * 60 * 1000;
        }
        // consumption threads amount.
        defaultMQPushConsumer.setConsumptionTimeoutMillis(consumptionTimeoutMillis);
        int consumptionThreadsAmount = DEFAULT_CONSUMPTION_THREADS_AMOUNT;
        final String consumptionThreadsAmountProp = properties.getProperty(PropertyKeyConst.ConsumeThreadNums);
        if (StringUtils.isNoneBlank(consumptionThreadsAmountProp)) {
            consumptionThreadsAmount = Integer.parseInt(consumptionThreadsAmountProp);
        }
        if (consumptionThreadsAmount < 1 || consumptionThreadsAmount > CONSUMPTION_THREADS_MAX_AMOUNT) {
            throw new ONSClientException("Consumption thread amount is out of range [1, 1000]");
        }
        defaultMQPushConsumer.setConsumptionThreadsAmount(consumptionThreadsAmount);
    }

    protected void subscribe(String topic, MessageSelector selector) {
        final ExpressionType type = selector.getType();
        com.aliyun.openservices.ons.shaded.org.apache.rocketmq.client.consumer.filter.ExpressionType rocketmqType;
        switch (type) {
            case TAG:
                rocketmqType = com.aliyun.openservices.ons.shaded.org.apache.rocketmq.client.consumer.filter.ExpressionType.TAG;
                break;
            case SQL92:
            default:
                rocketmqType = com.aliyun.openservices.ons.shaded.org.apache.rocketmq.client.consumer.filter.ExpressionType.SQL92;
                break;
        }
        this.defaultMQPushConsumer.subscribe(topic, selector.getSubExpression(), rocketmqType);
    }

    public void unsubscribe(String topic) {
        this.defaultMQPushConsumer.unsubscribe(topic);
    }

    public void setOffsetStore(final OffsetStore offsetStore) {
        if (null == offsetStore) {
            throw new ONSClientException("OffsetStore is null, please set it.");
        }
        this.defaultMQPushConsumer.setOffsetStore(new com.aliyun.openservices.ons.shaded.org.apache.rocketmq.client.impl.consumer.OffsetStore() {

            @Override
            public void start() {
                offsetStore.start();
            }

            @Override
            public void shutdown() {
                offsetStore.shutdown();
            }

            @Override
            public void updateOffset(MessageQueue mq, long offset) {
                final TopicPartition partition = UtilAll.convertToPartition(mq);
                offsetStore.updateOffset(partition, offset);
            }

            @Override
            public Optional readOffset(MessageQueue mq) {
                final TopicPartition partition = UtilAll.convertToPartition(mq);
                return offsetStore.readOffset(partition);
            }
        });
    }

    @Override
    public void start() {
        try {
            if (this.started.compareAndSet(false, true)) {
                log.info("Begin to start the ONS consumer.");
                this.defaultMQPushConsumer.start();
                log.info("Start the ONS consumer successfully.");
                return;
            }
            log.warn("ONS consumer has been started before.");
        } catch (Exception e) {
            log.error("Failed to start the ONS consumer.");
            throw new ONSClientException(e.getMessage());
        }
    }

    @Override
    public void shutdown() {
        if (this.started.compareAndSet(true, false)) {
            log.info("Begin to shutdown the ONS consumer.");
            try {
                this.defaultMQPushConsumer.shutdown();
            } catch (Throwable t) {
                throw new ONSClientException(t);
            }
            log.info("Shutdown the ONS consumer successfully.");
            return;
        }
        log.warn("Failed to shutdown the ONS consumer.");
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy