RocketMQ生产者和消费者Demo(二)

核心代码:

package org.example.mq.consumer;

import org.apache.commons.lang3.StringUtils;
import org.apache.rocketmq.acl.common.AclClientRPCHook;
import org.apache.rocketmq.acl.common.SessionCredentials;
import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer;
import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyContext;
import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyStatus;
import org.apache.rocketmq.client.consumer.listener.MessageListenerConcurrently;
import org.apache.rocketmq.client.consumer.rebalance.AllocateMessageQueueAveragely;
import org.apache.rocketmq.client.producer.TransactionListener;
import org.apache.rocketmq.client.producer.TransactionMQProducer;
import org.apache.rocketmq.common.MixAll;
import org.apache.rocketmq.common.consumer.ConsumeFromWhere;
import org.apache.rocketmq.common.message.MessageExt;
import org.apache.rocketmq.remoting.RPCHook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.atomic.AtomicLong;

@Component
@ConditionalOnProperty(name = "ennable.mq", havingValue = "true", matchIfMissing = true)
public class NewClientFactory {
    private static Map<String, Object> producerBusinessExecutor;

    @Autowired(required = false)
    private Map<String, ConsumerBusinessExecutor> consumerBusinessExecutorMap;

    private static List<TransactionMQProducer> transactionMQProducers = new ArrayList();

    private static List<DefaultMQPushConsumer> defaultMQPushConsumers = new ArrayList();
    private static AtomicLong getWitchProducer = new AtomicLong(0L);
    private static Logger logger = LoggerFactory.getLogger(NewClientFactory.class);
    private static boolean isInit = false;

    public NewClientFactory() {
    }

    public static TransactionMQProducer getTransactionMQProducer() {
        if (isInit) {
            if (transactionMQProducers.size() == 1) {
                return (TransactionMQProducer) transactionMQProducers.get(0);
            } else {
                long index = getWitchProducer.getAndIncrement();
                return (TransactionMQProducer) transactionMQProducers.get((int) (index % (long) transactionMQProducers.size()));
            }
        } else {
            logger.error("MQ 客户端未初始化,无法获取生产者");
            throw new RuntimeException("MQ 客户端未初始化,无法获取生产者");
        }
    }

    @PostConstruct
    private void init() throws Exception {
        hookBeforeInit();
        if (!isInit) {
            initProducter();
            Thread thread = new Thread(new Runnable() {
                public void run() {
                    try {
                        int delayStartMills = Integer.valueOf(Property.getProperty("consumerStartDelay", "60000"));
                        Thread.sleep((long) delayStartMills);
                        NewClientFactory.logger.info("延迟启动消费者 the delayStartMills is {}", delayStartMills);
                        delayStart();
                    } catch (Exception var2) {
                        NewClientFactory.logger.error("mq  delayStart 异常", var2);
                    }

                }
            });
            thread.start();
            isInit = true;
        } else {
            logger.error("MQ客户端已初始化,不能重复初始化");
            throw new RuntimeException("MQ客户端已初始化,不能重复初始化");
        }
    }

    private void delayStart() throws Exception {
        initConsumer();
    }

    private static void hookBeforeInit() {
        String systemName = Property.getProperty("systemName");
        if (StringUtils.isBlank(systemName)) {
            logger.error("systemName is null");
            throw new RuntimeException("systemName is null");
        } else {
            String namesrvAddr = Property.getProperty("new-namesrvAddr");
            if (StringUtils.isBlank(namesrvAddr)) {
                logger.error("new-namesrvAddr is null");
                throw new RuntimeException("new-namesrvAddr is null");
            }
        }
    }

    private static void initProducter() throws Exception {
        int producerCount = Integer.valueOf(Property.getProperty("producerCount", "1"));
        String systemName = Property.getProperty("systemName");
        if (systemName.contains(",")) {
            systemName = systemName.substring(0, systemName.indexOf(","));
        }

        RPCHook aclRPCHook = getAclRPCHook();

        for (int index = 1; index <= producerCount; ++index) {
            TransactionMQProducer producer;
            if (aclRPCHook != null) {
                logger.info("客户端发现acl配置,客户端启用acl!如若不生效,请检查broker是否开启acl!");
                producer = new TransactionMQProducer(systemName, aclRPCHook);
            } else {
                producer = new TransactionMQProducer(systemName);
            }

            setProductProperty(producer, systemName);
            TransactionListener transactionListener = new TransactionListenerImpl();
            producer.setTransactionListener(transactionListener);
            producer.start();
            transactionMQProducers.add(producer);
        }

    }

