核心代码:
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