com.aliyun.openservices.ons.client.rocketmq.PushConsumer Maven / Gradle / Ivy
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.");
}
}