    private void initConsumer() throws Exception {
        if (CollectionUtils.isEmpty(consumerBusinessExecutorMap)) {
            logger.info("未注册消费者订阅关系 . consumerBusinessExecutorMap is null.");
        } else {
            String[] consumerNames = Property.getProperty("systemName").split(",");
            boolean isMultiConsumer = consumerNames.length > 1;
            RPCHook aclRPCHook = getAclRPCHook();

            for (int i = 0; i < consumerNames.length; ++i) {
                final String consumerName = consumerNames[i];
                DefaultMQPushConsumer consumer;
                if (aclRPCHook != null) {
                    consumer = new DefaultMQPushConsumer(consumerName, aclRPCHook, new AllocateMessageQueueAveragely());
                } else {
                    consumer = new DefaultMQPushConsumer(consumerName);
                }

                setConsumerProperty(consumerName, consumer, isMultiConsumer);
                Set<String> topics = null;
                if (isMultiConsumer) {
                    String[] topicArray = Property.getProperty(consumerName + ".topics").split(",");
                    topics = new HashSet(Arrays.asList(topicArray));
                } else {
                    topics = consumerBusinessExecutorMap.keySet();
                }

                Iterator var9 = ((Set) topics).iterator();

                while (var9.hasNext()) {
                    String topic = (String) var9.next();
                    consumer.subscribe(topic, "*");
                }

                consumer.registerMessageListener(new MessageListenerConcurrently() {
                    public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs, ConsumeConcurrentlyContext context) {
                        long startTime = System.currentTimeMillis();
                        String flowNo = "";
                        boolean var18 = false;
                        ConsumeConcurrentlyStatus var10;
                        long endTime;
                        label75:
                        {
                            label74:
                            {
                                label73:
                                {
                                    ConsumeConcurrentlyStatus var7;
                                    try {
                                        var18 = true;
                                        MessageExt messageExt = (MessageExt) msgs.get(0);
                                        MessageReq messageReq = new MessageReq();
                                        messageReq.setTopic(messageExt.getTopic());
                                        messageReq.setKey(messageExt.getKeys());
                                        messageReq.setBody(new String(messageExt.getBody()));
                                        flowNo = messageExt.getMsgId();
                                        NewClientFactory.logger.info("[MQ-BEIGN][流水号:{}][消息Message:consumer={},topic={},key={},body={},queue={}].", new Object[]{flowNo, consumerName, messageReq.getTopic(), "DS_AUTO_" + messageReq.getKey(), "DS_AUTO_" + messageReq.getBody(), messageExt.getQueueId()});
                                        ConsumerBusinessExecutor consumerBusinessExecutor = (ConsumerBusinessExecutor) consumerBusinessExecutorMap.get(((MessageExt) msgs.get(0)).getTopic());
                                        ConsumerBussnessExecuteResult consumerBussnessExecuteResult = consumerBusinessExecutor.execute(messageReq);
                                        if (consumerBussnessExecuteResult == ConsumerBussnessExecuteResult.SUCCESS) {
                                            NewClientFactory.logger.info("消费者业务执行器返回结果 {} ", ConsumerBussnessExecuteResult.SUCCESS);
                                            var10 = ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
                                            var18 = false;
                                            break label75;
                                        }

                                        if (consumerBussnessExecuteResult == ConsumerBussnessExecuteResult.FAIL) {
                                            NewClientFactory.logger.info("消费者业务执行器返回结果 {} ", ConsumerBussnessExecuteResult.FAIL);
                                            var10 = ConsumeConcurrentlyStatus.RECONSUME_LATER;
                                            var18 = false;
                                            break label74;
                                        }

                                        NewClientFactory.logger.error("消费者业务执行器返回结果 null,当消费失败处理");
                                        var10 = ConsumeConcurrentlyStatus.RECONSUME_LATER;
                                        var18 = false;
                                        break label73;
                                    } catch (Exception var19) {
                                        NewClientFactory.logger.error("消费者业务执行器执行异常,当消费失败处理", var19);
                                        var7 = ConsumeConcurrentlyStatus.RECONSUME_LATER;
                                        var18 = false;
                                    } finally {
                                        if (var18) {
                                            long endTimexx = System.currentTimeMillis();
                                            NewClientFactory.logger.info("[MQ-END][流水号:{}][耗时: time={} ms].", flowNo, endTimexx - startTime);
                                        }
                                    }

                                    long endTimex = System.currentTimeMillis();
                                    NewClientFactory.logger.info("[MQ-END][流水号:{}][耗时: time={} ms].", flowNo, endTimex - startTime);
                                    return var7;
                                }

                                endTime = System.currentTimeMillis();
                                NewClientFactory.logger.info("[MQ-END][流水号:{}][耗时: time={} ms].", flowNo, endTime - startTime);
                                return var10;
                            }

                            endTime = System.currentTimeMillis();
                            NewClientFactory.logger.info("[MQ-END][流水号:{}][耗时: time={} ms].", flowNo, endTime - startTime);
                            return var10;
                        }

                        endTime = System.currentTimeMillis();
                        NewClientFactory.logger.info("[MQ-END][流水号:{}][耗时: time={} ms].", flowNo, endTime - startTime);
                        return var10;
                    }
                });
                consumer.start();
                defaultMQPushConsumers.add(consumer);
            }

        }
    }

    public static RPCHook getAclRPCHook() throws IOException {
        String aclAccessKey = Property.getProperty("aclAccessKey", (String) null);
        String aclSecretKey = Property.getProperty("aclSecretKey", (String) null);
        String securityToken = Property.getProperty("securityToken", (String) null);
        if (StringUtils.isNotBlank(aclAccessKey) && StringUtils.isNotBlank(aclSecretKey) && StringUtils.isNotBlank(securityToken)) {
            return new AclClientRPCHook(new SessionCredentials(aclAccessKey, aclSecretKey, securityToken));
        } else if (StringUtils.isNotBlank(aclAccessKey) && StringUtils.isNotBlank(aclSecretKey)) {
            return new AclClientRPCHook(new SessionCredentials(aclAccessKey, aclSecretKey));
        } else {
            return MixAll.file2String(SessionCredentials.KEY_FILE) != null ? new AclClientRPCHook(new SessionCredentials(aclAccessKey, aclSecretKey)) : null;
        }
    }

    private static void setProductProperty(TransactionMQProducer producer, String systemName) {
        producer.setInstanceName(systemName);
        producer.setNamesrvAddr(Property.getProperty("new-namesrvAddr"));
        producer.setSendMsgTimeout(Integer.valueOf(Property.getProperty("sendMsgTimeout", "3000")));
        producer.setCompressMsgBodyOverHowmuch(Integer.valueOf(Property.getProperty("compressMsgBodyOverHowmuch", "4096")));
        producer.setRetryTimesWhenSendFailed(Integer.valueOf(Property.getProperty("retryTimesWhenSendFailed", "2")));
        producer.setRetryAnotherBrokerWhenNotStoreOK(Boolean.valueOf(Property.getProperty("retryAnotherBrokerWhenNotStoreOK", "false")));
        producer.setMaxMessageSize(Integer.valueOf(Property.getProperty("maxMessageSize", "131072")));
    }

    private static void setConsumerProperty(String consumerName, DefaultMQPushConsumer consumer, boolean isMultiConsumer) {
        consumer.setInstanceName(consumerName);
        consumer.setNamesrvAddr(Property.getProperty("new-namesrvAddr"));
        String needConsumeBeforeMuchMsg = Property.getProperty("needConsumeBeforeMuchMsg", "false");
        if (StringUtils.isNotBlank(needConsumeBeforeMuchMsg) && needConsumeBeforeMuchMsg.equals("true")) {
            String consumeTimestamp = Property.getProperty("consumeTimestamp");
            if (StringUtils.isNotBlank(consumeTimestamp)) {
                consumer.setConsumeFromWhere(ConsumeFromWhere.CONSUME_FROM_TIMESTAMP);
                consumer.setConsumeTimestamp(consumeTimestamp);
            }
        }

        consumer.setConsumeThreadMin(Integer.valueOf(Property.getConsumerProperty(consumerName, "consumeThreadMin", "20")));
        consumer.setConsumeThreadMax(Integer.valueOf(Property.getConsumerProperty(consumerName, "consumeThreadMax", "64")));
        consumer.setAdjustThreadPoolNumsThreshold((long) Integer.valueOf(Property.getConsumerProperty(consumerName, "adjustThreadPoolNumsThreshold", "100000")));
        consumer.setConsumeConcurrentlyMaxSpan(Integer.valueOf(Property.getProperty("consumeConcurrentlyMaxSpan", "2000")));
        consumer.setPullThresholdForQueue(Integer.valueOf(Property.getProperty("pullThresholdForQueue", "1000")));
        consumer.setPullInterval((long) Integer.valueOf(Property.getProperty("pullInterval", "0")));
        consumer.setPullBatchSize(Integer.valueOf(Property.getProperty("pullBatchSize", "32")));
    }


    @PreDestroy
    private void shutdown() {
        if (!isInit) {
            logger.error("MQ客户端未初始化,不能关闭相关资源");
            throw new RuntimeException("MQ客户端未初始化,不能关闭相关资源");
        } else {
            Iterator var0 = transactionMQProducers.iterator();

            while (var0.hasNext()) {
                TransactionMQProducer transactionMQProducer = (TransactionMQProducer) var0.next();
                transactionMQProducer.shutdown();
            }

            var0 = defaultMQPushConsumers.iterator();

            while (var0.hasNext()) {
                DefaultMQPushConsumer defaultMQPushConsumer = (DefaultMQPushConsumer) var0.next();
                defaultMQPushConsumer.shutdown();
            }

        }
    }

    public static Map<String, Object> getBusinessExecuteResultQueryMap() {
        return producerBusinessExecutor;
    }

    public static void setBusinessExecuteResultQueryMap(Map<String, Object> businessExecuteResultQueryMap) {
        producerBusinessExecutor = businessExecuteResultQueryMap;
    }

   /* public static Map<String, ConsumerBusinessExecutor> getConsumerBusinessExecutorMap() {
        return consumerBusinessExecutorMap;
    }

    public static void setConsumerBusinessExecutorMap(Map<String, ConsumerBusinessExecutor> consumerBusinessExecutorMap) {
        NewClientFactory.consumerBusinessExecutorMap = consumerBusinessExecutorMap;
    }*/

    public static List<TransactionMQProducer> getTransactionMQProducers() {
        return transactionMQProducers;
    }

    public static void setTransactionMQProducers(List<TransactionMQProducer> transactionMQProducers) {
        NewClientFactory.transactionMQProducers = transactionMQProducers;
    }
}

