RocketMQ 生产者与消费者的封装

一、抽象消费类封装:

public abstract class Consumer {

    protected final Logger logger = LoggerFactory.getLogger(getClass());

    protected DefaultMQPushConsumer defaultMQPushConsumer;

    @Value("${rocketMQ.nameServer.address}")
    private String nameServerAddress;

    @PostConstruct
    private void init() throws MQClientException {
        defaultMQPushConsumer = new DefaultMQPushConsumer();
        defaultMQPushConsumer.setNamesrvAddr(nameServerAddress);
        defaultMQPushConsumer.setConsumeThreadMax(20);
        defaultMQPushConsumer.setConsumeThreadMin(10);
        init(defaultMQPushConsumer);
    }

    private void init(DefaultMQPushConsumer defaultMQPushConsumer) throws MQClientException {
        final MQConfig mqCfg = getMQConfig();
        defaultMQPushConsumer.setInstanceName(mqCfg.getInstanceName());
        defaultMQPushConsumer.setConsumerGroup(mqCfg.getConsumerGroup());
        defaultMQPushConsumer.subscribe(mqCfg.getTopic(), mqCfg.getSubExpression());

        // 设置Consumer第一次启动是从队列头部开始消费还是队列尾部开始消费,如果非第一次启动,那么按照上次消费的位置继续消费
        defaultMQPushConsumer.setConsumeFromWhere(ConsumeFromWhere.CONSUME_FROM_LAST_OFFSET);
        defaultMQPushConsumer.setMessageModel(mqCfg.getMessageModel());// 设置为集群消费(区别于广播消费)
        defaultMQPushConsumer.registerMessageListener(new MessageListenerConcurrently() { // 这里可以抽离出来,添加一个继承MessageListenerConcurrently的类
            @Override
            public ConsumeConcurrentlyStatus consumeMessage(List msgs, ConsumeConcurrentlyContext context) {
                if (null != msgs && !msgs.isEmpty()) {
                    for (MessageExt msg : msgs) {
                        if (mqCfg.getTopic().equals(msg.getTopic())) {
                            try {
                                consume(msg, context);
                            } catch (Exception e) {
                                logger.error(e.getMessage(), e);
                                return ConsumeConcurrentlyStatus.RECONSUME_LATER;
                            }
                        } else {
                            // 如果没有return success, consumer会重新消费该消息, 直到return success
                            return ConsumeConcurrentlyStatus.RECONSUME_LATER;
                        }
                    }
                    // 如果没有return success, consumer会重新消费该消息, 直到return success
                    return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
                }
                return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
            }
        });

        // Consumer对象在使用之前必须要调用start初始化, 初始化一次即可
        defaultMQPushConsumer.start();
        logger.info("///ConsumerGroup: {}, Topic: {}, SubExpression: {} started!", mqCfg.getConsumerGroup(), mqCfg.getTopic(), mqCfg.getSubExpression());
    }

    protected abstract void consume(MessageExt msg, ConsumeConcurrentlyContext context) throws Exception;

    protected abstract MQConfig getMQConfig();
}

二、实际消费者示例:

@Component
public class ActualConsumer extends Consumer {

    @Resource
    private CustomService customService;

    @Override
    protected void consume(MessageExt msg, ConsumeConcurrentlyContext context) {
        EntityDTO entityDTO = null;
        try {
            entityDTO = JSON.parseObject(new String(msg.getBody()), EntityDTO.class);
            customService.doSomething(entityDTO);
        } catch (Exception e) {
            logger.error("doSomething fail, the body: {}", entityDTO == null ? null : entityDTO.toString());
        }
    }

    @Override
    protected MQConfig getMQConfig() {
        return MQUtil.getMQConfig(CustomerMQCfg.CUSTOMER_PARAM.getGroup(), CustomerMQCfg.CUSTOMER_PARAM.getTopic());
    }
}

三、工具类:

import org.apache.rocketmq.common.protocol.heartbeat.MessageModel;

public class MQUtil {

    public static MQConfig getMQConfig(String pushMessageGroup, String pushMessageTopic) {
        MQConfig mqCfg = new MQConfig() {
            @Override
            public String getSubExpression() {
                return "*";
            }

            @Override
            public String getConsumerGroup() {
                return pushMessageGroup;
            }

            @Override
            public String getTopic() {
                return pushMessageTopic;
            }

            @Override
            public String getInstanceName() {
                // 也可以使用UUID.randomUUID().toString(),如:return UUID.randomUUID().toString();
                return String.valueOf(System.currentTimeMillis());
            }

            @Override
            public MessageModel getMessageModel() {
                return MessageModel.CLUSTERING;
            }
        };
        return mqCfg;
    }
}

四、配置类:

public enum CustomerMQCfg {

    CUSTOMER_PARAM("CUSTOMER_GROUP", "CUSTOMER_TOPIC", "CUSTOMER_TAG", "自定义MQ配置信息"),
    // 后续可以继续添加...;

    LogParamMQCfg(String group, String topic, String tag, String remark) {
        this.group = group;
        this.topic = topic;
        this.tag = tag;
        this.remark = remark;
    }

    private String group;
    private String topic;
    private String tag;
    private String remark;

    @Override
    public String getGroup() {
        return group;
    }

    @Override
    public void setGroup(String group) {
        this.group = group;
    }

    @Override
    public String getTopic() {
        return topic;
    }

    @Override
    public void setTopic(String topic) {
        this.topic = topic;
    }

    @Override
    public String getTag() {
        return tag;
    }

    @Override
    public void setTag(String tag) {
        this.tag = tag;
    }

    @Override
    public String getRemark() {
        return remark;
    }

    @Override
    public void setRemark(String remark) {
        this.remark = remark;
    }
}

你可能感兴趣的:(最java)