生产者:

public interface BusinessExecuteResultQuery {
    ProducerBussnessExecuteResult queryBussnessExecuteResult(MessageReq var1);
}


public interface ProducerBusinessExecutor extends BusinessExecuteResultQuery {
    ProducerBussnessExecuteResult exeBusiness(Object var1);
}

public enum ProducerBussnessExecuteResult {
    SUCCESS("1", "成功"),
    FAIL("2", "失败");

    private String code;
    private String desc;

    private ProducerBussnessExecuteResult(String code, String desc) {
        this.code = code;
        this.desc = desc;
    }

    public String getCode() {
        return this.code;
    }

    public String getDesc() {
        return this.desc;
    }
}

public class MessageUtil {
    public MessageUtil() {
    }

    public static void validateMessageReq(MessageReq messageReq) {
        if (messageReq == null) {
            throw new RuntimeException("MessageReq is null");
        } else if (StringUtils.isBlank(messageReq.getTopic())) {
            throw new RuntimeException("Topic is null");
        } else if (StringUtils.isBlank(messageReq.getBody())) {
            throw new RuntimeException("Body is null");
        } else if (StringUtils.isBlank(messageReq.getKey())) {
            throw new RuntimeException("key is null");
        }
    }
}



public enum MessageSendResult {
    SUCCESS("1", "成功"),
    FAIL("2", "失败"),
    UNKOWN("3", "结果未知");

    private String code;
    private String desc;

    private MessageSendResult(String code, String desc) {
        this.code = code;
        this.desc = desc;
    }

    public String getCode() {
        return this.code;
    }

    public String getDesc() {
        return this.desc;
    }
}



package org.example.mq.producer;

import java.io.Serializable;
import org.apache.rocketmq.client.producer.SendStatus;
import org.apache.rocketmq.common.message.MessageQueue;

public class MessageResponseNew implements Serializable {
    private static final long serialVersionUID = 1L;
    private MessageSendResult messageSendResult;
    private SendStatus sendStatus;
    private String msgId;
    private MessageQueue messageQueue;
    private long queueOffset;
    private String transactionId;

    public MessageResponseNew() {
    }

    public MessageSendResult getMessageSendResult() {
        return this.messageSendResult;
    }

    public void setMessageSendResult(MessageSendResult messageSendResult) {
        this.messageSendResult = messageSendResult;
    }

    public SendStatus getSendStatus() {
        return this.sendStatus;
    }

    public void setSendStatus(SendStatus sendStatus) {
        this.sendStatus = sendStatus;
    }

    public String getMsgId() {
        return this.msgId;
    }

    public void setMsgId(String msgId) {
        this.msgId = msgId;
    }

    public MessageQueue getMessageQueue() {
        return this.messageQueue;
    }

    public void setMessageQueue(MessageQueue messageQueue) {
        this.messageQueue = messageQueue;
    }

    public long getQueueOffset() {
        return this.queueOffset;
    }

    public void setQueueOffset(long queueOffset) {
        this.queueOffset = queueOffset;
    }

    public String getTransactionId() {
        return this.transactionId;
    }

    public void setTransactionId(String transactionId) {
        this.transactionId = transactionId;
    }

    public String toString() {
        return "MessageResponseNew [messageSendResult=" + this.messageSendResult + ", sendStatus=" + this.sendStatus + ", msgId=" + this.msgId + ", messageQueue=" + this.messageQueue + ", queueOffset=" + this.queueOffset + ", transactionId=" + this.transactionId + "]";
    }
}

package org.example.mq.producer;

import org.apache.rocketmq.client.producer.LocalTransactionState;
import org.apache.rocketmq.client.producer.SendResult;
import org.apache.rocketmq.client.producer.TransactionMQProducer;
import org.apache.rocketmq.client.producer.TransactionSendResult;
import org.apache.rocketmq.common.message.Message;
import org.example.mq.consumer.MessageReq;
import org.example.mq.consumer.NewClientFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class NewMessageProducer {
    private static Logger logger = LoggerFactory.getLogger(NewMessageProducer.class);

    public NewMessageProducer() {
    }

    public static MessageResponseNew sendMsg(MessageReq messageReq) {
        long startTime = System.currentTimeMillis();
        boolean var14 = false;

        MessageResponseNew var6;
        label36:
        {
            MessageResponseNew var4;
            try {
                var14 = true;
                logger.info("[MQ-SEND-BEIGN][发送普通消息MessageReq:topic={},key={},body={},delayLevel={}].", new Object[]{messageReq.getTopic(), "DS_AUTO_" + messageReq.getKey(), "DS_AUTO_" + messageReq.getBody(), messageReq.getDelayLevel()});
                MessageUtil.validateMessageReq(messageReq);
                Message msg = new Message();
                msg.setTopic(messageReq.getTopic());
                msg.setBody(messageReq.getBody().getBytes());
                msg.setKeys(messageReq.getKey());
                msg.setDelayTimeLevel(messageReq.getDelayLevel());
                TransactionMQProducer transactionMQProducer = NewClientFactory.getTransactionMQProducer();
                SendResult SendResult = transactionMQProducer.send(msg);
                logger.info("发送普通消息结束 。 SendResult is {}", SendResult);
                var6 = buildMsgResponse(MessageSendResult.SUCCESS, SendResult);
                var14 = false;
                break label36;
            } catch (Exception var15) {
                logger.error("发送普通消息异常", var15);
                var4 = buildMsgResponse(MessageSendResult.UNKOWN, (SendResult) null);
                var14 = false;
            } finally {
                if (var14) {
                    long endTime = System.currentTimeMillis();
                    logger.info("[MQ-SEND-END][发送普通消息耗时: time={} ms].", endTime - startTime);
                }
            }

            long endTime = System.currentTimeMillis();
            logger.info("[MQ-SEND-END][发送普通消息耗时: time={} ms].", endTime - startTime);
            return var4;
        }

        long endTime = System.currentTimeMillis();
        logger.info("[MQ-SEND-END][发送普通消息耗时: time={} ms].", endTime - startTime);
        return var6;
    }

    private static MessageResponseNew buildMsgResponse(MessageSendResult messageSendResult, SendResult sendResult) {
        MessageResponseNew messageResponse = new MessageResponseNew();
        messageResponse.setMessageSendResult(messageSendResult);
        if (sendResult != null) {
            messageResponse.setMessageQueue(sendResult.getMessageQueue());
            messageResponse.setSendStatus(sendResult.getSendStatus());
            messageResponse.setMsgId(sendResult.getMsgId());
            messageResponse.setQueueOffset(sendResult.getQueueOffset());
            messageResponse.setTransactionId(sendResult.getTransactionId());
        }

        return messageResponse;
    }

    public static MessageResponseNew sendTranMsg(MessageReq messageReq, ProducerBusinessExecutor producerBusinessExecutor, Object businessArgs) {
        long startTime = System.currentTimeMillis();
        boolean var16 = false;

        MessageResponseNew var8;
        long endTime;
        label83:
        {
            label82:
            {
                label81:
                {
                    MessageResponseNew var6;
                    try {
                        var16 = true;
                        logger.info("[MQ-SEND-BEIGN][发送事务消息MessageReq:topic={},key={},body={},delayLevel={},producerBusinessExecutor={},businessArgs={}].", new Object[]{messageReq.getTopic(), "DS_AUTO_" + messageReq.getKey(), "DS_AUTO_" + messageReq.getBody(), messageReq.getDelayLevel(), producerBusinessExecutor, businessArgs});
                        MessageUtil.validateMessageReq(messageReq);
                        if (null == NewClientFactory.getBusinessExecuteResultQueryMap().get(messageReq.getTopic())) {
                            NewClientFactory.getBusinessExecuteResultQueryMap().put(messageReq.getTopic(), producerBusinessExecutor);
                        }

                        TransactionMQProducer transactionMQProducer = NewClientFactory.getTransactionMQProducer();
                        Message msg = new Message();
                        msg.setTopic(messageReq.getTopic());
                        msg.setBody(messageReq.getBody().getBytes());
                        msg.setKeys(messageReq.getKey());
                        TransactionSendResult transactionSendResult = transactionMQProducer.sendMessageInTransaction(msg, businessArgs);
                        logger.info("发送事务消息结束, the TransactionSendResult is {} ", transactionSendResult);
                        if (transactionSendResult.getLocalTransactionState() == LocalTransactionState.COMMIT_MESSAGE) {
                            var8 = buildMsgResponse(MessageSendResult.SUCCESS, transactionSendResult);
                            var16 = false;
                            break label83;
                        }

                        if (transactionSendResult.getLocalTransactionState() == LocalTransactionState.ROLLBACK_MESSAGE) {
                            var8 = buildMsgResponse(MessageSendResult.FAIL, transactionSendResult);
                            var16 = false;
                            break label82;
                        }

                        var8 = buildMsgResponse(MessageSendResult.UNKOWN, transactionSendResult);
                        var16 = false;
                        break label81;
                    } catch (Exception var17) {
                        logger.error("发送事务消息异常", var17);
                        var6 = buildMsgResponse(MessageSendResult.UNKOWN, (SendResult) null);
                        var16 = false;
                    } finally {
                        if (var16) {
                            endTime = System.currentTimeMillis();
                            logger.info("[MQ-SEND-END][发送事务消息耗时: time={} ms].", endTime - startTime);
                        }
                    }

                    endTime = System.currentTimeMillis();
                    logger.info("[MQ-SEND-END][发送事务消息耗时: time={} ms].", endTime - startTime);
                    return var6;
                }

                endTime = System.currentTimeMillis();
                logger.info("[MQ-SEND-END][发送事务消息耗时: time={} ms].", endTime - startTime);
                return var8;
            }

            endTime = System.currentTimeMillis();
            logger.info("[MQ-SEND-END][发送事务消息耗时: time={} ms].", endTime - startTime);
            return var8;
        }

        endTime = System.currentTimeMillis();
        logger.info("[MQ-SEND-END][发送事务消息耗时: time={} ms].", endTime - startTime);
        return var8;
    }
}
package org.example.mq.producer;

import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.example.mq.consumer.MessageReq;
import org.example.mq.thread.ThreadPoolFactory;

import java.util.UUID;

/**
 * Description: 异步发送MQ
 */
@Slf4j
public class MQUtil {

    /**
     * 发送简表数据表更消息
     *
     * @param message 变更对象
     */
    public static void sendSimpleTableChangeMqAsyn(final Object message, String topic) {
        final String messageBody = JSON.toJSONString(message);
        ThreadPoolFactory.getSendSimpleMQThreadPool().execute(() -> {
            try {
                String key = UUID.randomUUID().toString().replaceAll("-", "");
                MessageReq messageReq = new MessageReq();
                messageReq.setTopic(topic);
                messageReq.setKey(key);
                messageReq.setDelayLevel(2);
                messageReq.setBody(messageBody);
                MessageResponseNew messageResponseNew = NewMessageProducer.sendMsg(messageReq);
                log.info("发送消息{},{}结果:{}", key, messageReq.getBody(), messageResponseNew);
            } catch (RuntimeException e) {
                log.error("发送消息异常:{}", JSON.toJSONString(message));
                log.error("异常堆栈:", e);
            }
        });
    }


    public static void sendSimpleTableChangeMqSyn(final Object message, String topic) {
        final String messageBody = JSON.toJSONString(message);
        try {
            String key = UUID.randomUUID().toString().replaceAll("-", "");
            MessageReq messageReq = new MessageReq();
            messageReq.setTopic(topic);
            messageReq.setKey(key);
            messageReq.setDelayLevel(2);
            messageReq.setBody(messageBody);
            MessageResponseNew messageResponseNew = NewMessageProducer.sendMsg(messageReq);
            log.info("发送消息{},{}结果:{}", key, messageReq.getBody(), messageResponseNew);
        } catch (RuntimeException e) {
            log.error("发送消息异常:{}", JSON.toJSONString(message));
            log.error("异常堆栈:", e);
        }
    }


}

消费者:

package org.example.mq.consumer;

import java.io.Serializable;

public class MessageReq implements Serializable {
    private static final long serialVersionUID = 6688303791360711053L;
    private String topic;
    private String key;
    private String tags;
    private String body;
    private int delayLevel;

    public MessageReq() {
    }

    public String getTopic() {
        return this.topic;
    }

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

    public String getKey() {
        return this.key;
    }

    public String getBody() {
        return this.body;
    }

    public void setKey(String key) {
        this.key = key;
    }

    public void setBody(String body) {
        this.body = body;
    }

    public String getTags() {
        return this.tags;
    }

    public void setTags(String tags) {
        this.tags = tags;
    }

    public int getDelayLevel() {
        return this.delayLevel;
    }

    public void setDelayLevel(int delayLevel) {
        this.delayLevel = delayLevel;
    }

    public String toString() {
        return "MessageReq [topic=" + this.topic + ", tags=" + this.tags + ", key=" + this.key + ", body=***, delayLevel=" + this.delayLevel + "]";
    }
}


public interface ConsumerBusinessExecutor {
    ConsumerBussnessExecuteResult execute(MessageReq var1);
}


import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

@Service("topic_test")
@Slf4j
public class ConsumerBusinessExecutorDemo implements ConsumerBusinessExecutor{
    @Override
    public ConsumerBussnessExecuteResult execute(MessageReq var1) {
        log.info("消费消息:{}", JSON.toJSONString(var1));
        // TODO 这里还可以再根据再做策略分发,如 ConsumerBusinessTagExecutor
        return ConsumerBussnessExecuteResult.SUCCESS;
    }
}


public enum ConsumerBussnessExecuteResult {
    SUCCESS("1", "成功"),
    FAIL("2", "失败");

    private String code;
    private String desc;

    private ConsumerBussnessExecuteResult(String code, String desc) {
        this.code = code;
        this.desc = desc;
    }

    public String getCode() {
        return this.code;
    }

    public String getDesc() {
        return this.desc;
    }
}



package org.example.mq.consumer;

import org.apache.rocketmq.client.producer.LocalTransactionState;
import org.apache.rocketmq.client.producer.TransactionListener;
import org.apache.rocketmq.common.message.Message;
import org.apache.rocketmq.common.message.MessageExt;
import org.example.mq.producer.ProducerBusinessExecutor;
import org.example.mq.producer.ProducerBussnessExecuteResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

@Service
public class TransactionListenerImpl implements TransactionListener {
    private static Logger logger = LoggerFactory.getLogger(TransactionListenerImpl.class);

    public TransactionListenerImpl() {
    }

    public LocalTransactionState executeLocalTransaction(Message message, Object o) {
        try {
            ProducerBusinessExecutor producerBusinessExecutor = (ProducerBusinessExecutor)NewClientFactory.getBusinessExecuteResultQueryMap().get(message.getTopic());
            ProducerBussnessExecuteResult bussnessExecuteResult = producerBusinessExecutor.exeBusiness(o);
            if (bussnessExecuteResult == ProducerBussnessExecuteResult.SUCCESS) {
                logger.info("producer执行本地业务操作返回 {}", ProducerBussnessExecuteResult.SUCCESS);
                return LocalTransactionState.COMMIT_MESSAGE;
            } else if (bussnessExecuteResult == ProducerBussnessExecuteResult.FAIL) {
                logger.error("producer执行本地业务操作返回 {}", ProducerBussnessExecuteResult.FAIL);
                return LocalTransactionState.ROLLBACK_MESSAGE;
            } else {
                logger.error("producer执行本地业务操作返回 null 结果当UNKNOW处理");
                return LocalTransactionState.UNKNOW;
            }
        } catch (Exception var5) {
            logger.error("producer执行本地业务操作异常,结果当UNKNOW处理", var5);
            return LocalTransactionState.UNKNOW;
        }
    }

    public LocalTransactionState checkLocalTransaction(MessageExt messageExt) {
        try {
            MessageReq messageReq = new MessageReq();
            messageReq.setTopic(messageExt.getTopic());
            messageReq.setKey(messageExt.getKeys());
            messageReq.setBody(new String(messageExt.getBody()));
            logger.info("MQ服务端回调检查业务结果开始  the MessageReq is {}", "DS_AUTO_" + messageReq.toString());
            if (CollectionUtils.isEmpty(NewClientFactory.getBusinessExecuteResultQueryMap())) {
                logger.error("MQ服务端回调检查业务结果时,businessExecuteResultQueryMap对象为空");
                return LocalTransactionState.UNKNOW;
            } else {
                ProducerBusinessExecutor producerBusinessExecutor = (ProducerBusinessExecutor)NewClientFactory.getBusinessExecuteResultQueryMap().get(messageExt.getTopic());
                if (producerBusinessExecutor == null) {
                    logger.error("MQ服务端回调检查业务结果时,未获取到回调执行器 the topic is {}", messageExt.getTopic());
                    return LocalTransactionState.UNKNOW;
                } else {
                    ProducerBussnessExecuteResult bussnessExecuteResult = producerBusinessExecutor.queryBussnessExecuteResult(messageReq);
                    if (ProducerBussnessExecuteResult.SUCCESS == bussnessExecuteResult) {
                        logger.info("the 业务执行结果查询器返回结果为 {}", ProducerBussnessExecuteResult.SUCCESS);
                        return LocalTransactionState.COMMIT_MESSAGE;
                    } else if (ProducerBussnessExecuteResult.FAIL == bussnessExecuteResult) {
                        logger.info("业务执行结果查询器返回结果为 {}", ProducerBussnessExecuteResult.FAIL);
                        return LocalTransactionState.ROLLBACK_MESSAGE;
                    } else {
                        logger.error("业务执行结果查询器返回结果为 null ,当UNKNOW 处理");
                        return LocalTransactionState.UNKNOW;
                    }
                }
            }
        } catch (Exception var5) {
            logger.error("获取业务执行结果异常,当UNKNOW处理", var5);
            return LocalTransactionState.UNKNOW;
        }
    }
}

工具类:

package org.example.mq.consumer;

import org.apache.commons.lang3.StringUtils;

import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

public class Property {

    private static String filename = "application.properties";
    private static Properties property = null;
    static {
        if(null == property){
            property = new Properties();
            InputStream is = null;
            try{
                is = Property.class.getClassLoader().getResourceAsStream(filename);
                property.load(is);
            }catch (Exception e){
                e.printStackTrace();
            }finally {
                try {
                    if(is != null){
                        is.close();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 获取配置文件
     * @param key
     * @return
     */
    public static String getProperty(String key){
        return property.getProperty(key);
    }

    /**
     * 获取配置文件,并设置默认值
     * @param key
     * @param defaultValue
     * @return
     */
    public static String getProperty(String key, String defaultValue) {
        return property.getProperty(key, defaultValue);
    }


    public static String getConsumerProperty(String consumer, String property, String defaultValue) {
        String consumerProperty = Property.getProperty(consumer + "." + property);
        return StringUtils.isNotEmpty(consumerProperty) ? consumerProperty : Property.getProperty(property, defaultValue);
    }

}
package org.example.mq.thread;

import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/**
 * Description: 线程池工厂
 *
 */
@Slf4j
public class ThreadPoolFactory {

    /**
     * 发送普通MQ线程池
     */
    private static ThreadPoolProxy sendSimpleChangedMQThreadPool = new ThreadPoolProxy(8, "sendSimpleChangedMQ");


    static {
        ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(1);
        scheduledExecutorService.scheduleAtFixedRate(() -> {
            log.info("ThreadPoolFactory 线程池队列监控开始");
            log.info("发送普通MQ线程池队列堵塞:{}", getSendSimpleMQThreadPool().getBlockSize());
            log.info("ThreadPoolFactory 线程池队列监控结束");
        }, 10L, 20L, TimeUnit.SECONDS);
    }

    /**
     * 发送普通MQ线程池
     *
     * @return 线程池
     */
    public static ThreadPoolProxy getSendSimpleMQThreadPool() {
        if (sendSimpleChangedMQThreadPool == null) {
            synchronized (ThreadPoolProxy.class) {
                if (sendSimpleChangedMQThreadPool == null) {
                    sendSimpleChangedMQThreadPool = new ThreadPoolProxy(10, "sendSimpleChangedMQ");
                }
            }
        }
        return sendSimpleChangedMQThreadPool;
    }
}
package org.example.mq.thread;

import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * Description: 线程池代理
 */
@Slf4j
public class ThreadPoolProxy {

    private ThreadPoolExecutor threadPoolExecutor;
    private int                corePoolSize;
    private String             threadPoolNamePrefix;

    /**
     * 构造函数
     *
     * @param corePoolSize 核心线程数
     */
    public ThreadPoolProxy(int corePoolSize, String threadPoolNamePrefix) {
        this.corePoolSize = corePoolSize;
        this.threadPoolNamePrefix = threadPoolNamePrefix;
    }

    /**
     * 初始化线程池
     * 双重检查加锁
     */
    private void initThreadPoolExecutor() {
        if (threadPoolExecutor == null) {
            synchronized (ThreadPoolProxy.class) {
                if (threadPoolExecutor == null) {
                    BlockingQueue<Runnable> workQueue = new LinkedBlockingQueue<>();
                    ThreadFactory threadFactory = new TigerThreadFactory(threadPoolNamePrefix);
                    RejectedExecutionHandler handler = new ThreadPoolExecutor.AbortPolicy();
                    this.threadPoolExecutor = new ThreadPoolExecutor(corePoolSize, Integer.MAX_VALUE, 60,
                                                                     TimeUnit.SECONDS, workQueue, threadFactory,
                                                                     handler);
                }
            }
        }
    }

    /**
     * 执行任务
     */
    public void execute(Runnable task) {
        initThreadPoolExecutor();
        threadPoolExecutor.execute(task);
    }

    /**
     * 提交任务
     */
    public Future<?> submit(Callable<?> task) {
        initThreadPoolExecutor();
        return threadPoolExecutor.submit(task);
    }

    /**
     * 提交任务
     */
    public Future<Integer> submitInt(Callable<Integer> task) {
        initThreadPoolExecutor();
        return threadPoolExecutor.submit(task);
    }

    long getBlockSize(){
        initThreadPoolExecutor();
        return threadPoolExecutor.getQueue().size();
    }

    /**
     * 线程工厂
     */
    public static class TigerThreadFactory implements ThreadFactory {

        private final ThreadGroup   group;
        private final AtomicInteger threadNumber = new AtomicInteger(1);
        private final String        namePrefix;

        public TigerThreadFactory(String threadNamePrefix) {
            SecurityManager s = System.getSecurityManager();
            group = (s != null) ? s.getThreadGroup() : Thread.currentThread().getThreadGroup();
            namePrefix = threadNamePrefix + "-threadPool-";
        }

        @Override
        public Thread newThread(Runnable r) {
            Thread t = new Thread(group, r, namePrefix + threadNumber.getAndIncrement(), 0);
            if (t.isDaemon()) {
                t.setDaemon(false);
            }
            if (t.getPriority() != Thread.NORM_PRIORITY) {
                t.setPriority(Thread.NORM_PRIORITY);
            }
            t.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {

                @Override
                public void uncaughtException(Thread t, Throwable e) {
                    log.error("thread:{}===>Exception:{}", t.getName(), e.getMessage());
                    log.error("线程异常:", e);
                    throw new RuntimeException(e);
                }
            });
            return t;
        }
    }
}

测试代码:

@Component
public class Jobs {

    //表示每天8时30分0秒执行
    @Scheduled(cron = "20 * * * * ?")
    public void cronJob() {
        Map map = new HashMap();
        map.put("name","张三");
        map.put("age","25");
        MQUtil.sendSimpleTableChangeMqSyn(map,"topic_test");
    }
}

相关配置:

systemName=demo
new-namesrvAddr : 127.0.0.1:9876

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值