From d943456bcaa8317b8d3ae55f9a1117a5bf8478ed Mon Sep 17 00:00:00 2001
From: Zhouxiang Zhan
Date: Tue, 14 May 2024 10:40:42 +0800
Subject: [PATCH 001/265] Add unit test for MQClientAPIExtTest (#8080)
---
.../impl/mqclient/MQClientAPIExtTest.java | 74 +++++++++++++++++++
1 file changed, 74 insertions(+)
create mode 100644 client/src/test/java/org/apache/rocketmq/client/impl/mqclient/MQClientAPIExtTest.java
diff --git a/client/src/test/java/org/apache/rocketmq/client/impl/mqclient/MQClientAPIExtTest.java b/client/src/test/java/org/apache/rocketmq/client/impl/mqclient/MQClientAPIExtTest.java
new file mode 100644
index 00000000000..752bc98eabd
--- /dev/null
+++ b/client/src/test/java/org/apache/rocketmq/client/impl/mqclient/MQClientAPIExtTest.java
@@ -0,0 +1,74 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.rocketmq.client.impl.mqclient;
+
+import java.util.concurrent.CompletableFuture;
+import org.apache.rocketmq.client.ClientConfig;
+import org.apache.rocketmq.client.producer.SendResult;
+import org.apache.rocketmq.common.message.Message;
+import org.apache.rocketmq.common.utils.FutureUtils;
+import org.apache.rocketmq.remoting.exception.RemotingTimeoutException;
+import org.apache.rocketmq.remoting.netty.NettyClientConfig;
+import org.apache.rocketmq.remoting.netty.NettyRemotingClient;
+import org.apache.rocketmq.remoting.protocol.header.SendMessageRequestHeader;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.junit.MockitoJUnitRunner;
+
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.ArgumentMatchers.anyString;
+
+@RunWith(MockitoJUnitRunner.class)
+public class MQClientAPIExtTest {
+ MQClientAPIExt mqClientAPIExt;
+ @Mock
+ NettyRemotingClient remotingClientMock;
+
+ @Before
+ public void before() {
+ mqClientAPIExt = Mockito.spy(new MQClientAPIExt(new ClientConfig(), new NettyClientConfig(), null, null));
+ Mockito.when(mqClientAPIExt.getRemotingClient()).thenReturn(remotingClientMock);
+ Mockito.when(remotingClientMock.invoke(anyString(), any(), anyLong())).thenReturn(FutureUtils.completeExceptionally(new RemotingTimeoutException("addr")));
+ }
+
+ @Test
+ public void sendMessageAsync() {
+ String topic = "test";
+ Message msg = new Message(topic, "test".getBytes());
+ SendMessageRequestHeader requestHeader = new SendMessageRequestHeader();
+ requestHeader.setTopic(topic);
+ requestHeader.setProducerGroup("test");
+ requestHeader.setDefaultTopic("test");
+ requestHeader.setDefaultTopicQueueNums(1);
+ requestHeader.setQueueId(0);
+ requestHeader.setSysFlag(0);
+ requestHeader.setBornTimestamp(0L);
+ requestHeader.setFlag(0);
+ requestHeader.setProperties("test");
+ requestHeader.setReconsumeTimes(0);
+ requestHeader.setUnitMode(false);
+ requestHeader.setBatch(false);
+ CompletableFuture future = mqClientAPIExt.sendMessageAsync("127.0.0.1:10911", "test", msg, requestHeader, 10);
+ assertThatThrownBy(future::get).getCause().isInstanceOf(RemotingTimeoutException.class);
+ }
+}
\ No newline at end of file
From 502e2d798e57fd4f40d16a90c44679af5ee7f986 Mon Sep 17 00:00:00 2001
From: hiyo <77013030+miles-ton@users.noreply.github.com>
Date: Tue, 14 May 2024 14:45:29 +0800
Subject: [PATCH 002/265] [ISSUE #8118] Remove redundant mod in client (#8119)
---
.../consumer/rebalance/AllocateMessageQueueAveragely.java | 2 +-
.../apache/rocketmq/client/impl/factory/MQClientInstance.java | 3 +--
2 files changed, 2 insertions(+), 3 deletions(-)
diff --git a/client/src/main/java/org/apache/rocketmq/client/consumer/rebalance/AllocateMessageQueueAveragely.java b/client/src/main/java/org/apache/rocketmq/client/consumer/rebalance/AllocateMessageQueueAveragely.java
index 75e5d1c218b..6f63a6fc607 100644
--- a/client/src/main/java/org/apache/rocketmq/client/consumer/rebalance/AllocateMessageQueueAveragely.java
+++ b/client/src/main/java/org/apache/rocketmq/client/consumer/rebalance/AllocateMessageQueueAveragely.java
@@ -42,7 +42,7 @@ public List allocate(String consumerGroup, String currentCID, List
int startIndex = (mod > 0 && index < mod) ? index * averageSize : index * averageSize + mod;
int range = Math.min(averageSize, mqAll.size() - startIndex);
for (int i = 0; i < range; i++) {
- result.add(mqAll.get((startIndex + i) % mqAll.size()));
+ result.add(mqAll.get(startIndex + i));
}
return result;
}
diff --git a/client/src/main/java/org/apache/rocketmq/client/impl/factory/MQClientInstance.java b/client/src/main/java/org/apache/rocketmq/client/impl/factory/MQClientInstance.java
index 227f3346d0d..f964869ac24 100644
--- a/client/src/main/java/org/apache/rocketmq/client/impl/factory/MQClientInstance.java
+++ b/client/src/main/java/org/apache/rocketmq/client/impl/factory/MQClientInstance.java
@@ -1222,8 +1222,7 @@ public String findBrokerAddrByTopic(final String topic) {
if (topicRouteData != null) {
List brokers = topicRouteData.getBrokerDatas();
if (!brokers.isEmpty()) {
- int index = random.nextInt(brokers.size());
- BrokerData bd = brokers.get(index % brokers.size());
+ BrokerData bd = brokers.get(random.nextInt(brokers.size()));
return bd.selectBrokerAddr();
}
}
From 03b16aadce572b3908dc09b99347fcf7e6c6ac7c Mon Sep 17 00:00:00 2001
From: fujian-zfj <2573259572@qq.com>
Date: Tue, 14 May 2024 14:47:37 +0800
Subject: [PATCH 003/265] [ISSUE #8061] Fix npe in netty remoting client
(#8064)
---
.../org/apache/rocketmq/remoting/netty/NettyRemotingClient.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/remoting/src/main/java/org/apache/rocketmq/remoting/netty/NettyRemotingClient.java b/remoting/src/main/java/org/apache/rocketmq/remoting/netty/NettyRemotingClient.java
index ede6005f541..1bc5e57db52 100644
--- a/remoting/src/main/java/org/apache/rocketmq/remoting/netty/NettyRemotingClient.java
+++ b/remoting/src/main/java/org/apache/rocketmq/remoting/netty/NettyRemotingClient.java
@@ -631,7 +631,7 @@ private Channel getAndCreateChannel(final String addr) throws InterruptedExcepti
if (channelFuture == null) {
return null;
}
- return getAndCreateChannelAsync(addr).awaitUninterruptibly().channel();
+ return channelFuture.awaitUninterruptibly().channel();
}
private ChannelFuture getAndCreateNameserverChannelAsync() throws InterruptedException {
From 2fdafd232a45ffd4a72239782248e2d1a91d6abc Mon Sep 17 00:00:00 2001
From: hiyo <77013030+miles-ton@users.noreply.github.com>
Date: Wed, 15 May 2024 10:01:21 +0800
Subject: [PATCH 004/265] [ISSUE #8136] Replace with createProcessQueue and
remove createProcessQueue(topic) in client (#8139)
---
.../apache/rocketmq/client/impl/consumer/RebalanceImpl.java | 4 +---
.../rocketmq/client/impl/consumer/RebalanceLitePullImpl.java | 3 ---
.../rocketmq/client/impl/consumer/RebalancePullImpl.java | 4 ----
.../rocketmq/client/impl/consumer/RebalancePushImpl.java | 5 -----
4 files changed, 1 insertion(+), 15 deletions(-)
diff --git a/client/src/main/java/org/apache/rocketmq/client/impl/consumer/RebalanceImpl.java b/client/src/main/java/org/apache/rocketmq/client/impl/consumer/RebalanceImpl.java
index 53addc5f50c..711df3a9f08 100644
--- a/client/src/main/java/org/apache/rocketmq/client/impl/consumer/RebalanceImpl.java
+++ b/client/src/main/java/org/apache/rocketmq/client/impl/consumer/RebalanceImpl.java
@@ -525,7 +525,7 @@ private boolean updateProcessQueueTableInRebalance(final String topic, final Set
}
this.removeDirtyOffset(mq);
- ProcessQueue pq = createProcessQueue(topic);
+ ProcessQueue pq = createProcessQueue();
pq.setLocked(true);
long nextOffset = this.computePullFromWhere(mq);
if (nextOffset >= 0) {
@@ -779,8 +779,6 @@ public boolean removeUnnecessaryPopMessageQueue(final MessageQueue mq, final Pop
public abstract PopProcessQueue createPopProcessQueue();
- public abstract ProcessQueue createProcessQueue(String topicName);
-
public void removeProcessQueue(final MessageQueue mq) {
ProcessQueue prev = this.processQueueTable.remove(mq);
if (prev != null) {
diff --git a/client/src/main/java/org/apache/rocketmq/client/impl/consumer/RebalanceLitePullImpl.java b/client/src/main/java/org/apache/rocketmq/client/impl/consumer/RebalanceLitePullImpl.java
index 335d89b7877..330772f22bb 100644
--- a/client/src/main/java/org/apache/rocketmq/client/impl/consumer/RebalanceLitePullImpl.java
+++ b/client/src/main/java/org/apache/rocketmq/client/impl/consumer/RebalanceLitePullImpl.java
@@ -177,7 +177,4 @@ public PopProcessQueue createPopProcessQueue() {
return null;
}
- public ProcessQueue createProcessQueue(String topicName) {
- return createProcessQueue();
- }
}
diff --git a/client/src/main/java/org/apache/rocketmq/client/impl/consumer/RebalancePullImpl.java b/client/src/main/java/org/apache/rocketmq/client/impl/consumer/RebalancePullImpl.java
index 1b5f9766174..e0b682868ab 100644
--- a/client/src/main/java/org/apache/rocketmq/client/impl/consumer/RebalancePullImpl.java
+++ b/client/src/main/java/org/apache/rocketmq/client/impl/consumer/RebalancePullImpl.java
@@ -103,8 +103,4 @@ public PopProcessQueue createPopProcessQueue() {
return null;
}
- public ProcessQueue createProcessQueue(String topicName) {
- return createProcessQueue();
- }
-
}
diff --git a/client/src/main/java/org/apache/rocketmq/client/impl/consumer/RebalancePushImpl.java b/client/src/main/java/org/apache/rocketmq/client/impl/consumer/RebalancePushImpl.java
index f28890d306f..59e087c0e04 100644
--- a/client/src/main/java/org/apache/rocketmq/client/impl/consumer/RebalancePushImpl.java
+++ b/client/src/main/java/org/apache/rocketmq/client/impl/consumer/RebalancePushImpl.java
@@ -288,11 +288,6 @@ public ProcessQueue createProcessQueue() {
return new ProcessQueue();
}
- @Override
- public ProcessQueue createProcessQueue(String topicName) {
- return createProcessQueue();
- }
-
@Override
public PopProcessQueue createPopProcessQueue() {
return new PopProcessQueue();
From 8150e13a29f9d5ea7bf8814960389837650164af Mon Sep 17 00:00:00 2001
From: Willhow <65004897+Willhow-Gao@users.noreply.github.com>
Date: Thu, 16 May 2024 09:50:25 +0800
Subject: [PATCH 005/265] [ISSUE #8145] Optimize some code style in client
module (#8146)
---
.../ConsumeMessageOrderlyService.java | 8 ++++--
.../impl/consumer/RebalancePushImpl.java | 4 ---
.../client/impl/factory/MQClientInstance.java | 6 ++--
.../impl/producer/DefaultMQProducerImpl.java | 28 +++++++++----------
.../latency/LatencyFaultToleranceImpl.java | 8 ++++++
.../client/trace/AsyncTraceDispatcher.java | 7 +++--
6 files changed, 34 insertions(+), 27 deletions(-)
diff --git a/client/src/main/java/org/apache/rocketmq/client/impl/consumer/ConsumeMessageOrderlyService.java b/client/src/main/java/org/apache/rocketmq/client/impl/consumer/ConsumeMessageOrderlyService.java
index 36d686048ce..3ca465da70d 100644
--- a/client/src/main/java/org/apache/rocketmq/client/impl/consumer/ConsumeMessageOrderlyService.java
+++ b/client/src/main/java/org/apache/rocketmq/client/impl/consumer/ConsumeMessageOrderlyService.java
@@ -85,6 +85,7 @@ public ConsumeMessageOrderlyService(DefaultMQPushConsumerImpl defaultMQPushConsu
this.scheduledExecutorService = Executors.newSingleThreadScheduledExecutor(new ThreadFactoryImpl("ConsumeMessageScheduledThread_" + consumerGroupTag));
}
+ @Override
public void start() {
if (MessageModel.CLUSTERING.equals(ConsumeMessageOrderlyService.this.defaultMQPushConsumerImpl.messageModel())) {
this.scheduledExecutorService.scheduleAtFixedRate(new Runnable() {
@@ -96,10 +97,11 @@ public void run() {
log.error("scheduleAtFixedRate lockMQPeriodically exception", e);
}
}
- }, 1000 * 1, ProcessQueue.REBALANCE_LOCK_INTERVAL, TimeUnit.MILLISECONDS);
+ }, 1000, ProcessQueue.REBALANCE_LOCK_INTERVAL, TimeUnit.MILLISECONDS);
}
}
+ @Override
public void shutdown(long awaitTerminateMillis) {
this.stopped = true;
this.scheduledExecutorService.shutdown();
@@ -201,8 +203,8 @@ public void submitConsumeRequest(
final List msgs,
final ProcessQueue processQueue,
final MessageQueue messageQueue,
- final boolean dispathToConsume) {
- if (dispathToConsume) {
+ final boolean dispatchToConsume) {
+ if (dispatchToConsume) {
ConsumeRequest consumeRequest = new ConsumeRequest(processQueue, messageQueue);
this.consumeExecutor.submit(consumeRequest);
}
diff --git a/client/src/main/java/org/apache/rocketmq/client/impl/consumer/RebalancePushImpl.java b/client/src/main/java/org/apache/rocketmq/client/impl/consumer/RebalancePushImpl.java
index 59e087c0e04..fe2f19b2f9a 100644
--- a/client/src/main/java/org/apache/rocketmq/client/impl/consumer/RebalancePushImpl.java
+++ b/client/src/main/java/org/apache/rocketmq/client/impl/consumer/RebalancePushImpl.java
@@ -140,10 +140,6 @@ public boolean clientRebalance(String topic) {
return defaultMQPushConsumerImpl.getDefaultMQPushConsumer().isClientRebalance() || defaultMQPushConsumerImpl.isConsumeOrderly() || MessageModel.BROADCASTING.equals(messageModel);
}
- public boolean removeUnnecessaryPopMessageQueue(final MessageQueue mq, final PopProcessQueue pq) {
- return true;
- }
-
@Override
public ConsumeType consumeType() {
return ConsumeType.CONSUME_PASSIVELY;
diff --git a/client/src/main/java/org/apache/rocketmq/client/impl/factory/MQClientInstance.java b/client/src/main/java/org/apache/rocketmq/client/impl/factory/MQClientInstance.java
index f964869ac24..1ff35a00d12 100644
--- a/client/src/main/java/org/apache/rocketmq/client/impl/factory/MQClientInstance.java
+++ b/client/src/main/java/org/apache/rocketmq/client/impl/factory/MQClientInstance.java
@@ -125,8 +125,8 @@ public class MQClientInstance {
private final ConcurrentMap> brokerAddrTable = new ConcurrentHashMap<>();
private final ConcurrentMap> brokerVersionTable = new ConcurrentHashMap<>();
- private final Set brokerSupportV2HeartbeatSet = new HashSet();
- private final ConcurrentMap brokerAddrHeartbeatFingerprintTable = new ConcurrentHashMap();
+ private final Set brokerSupportV2HeartbeatSet = new HashSet<>();
+ private final ConcurrentMap brokerAddrHeartbeatFingerprintTable = new ConcurrentHashMap<>();
private final ScheduledExecutorService scheduledExecutorService = Executors.newSingleThreadScheduledExecutor(r -> new Thread(r, "MQClientFactoryScheduledThread"));
private final ScheduledExecutorService fetchRemoteConfigExecutorService = Executors.newSingleThreadScheduledExecutor(new ThreadFactory() {
@Override
@@ -1161,7 +1161,7 @@ public FindBrokerResult findBrokerAddressInSubscribe(
Entry entry = map.entrySet().iterator().next();
brokerAddr = entry.getValue();
slave = entry.getKey() != MixAll.MASTER_ID;
- found = true;
+ found = brokerAddr != null;
}
}
diff --git a/client/src/main/java/org/apache/rocketmq/client/impl/producer/DefaultMQProducerImpl.java b/client/src/main/java/org/apache/rocketmq/client/impl/producer/DefaultMQProducerImpl.java
index 5b7bd2dc9dc..6268bcc0a17 100644
--- a/client/src/main/java/org/apache/rocketmq/client/impl/producer/DefaultMQProducerImpl.java
+++ b/client/src/main/java/org/apache/rocketmq/client/impl/producer/DefaultMQProducerImpl.java
@@ -570,8 +570,8 @@ public void run() {
}
class BackpressureSendCallBack implements SendCallback {
- public boolean isSemaphoreAsyncSizeAquired = false;
- public boolean isSemaphoreAsyncNumAquired = false;
+ public boolean isSemaphoreAsyncSizeAcquired = false;
+ public boolean isSemaphoreAsyncNumbAcquired = false;
public int msgLen;
private final SendCallback sendCallback;
@@ -581,10 +581,10 @@ public BackpressureSendCallBack(final SendCallback sendCallback) {
@Override
public void onSuccess(SendResult sendResult) {
- if (isSemaphoreAsyncSizeAquired) {
+ if (isSemaphoreAsyncSizeAcquired) {
semaphoreAsyncSendSize.release(msgLen);
}
- if (isSemaphoreAsyncNumAquired) {
+ if (isSemaphoreAsyncNumbAcquired) {
semaphoreAsyncSendNum.release();
}
sendCallback.onSuccess(sendResult);
@@ -592,10 +592,10 @@ public void onSuccess(SendResult sendResult) {
@Override
public void onException(Throwable e) {
- if (isSemaphoreAsyncSizeAquired) {
+ if (isSemaphoreAsyncSizeAcquired) {
semaphoreAsyncSendSize.release(msgLen);
}
- if (isSemaphoreAsyncNumAquired) {
+ if (isSemaphoreAsyncNumbAcquired) {
semaphoreAsyncSendNum.release();
}
sendCallback.onException(e);
@@ -607,31 +607,31 @@ public void executeAsyncMessageSend(Runnable runnable, final Message msg, final
throws MQClientException, InterruptedException {
ExecutorService executor = this.getAsyncSenderExecutor();
boolean isEnableBackpressureForAsyncMode = this.getDefaultMQProducer().isEnableBackpressureForAsyncMode();
- boolean isSemaphoreAsyncNumAquired = false;
- boolean isSemaphoreAsyncSizeAquired = false;
+ boolean isSemaphoreAsyncNumbAcquired = false;
+ boolean isSemaphoreAsyncSizeAcquired = false;
int msgLen = msg.getBody() == null ? 1 : msg.getBody().length;
try {
if (isEnableBackpressureForAsyncMode) {
long costTime = System.currentTimeMillis() - beginStartTime;
- isSemaphoreAsyncNumAquired = timeout - costTime > 0
+ isSemaphoreAsyncNumbAcquired = timeout - costTime > 0
&& semaphoreAsyncSendNum.tryAcquire(timeout - costTime, TimeUnit.MILLISECONDS);
- if (!isSemaphoreAsyncNumAquired) {
+ if (!isSemaphoreAsyncNumbAcquired) {
sendCallback.onException(
new RemotingTooMuchRequestException("send message tryAcquire semaphoreAsyncNum timeout"));
return;
}
costTime = System.currentTimeMillis() - beginStartTime;
- isSemaphoreAsyncSizeAquired = timeout - costTime > 0
+ isSemaphoreAsyncSizeAcquired = timeout - costTime > 0
&& semaphoreAsyncSendSize.tryAcquire(msgLen, timeout - costTime, TimeUnit.MILLISECONDS);
- if (!isSemaphoreAsyncSizeAquired) {
+ if (!isSemaphoreAsyncSizeAcquired) {
sendCallback.onException(
new RemotingTooMuchRequestException("send message tryAcquire semaphoreAsyncSize timeout"));
return;
}
}
- sendCallback.isSemaphoreAsyncSizeAquired = isSemaphoreAsyncSizeAquired;
- sendCallback.isSemaphoreAsyncNumAquired = isSemaphoreAsyncNumAquired;
+ sendCallback.isSemaphoreAsyncSizeAcquired = isSemaphoreAsyncSizeAcquired;
+ sendCallback.isSemaphoreAsyncNumbAcquired = isSemaphoreAsyncNumbAcquired;
sendCallback.msgLen = msgLen;
executor.submit(runnable);
} catch (RejectedExecutionException e) {
diff --git a/client/src/main/java/org/apache/rocketmq/client/latency/LatencyFaultToleranceImpl.java b/client/src/main/java/org/apache/rocketmq/client/latency/LatencyFaultToleranceImpl.java
index f629fe44a87..db8bbd66ef2 100644
--- a/client/src/main/java/org/apache/rocketmq/client/latency/LatencyFaultToleranceImpl.java
+++ b/client/src/main/java/org/apache/rocketmq/client/latency/LatencyFaultToleranceImpl.java
@@ -55,6 +55,7 @@ public LatencyFaultToleranceImpl(Resolver resolver, ServiceDetector serviceDetec
this.serviceDetector = serviceDetector;
}
+ @Override
public void detectByOneRound() {
for (Map.Entry item : this.faultItemTable.entrySet()) {
FaultItem brokerItem = item.getValue();
@@ -77,6 +78,7 @@ public void detectByOneRound() {
}
}
+ @Override
public void startDetector() {
this.scheduledExecutorService.scheduleAtFixedRate(new Runnable() {
@Override
@@ -92,6 +94,7 @@ public void run() {
}, 3, 3, TimeUnit.SECONDS);
}
+ @Override
public void shutdown() {
this.scheduledExecutorService.shutdown();
}
@@ -128,6 +131,7 @@ public boolean isAvailable(final String name) {
return true;
}
+ @Override
public boolean isReachable(final String name) {
final FaultItem faultItem = this.faultItemTable.get(name);
if (faultItem != null) {
@@ -141,10 +145,12 @@ public void remove(final String name) {
this.faultItemTable.remove(name);
}
+ @Override
public boolean isStartDetectorEnable() {
return startDetectorEnable;
}
+ @Override
public void setStartDetectorEnable(boolean startDetectorEnable) {
this.startDetectorEnable = startDetectorEnable;
}
@@ -177,10 +183,12 @@ public String toString() {
'}';
}
+ @Override
public void setDetectTimeout(final int detectTimeout) {
this.detectTimeout = detectTimeout;
}
+ @Override
public void setDetectInterval(final int detectInterval) {
this.detectInterval = detectInterval;
}
diff --git a/client/src/main/java/org/apache/rocketmq/client/trace/AsyncTraceDispatcher.java b/client/src/main/java/org/apache/rocketmq/client/trace/AsyncTraceDispatcher.java
index d44f22616f4..1fe19773a5a 100644
--- a/client/src/main/java/org/apache/rocketmq/client/trace/AsyncTraceDispatcher.java
+++ b/client/src/main/java/org/apache/rocketmq/client/trace/AsyncTraceDispatcher.java
@@ -153,6 +153,7 @@ public void setNamespaceV2(String namespaceV2) {
this.namespaceV2 = namespaceV2;
}
+ @Override
public void start(String nameSrvAddr, AccessChannel accessChannel) throws MQClientException {
if (isStarted.compareAndSet(false, true)) {
traceProducer.setNamesrvAddr(nameSrvAddr);
@@ -330,7 +331,7 @@ class TraceDataSegment {
private int currentMsgKeySize;
private final String traceTopicName;
private final String regionId;
- private final List traceTransferBeanList = new ArrayList();
+ private final List traceTransferBeanList = new ArrayList<>();
TraceDataSegment(String traceTopicName, String regionId) {
this.traceTopicName = traceTopicName;
@@ -345,7 +346,7 @@ public void addTraceTransferBean(TraceTransferBean traceTransferBean) {
this.currentMsgKeySize = traceTransferBean.getTransKey().stream()
.reduce(currentMsgKeySize, (acc, x) -> acc + x.length(), Integer::sum);
if (currentMsgSize >= traceProducer.getMaxMessageSize() - 10 * 1000 || currentMsgKeySize >= MAX_MSG_KEY_SIZE) {
- List dataToSend = new ArrayList(traceTransferBeanList);
+ List dataToSend = new ArrayList<>(traceTransferBeanList);
AsyncDataSendTask asyncDataSendTask = new AsyncDataSendTask(traceTopicName, regionId, dataToSend);
traceExecutor.submit(asyncDataSendTask);
this.clear();
@@ -356,7 +357,7 @@ public void sendAllData() {
if (this.traceTransferBeanList.isEmpty()) {
return;
}
- List dataToSend = new ArrayList(traceTransferBeanList);
+ List dataToSend = new ArrayList<>(traceTransferBeanList);
AsyncDataSendTask asyncDataSendTask = new AsyncDataSendTask(traceTopicName, regionId, dataToSend);
traceExecutor.submit(asyncDataSendTask);
From c00fac3c770c436717f9aad1d5c7bc6591c734b2 Mon Sep 17 00:00:00 2001
From: oopooa <41882826+oopooa@users.noreply.github.com>
Date: Thu, 16 May 2024 09:56:09 +0800
Subject: [PATCH 006/265] [ISSUE #8148] Fix variable typo
---
.../org/apache/rocketmq/broker/BrokerController.java | 2 +-
.../rocketmq/store/stats/BrokerStatsManager.java | 12 ++++++------
2 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/broker/src/main/java/org/apache/rocketmq/broker/BrokerController.java b/broker/src/main/java/org/apache/rocketmq/broker/BrokerController.java
index a9dcc0af1f8..76224db5cb5 100644
--- a/broker/src/main/java/org/apache/rocketmq/broker/BrokerController.java
+++ b/broker/src/main/java/org/apache/rocketmq/broker/BrokerController.java
@@ -408,7 +408,7 @@ public BrokerController(
this.brokerConfig, this.nettyServerConfig, this.nettyClientConfig, this.messageStoreConfig
);
- this.brokerStatsManager.setProduerStateGetter(new BrokerStatsManager.StateGetter() {
+ this.brokerStatsManager.setProducerStateGetter(new BrokerStatsManager.StateGetter() {
@Override
public boolean online(String instanceId, String group, String topic) {
if (getTopicConfigManager().getTopicConfigTable().containsKey(NamespaceUtil.wrapNamespace(instanceId, topic))) {
diff --git a/store/src/main/java/org/apache/rocketmq/store/stats/BrokerStatsManager.java b/store/src/main/java/org/apache/rocketmq/store/stats/BrokerStatsManager.java
index 489d7b4fbce..c165d333fd0 100644
--- a/store/src/main/java/org/apache/rocketmq/store/stats/BrokerStatsManager.java
+++ b/store/src/main/java/org/apache/rocketmq/store/stats/BrokerStatsManager.java
@@ -142,7 +142,7 @@ public class BrokerStatsManager {
private MomentStatsItemSet momentStatsItemSetFallTime;
private final StatisticsManager accountStatManager = new StatisticsManager();
- private StateGetter produerStateGetter;
+ private StateGetter producerStateGetter;
private StateGetter consumerStateGetter;
private BrokerConfig brokerConfig;
@@ -270,7 +270,7 @@ public boolean online(StatisticsItem item) {
String kind = item.getStatKind();
if (ACCOUNT_SEND.equals(kind) || ACCOUNT_SEND_REJ.equals(kind)) {
- return produerStateGetter.online(instanceId, group, topic);
+ return producerStateGetter.online(instanceId, group, topic);
} else if (ACCOUNT_RCV.equals(kind) || ACCOUNT_SEND_BACK.equals(kind) || ACCOUNT_SEND_BACK_TO_DLQ.equals(kind) || ACCOUNT_REV_REJ.equals(kind)) {
return consumerStateGetter.online(instanceId, group, topic);
}
@@ -296,12 +296,12 @@ public MomentStatsItemSet getMomentStatsItemSetFallTime() {
return momentStatsItemSetFallTime;
}
- public StateGetter getProduerStateGetter() {
- return produerStateGetter;
+ public StateGetter getProducerStateGetter() {
+ return producerStateGetter;
}
- public void setProduerStateGetter(StateGetter produerStateGetter) {
- this.produerStateGetter = produerStateGetter;
+ public void setProducerStateGetter(StateGetter producerStateGetter) {
+ this.producerStateGetter = producerStateGetter;
}
public StateGetter getConsumerStateGetter() {
From 9bdc9db9c46873f948fad2bdac5cc14aa1918f57 Mon Sep 17 00:00:00 2001
From: oopooa <41882826+oopooa@users.noreply.github.com>
Date: Fri, 17 May 2024 08:35:23 +0800
Subject: [PATCH 007/265] [ISSUE #8155] Fix doc typo
---
docs/cn/BrokerContainer.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/docs/cn/BrokerContainer.md b/docs/cn/BrokerContainer.md
index 236439284be..a4de9889f27 100644
--- a/docs/cn/BrokerContainer.md
+++ b/docs/cn/BrokerContainer.md
@@ -72,7 +72,7 @@ sh mqbrokercontainer -c broker-container.conf
```
mqbrokercontainer脚本路径为distribution/bin/mqbrokercontainer。
-## 运行时增加或较少Broker
+## 运行时增加或减少Broker
当BrokerContainer进程启动后,也可以通过Admin命令来增加或减少Broker。
From 256217fb6283f8b4c535045682aaef6346be2a87 Mon Sep 17 00:00:00 2001
From: superdev42 <138118491+superdev42@users.noreply.github.com>
Date: Mon, 20 May 2024 09:57:21 +0800
Subject: [PATCH 008/265] [ISSUE#8142] Show time of create topic and
subScriptionGroup (#8143)
* show time of create topic and subScriptionGroup
* show time of create topic and subScriptionGroup again
* show time of create topic and subScriptionGroup changed
---------
Co-authored-by: wengxiaolong <22260113@zju.edu.cn>
---
.../broker/processor/AdminBrokerProcessor.java | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/broker/src/main/java/org/apache/rocketmq/broker/processor/AdminBrokerProcessor.java b/broker/src/main/java/org/apache/rocketmq/broker/processor/AdminBrokerProcessor.java
index 78a5ba92eed..a1a6f5bf6ce 100644
--- a/broker/src/main/java/org/apache/rocketmq/broker/processor/AdminBrokerProcessor.java
+++ b/broker/src/main/java/org/apache/rocketmq/broker/processor/AdminBrokerProcessor.java
@@ -455,6 +455,7 @@ public boolean rejectRequest() {
private synchronized RemotingCommand updateAndCreateTopic(ChannelHandlerContext ctx,
RemotingCommand request) throws RemotingCommandException {
+ long startTime = System.currentTimeMillis();
final RemotingCommand response = RemotingCommand.createResponseCommand(null);
final CreateTopicRequestHeader requestHeader =
(CreateTopicRequestHeader) request.decodeCommandCustomHeader(CreateTopicRequestHeader.class);
@@ -514,8 +515,10 @@ private synchronized RemotingCommand updateAndCreateTopic(ChannelHandlerContext
LOGGER.error("Update / create topic failed for [{}]", request, e);
response.setCode(ResponseCode.SYSTEM_ERROR);
response.setRemark(e.getMessage());
+ return response;
}
-
+ long executionTime = System.currentTimeMillis() - startTime;
+ LOGGER.info("executionTime of create topic:{} is {} ms" , topic, executionTime);
return response;
}
@@ -1450,6 +1453,7 @@ public void onException(Throwable e) {
private RemotingCommand updateAndCreateSubscriptionGroup(ChannelHandlerContext ctx, RemotingCommand request)
throws RemotingCommandException {
+ long startTime = System.currentTimeMillis();
final RemotingCommand response = RemotingCommand.createResponseCommand(null);
LOGGER.info("AdminBrokerProcessor#updateAndCreateSubscriptionGroup called by {}",
@@ -1462,6 +1466,8 @@ private RemotingCommand updateAndCreateSubscriptionGroup(ChannelHandlerContext c
response.setCode(ResponseCode.SUCCESS);
response.setRemark(null);
+ long executionTime = System.currentTimeMillis() - startTime;
+ LOGGER.info("executionTime of create subscriptionGroup:{} is {} ms" ,config.getGroupName() ,executionTime);
return response;
}
@@ -3154,7 +3160,7 @@ private boolean validateSlave(RemotingCommand response) {
}
private boolean validateBlackListConfigExist(Properties properties) {
- for (String blackConfig:configBlackList) {
+ for (String blackConfig : configBlackList) {
if (properties.containsKey(blackConfig)) {
return true;
}
From 0ad0244fe504d9e20a15e83222826f1172bdc4b3 Mon Sep 17 00:00:00 2001
From: hiyo <77013030+miles-ton@users.noreply.github.com>
Date: Mon, 20 May 2024 10:47:59 +0800
Subject: [PATCH 009/265] [ISSUE #8164] Log more accurate for the
MQClientInstance#doRebalance (#8165)
---
.../apache/rocketmq/client/impl/factory/MQClientInstance.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/client/src/main/java/org/apache/rocketmq/client/impl/factory/MQClientInstance.java b/client/src/main/java/org/apache/rocketmq/client/impl/factory/MQClientInstance.java
index 1ff35a00d12..b4ebf692736 100644
--- a/client/src/main/java/org/apache/rocketmq/client/impl/factory/MQClientInstance.java
+++ b/client/src/main/java/org/apache/rocketmq/client/impl/factory/MQClientInstance.java
@@ -1070,7 +1070,7 @@ public boolean doRebalance() {
balanced = false;
}
} catch (Throwable e) {
- log.error("doRebalance exception", e);
+ log.error("doRebalance for consumer group [{}] exception", entry.getKey(), e);
}
}
}
From 94bb64f73160e309438fb000719fff0619355dd4 Mon Sep 17 00:00:00 2001
From: mxsm
Date: Tue, 21 May 2024 08:32:20 +0800
Subject: [PATCH 010/265] [ISSUE #8162]Optimize the logging printout for the
ConfigManager#loadBak method (#8163)
---
.../main/java/org/apache/rocketmq/common/ConfigManager.java | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/common/src/main/java/org/apache/rocketmq/common/ConfigManager.java b/common/src/main/java/org/apache/rocketmq/common/ConfigManager.java
index 5e997596194..099f0d8d560 100644
--- a/common/src/main/java/org/apache/rocketmq/common/ConfigManager.java
+++ b/common/src/main/java/org/apache/rocketmq/common/ConfigManager.java
@@ -52,8 +52,8 @@ public boolean load() {
private boolean loadBak() {
String fileName = null;
try {
- fileName = this.configFilePath();
- String jsonString = MixAll.file2String(fileName + ".bak");
+ fileName = this.configFilePath() + ".bak";
+ String jsonString = MixAll.file2String(fileName);
if (jsonString != null && jsonString.length() > 0) {
this.decode(jsonString);
log.info("load " + fileName + " OK");
From 1b42515093fb56a2cabfa754564397e343a357be Mon Sep 17 00:00:00 2001
From: yuz10 <845238369@qq.com>
Date: Wed, 22 May 2024 14:09:00 +0800
Subject: [PATCH 011/265] [ISSUE #8129] Support topic reserved time in tiered
storage (#8130)
Co-authored-by: yuzhou
---
broker/BUILD.bazel | 2 ++
.../broker/topic/TopicConfigManager.java | 31 +++++++++++++++++++
.../rocketmq/common/TopicAttributes.java | 9 ++++++
tieredstore/README.md | 4 +--
.../tieredstore/file/FlatFileStore.java | 4 +--
.../tieredstore/file/FlatMessageFile.java | 7 +++++
.../metrics/TieredStoreMetricsManager.java | 5 +--
7 files changed, 56 insertions(+), 6 deletions(-)
diff --git a/broker/BUILD.bazel b/broker/BUILD.bazel
index 785b7657740..0dbc85f9453 100644
--- a/broker/BUILD.bazel
+++ b/broker/BUILD.bazel
@@ -29,6 +29,7 @@ java_library(
"//remoting",
"//srvutil",
"//store",
+ "//tieredstore",
"@maven//:ch_qos_logback_logback_classic",
"@maven//:com_alibaba_fastjson",
"@maven//:com_alibaba_fastjson2_fastjson2",
@@ -81,6 +82,7 @@ java_library(
"//filter",
"//remoting",
"//store",
+ "//tieredstore",
"@maven//:com_alibaba_fastjson",
"@maven//:com_alibaba_fastjson2_fastjson2",
"@maven//:com_google_guava_guava",
diff --git a/broker/src/main/java/org/apache/rocketmq/broker/topic/TopicConfigManager.java b/broker/src/main/java/org/apache/rocketmq/broker/topic/TopicConfigManager.java
index 511d29e12ad..1ed9cbab5f8 100644
--- a/broker/src/main/java/org/apache/rocketmq/broker/topic/TopicConfigManager.java
+++ b/broker/src/main/java/org/apache/rocketmq/broker/topic/TopicConfigManager.java
@@ -51,6 +51,9 @@
import org.apache.rocketmq.remoting.protocol.body.TopicConfigAndMappingSerializeWrapper;
import org.apache.rocketmq.remoting.protocol.body.TopicConfigSerializeWrapper;
import org.apache.rocketmq.remoting.protocol.statictopic.TopicQueueMappingInfo;
+import org.apache.rocketmq.tieredstore.TieredMessageStore;
+import org.apache.rocketmq.tieredstore.metadata.MetadataStore;
+import org.apache.rocketmq.tieredstore.metadata.entity.TopicMetadata;
import static com.google.common.base.Preconditions.checkNotNull;
@@ -501,6 +504,7 @@ public void updateTopicConfig(final TopicConfig topicConfig) {
ImmutableMap.copyOf(newAttributes));
topicConfig.setAttributes(finalAttributes);
+ updateTieredStoreTopicMetadata(topicConfig, newAttributes);
TopicConfig old = putTopicConfig(topicConfig);
if (old != null) {
@@ -515,6 +519,33 @@ public void updateTopicConfig(final TopicConfig topicConfig) {
this.persist(topicConfig.getTopicName(), topicConfig);
}
+ private synchronized void updateTieredStoreTopicMetadata(final TopicConfig topicConfig, Map newAttributes) {
+ if (!(brokerController.getMessageStore() instanceof TieredMessageStore)) {
+ if (newAttributes.get(TopicAttributes.TOPIC_RESERVE_TIME_ATTRIBUTE.getName()) != null) {
+ throw new IllegalArgumentException("Update topic reserveTime not supported");
+ }
+ return;
+ }
+
+ String topic = topicConfig.getTopicName();
+ long reserveTime = TopicAttributes.TOPIC_RESERVE_TIME_ATTRIBUTE.getDefaultValue();
+ String attr = topicConfig.getAttributes().get(TopicAttributes.TOPIC_RESERVE_TIME_ATTRIBUTE.getName());
+ if (attr != null) {
+ reserveTime = Long.parseLong(attr);
+ }
+
+ log.info("Update tiered storage metadata, topic {}, reserveTime {}", topic, reserveTime);
+ TieredMessageStore tieredMessageStore = (TieredMessageStore) brokerController.getMessageStore();
+ MetadataStore metadataStore = tieredMessageStore.getMetadataStore();
+ TopicMetadata topicMetadata = metadataStore.getTopic(topic);
+ if (topicMetadata == null) {
+ metadataStore.addTopic(topic, reserveTime);
+ } else if (topicMetadata.getReserveTime() != reserveTime) {
+ topicMetadata.setReserveTime(reserveTime);
+ metadataStore.updateTopic(topicMetadata);
+ }
+ }
+
public void updateOrderTopicConfig(final KVTable orderKVTableFromNs) {
if (orderKVTableFromNs != null && orderKVTableFromNs.getTable() != null) {
diff --git a/common/src/main/java/org/apache/rocketmq/common/TopicAttributes.java b/common/src/main/java/org/apache/rocketmq/common/TopicAttributes.java
index 1f26866e5b3..c507748c677 100644
--- a/common/src/main/java/org/apache/rocketmq/common/TopicAttributes.java
+++ b/common/src/main/java/org/apache/rocketmq/common/TopicAttributes.java
@@ -20,6 +20,7 @@
import java.util.Map;
import org.apache.rocketmq.common.attribute.Attribute;
import org.apache.rocketmq.common.attribute.EnumAttribute;
+import org.apache.rocketmq.common.attribute.LongRangeAttribute;
import org.apache.rocketmq.common.attribute.TopicMessageType;
import static com.google.common.collect.Sets.newHashSet;
@@ -43,6 +44,13 @@ public class TopicAttributes {
TopicMessageType.topicMessageTypeSet(),
TopicMessageType.NORMAL.getValue()
);
+ public static final LongRangeAttribute TOPIC_RESERVE_TIME_ATTRIBUTE = new LongRangeAttribute(
+ "reserve.time",
+ true,
+ -1,
+ Long.MAX_VALUE,
+ -1
+ );
public static final Map ALL;
@@ -51,5 +59,6 @@ public class TopicAttributes {
ALL.put(QUEUE_TYPE_ATTRIBUTE.getName(), QUEUE_TYPE_ATTRIBUTE);
ALL.put(CLEANUP_POLICY_ATTRIBUTE.getName(), CLEANUP_POLICY_ATTRIBUTE);
ALL.put(TOPIC_MESSAGE_TYPE_ATTRIBUTE.getName(), TOPIC_MESSAGE_TYPE_ATTRIBUTE);
+ ALL.put(TOPIC_RESERVE_TIME_ATTRIBUTE.getName(), TOPIC_RESERVE_TIME_ATTRIBUTE);
}
}
diff --git a/tieredstore/README.md b/tieredstore/README.md
index baeb56acc36..41e7458a2a6 100644
--- a/tieredstore/README.md
+++ b/tieredstore/README.md
@@ -57,8 +57,8 @@ Tiered storage provides some useful metrics, see [RIP-46](https://github.com/apa
## How to contribute
-We need community participation to add more backend service providers for tiered storage. [PosixFileSegment](https://github.com/apache/rocketmq/blob/develop/tieredstore/src/main/java/org/apache/rocketmq/tieredstore/provider/posix/PosixFileSegment.java), the implementation provided by default is just an example. People who want to contribute can follow it to implement their own providers, such as S3FileSegment, OSSFileSegment, and MinIOFileSegment. Here are some guidelines:
+We need community participation to add more backend service providers for tiered storage. [PosixFileSegment](https://github.com/apache/rocketmq/blob/develop/tieredstore/src/main/java/org/apache/rocketmq/tieredstore/provider/PosixFileSegment.java), the implementation provided by default is just an example. People who want to contribute can follow it to implement their own providers, such as S3FileSegment, OSSFileSegment, and MinIOFileSegment. Here are some guidelines:
-1. Extend [TieredFileSegment](https://github.com/apache/rocketmq/blob/develop/tieredstore/src/main/java/org/apache/rocketmq/tieredstore/provider/TieredFileSegment.java) and implement the methods of [TieredStoreProvider](https://github.com/apache/rocketmq/blob/develop/tieredstore/src/main/java/org/apache/rocketmq/tieredstore/provider/TieredStoreProvider.java) interface.
+1. Extend [FileSegment](https://github.com/apache/rocketmq/blob/develop/tieredstore/src/main/java/org/apache/rocketmq/tieredstore/provider/FileSegment.java) and implement the methods of [FileSegmentProvider](https://github.com/apache/rocketmq/blob/develop/tieredstore/src/main/java/org/apache/rocketmq/tieredstore/provider/FileSegmentProvider.java) interface.
2. Record metrics where appropriate. See `rocketmq_tiered_store_provider_rpc_latency`, `rocketmq_tiered_store_provider_upload_bytes`, and `rocketmq_tiered_store_provider_download_bytes`
3. No need to maintain your own cache and avoid polluting the page cache. It is already having the read-ahead cache.
diff --git a/tieredstore/src/main/java/org/apache/rocketmq/tieredstore/file/FlatFileStore.java b/tieredstore/src/main/java/org/apache/rocketmq/tieredstore/file/FlatFileStore.java
index 0d7044a5447..f782d099def 100644
--- a/tieredstore/src/main/java/org/apache/rocketmq/tieredstore/file/FlatFileStore.java
+++ b/tieredstore/src/main/java/org/apache/rocketmq/tieredstore/file/FlatFileStore.java
@@ -60,9 +60,9 @@ public boolean load() {
this.flatFileConcurrentMap.clear();
this.recover();
this.executor.commonExecutor.scheduleWithFixedDelay(() -> {
- long expiredTimeStamp = System.currentTimeMillis() -
- TimeUnit.HOURS.toMillis(storeConfig.getTieredStoreFileReservedTime());
for (FlatMessageFile flatFile : deepCopyFlatFileToList()) {
+ long expiredTimeStamp = System.currentTimeMillis() -
+ TimeUnit.HOURS.toMillis(flatFile.getFileReservedHours());
flatFile.destroyExpiredFile(expiredTimeStamp);
if (flatFile.consumeQueue.fileSegmentTable.isEmpty()) {
this.destroyFile(flatFile.getMessageQueue());
diff --git a/tieredstore/src/main/java/org/apache/rocketmq/tieredstore/file/FlatMessageFile.java b/tieredstore/src/main/java/org/apache/rocketmq/tieredstore/file/FlatMessageFile.java
index a214059442b..d5675976cb1 100644
--- a/tieredstore/src/main/java/org/apache/rocketmq/tieredstore/file/FlatMessageFile.java
+++ b/tieredstore/src/main/java/org/apache/rocketmq/tieredstore/file/FlatMessageFile.java
@@ -399,4 +399,11 @@ public void destroy() {
fileLock.unlock();
}
}
+
+ public long getFileReservedHours() {
+ if (topicMetadata.getReserveTime() > 0) {
+ return topicMetadata.getReserveTime();
+ }
+ return storeConfig.getTieredStoreFileReservedTime();
+ }
}
diff --git a/tieredstore/src/main/java/org/apache/rocketmq/tieredstore/metrics/TieredStoreMetricsManager.java b/tieredstore/src/main/java/org/apache/rocketmq/tieredstore/metrics/TieredStoreMetricsManager.java
index e76c86d79bf..8b5a9e63c0c 100644
--- a/tieredstore/src/main/java/org/apache/rocketmq/tieredstore/metrics/TieredStoreMetricsManager.java
+++ b/tieredstore/src/main/java/org/apache/rocketmq/tieredstore/metrics/TieredStoreMetricsManager.java
@@ -32,6 +32,7 @@
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.concurrent.TimeUnit;
import java.util.function.Supplier;
import org.apache.rocketmq.common.Pair;
import org.apache.rocketmq.common.message.MessageQueue;
@@ -180,7 +181,7 @@ public static void init(Meter meter, Supplier attributesBuild
MessageQueue mq = flatFile.getMessageQueue();
long maxOffset = next.getMaxOffsetInQueue(mq.getTopic(), mq.getQueueId());
long maxTimestamp = next.getMessageStoreTimeStamp(mq.getTopic(), mq.getQueueId(), maxOffset - 1);
- if (maxTimestamp > 0 && System.currentTimeMillis() - maxTimestamp > (long) storeConfig.getTieredStoreFileReservedTime() * 60 * 60 * 1000) {
+ if (maxTimestamp > 0 && System.currentTimeMillis() - maxTimestamp > TimeUnit.HOURS.toMillis(flatFile.getFileReservedHours())) {
continue;
}
@@ -209,7 +210,7 @@ public static void init(Meter meter, Supplier attributesBuild
MessageQueue mq = flatFile.getMessageQueue();
long maxOffset = next.getMaxOffsetInQueue(mq.getTopic(), mq.getQueueId());
long maxTimestamp = next.getMessageStoreTimeStamp(mq.getTopic(), mq.getQueueId(), maxOffset - 1);
- if (maxTimestamp > 0 && System.currentTimeMillis() - maxTimestamp > (long) storeConfig.getTieredStoreFileReservedTime() * 60 * 60 * 1000) {
+ if (maxTimestamp > 0 && System.currentTimeMillis() - maxTimestamp > TimeUnit.HOURS.toMillis(flatFile.getFileReservedHours())) {
continue;
}
From dcc88c65f1f29b392fbb300001b386dbf1901afc Mon Sep 17 00:00:00 2001
From: Humkum <1109939087@qq.com>
Date: Thu, 23 May 2024 13:56:30 +0800
Subject: [PATCH 012/265] [ISSUE #8166] optimize: make compression type
configurable in producer clinet level
---
.../impl/producer/DefaultMQProducerImpl.java | 28 +------------
.../client/producer/DefaultMQProducer.java | 39 +++++++++++++++++++
.../example/benchmark/BatchProducer.java | 4 +-
.../rocketmq/example/benchmark/Producer.java | 4 +-
4 files changed, 45 insertions(+), 30 deletions(-)
diff --git a/client/src/main/java/org/apache/rocketmq/client/impl/producer/DefaultMQProducerImpl.java b/client/src/main/java/org/apache/rocketmq/client/impl/producer/DefaultMQProducerImpl.java
index 6268bcc0a17..7ef34025137 100644
--- a/client/src/main/java/org/apache/rocketmq/client/impl/producer/DefaultMQProducerImpl.java
+++ b/client/src/main/java/org/apache/rocketmq/client/impl/producer/DefaultMQProducerImpl.java
@@ -70,9 +70,6 @@
import org.apache.rocketmq.common.ServiceState;
import org.apache.rocketmq.common.ThreadFactoryImpl;
import org.apache.rocketmq.common.UtilAll;
-import org.apache.rocketmq.common.compression.CompressionType;
-import org.apache.rocketmq.common.compression.Compressor;
-import org.apache.rocketmq.common.compression.CompressorFactory;
import org.apache.rocketmq.common.help.FAQUrl;
import org.apache.rocketmq.common.message.Message;
import org.apache.rocketmq.common.message.MessageAccessor;
@@ -118,11 +115,6 @@ public class DefaultMQProducerImpl implements MQProducerInner {
private MQFaultStrategy mqFaultStrategy;
private ExecutorService asyncSenderExecutor;
- // compression related
- private int compressLevel = Integer.parseInt(System.getProperty(MixAll.MESSAGE_COMPRESS_LEVEL, "5"));
- private CompressionType compressType = CompressionType.of(System.getProperty(MixAll.MESSAGE_COMPRESS_TYPE, "ZLIB"));
- private final Compressor compressor = CompressorFactory.getCompressor(compressType);
-
// backpressure related
private Semaphore semaphoreAsyncSendNum;
private Semaphore semaphoreAsyncSendSize;
@@ -900,7 +892,7 @@ private SendResult sendKernelImpl(final Message msg,
boolean msgBodyCompressed = false;
if (this.tryToCompressMessage(msg)) {
sysFlag |= MessageSysFlag.COMPRESSED_FLAG;
- sysFlag |= compressType.getCompressionFlag();
+ sysFlag |= this.defaultMQProducer.getCompressType().getCompressionFlag();
msgBodyCompressed = true;
}
@@ -1070,7 +1062,7 @@ private boolean tryToCompressMessage(final Message msg) {
if (body != null) {
if (body.length >= this.defaultMQProducer.getCompressMsgBodyOverHowmuch()) {
try {
- byte[] data = compressor.compress(body, compressLevel);
+ byte[] data = this.defaultMQProducer.getCompressor().compress(body, this.defaultMQProducer.getCompressLevel());
if (data != null) {
msg.setBody(data);
return true;
@@ -1763,22 +1755,6 @@ public ConcurrentMap getTopicPublishInfoTable() {
return topicPublishInfoTable;
}
- public int getCompressLevel() {
- return compressLevel;
- }
-
- public void setCompressLevel(int compressLevel) {
- this.compressLevel = compressLevel;
- }
-
- public CompressionType getCompressType() {
- return compressType;
- }
-
- public void setCompressType(CompressionType compressType) {
- this.compressType = compressType;
- }
-
public ServiceState getServiceState() {
return serviceState;
}
diff --git a/client/src/main/java/org/apache/rocketmq/client/producer/DefaultMQProducer.java b/client/src/main/java/org/apache/rocketmq/client/producer/DefaultMQProducer.java
index b350ba074db..5304887e380 100644
--- a/client/src/main/java/org/apache/rocketmq/client/producer/DefaultMQProducer.java
+++ b/client/src/main/java/org/apache/rocketmq/client/producer/DefaultMQProducer.java
@@ -36,6 +36,9 @@
import org.apache.rocketmq.client.trace.hook.EndTransactionTraceHookImpl;
import org.apache.rocketmq.client.trace.hook.SendMessageTraceHookImpl;
import org.apache.rocketmq.common.MixAll;
+import org.apache.rocketmq.common.compression.CompressionType;
+import org.apache.rocketmq.common.compression.Compressor;
+import org.apache.rocketmq.common.compression.CompressorFactory;
import org.apache.rocketmq.common.message.Message;
import org.apache.rocketmq.common.message.MessageBatch;
import org.apache.rocketmq.common.message.MessageClientIDSetter;
@@ -170,6 +173,21 @@ public class DefaultMQProducer extends ClientConfig implements MQProducer {
private RPCHook rpcHook = null;
+ /**
+ * Compress level of compress algorithm.
+ */
+ private int compressLevel = Integer.parseInt(System.getProperty(MixAll.MESSAGE_COMPRESS_LEVEL, "5"));
+
+ /**
+ * Compress type of compress algorithm, default using ZLIB.
+ */
+ private CompressionType compressType = CompressionType.of(System.getProperty(MixAll.MESSAGE_COMPRESS_TYPE, "ZLIB"));
+
+ /**
+ * Compressor of compress algorithm.
+ */
+ private Compressor compressor = CompressorFactory.getCompressor(compressType);
+
/**
* Default constructor.
*/
@@ -1344,4 +1362,25 @@ public void setStartDetectorEnable(boolean startDetectorEnable) {
super.setStartDetectorEnable(startDetectorEnable);
this.defaultMQProducerImpl.getMqFaultStrategy().setStartDetectorEnable(startDetectorEnable);
}
+
+ public int getCompressLevel() {
+ return compressLevel;
+ }
+
+ public void setCompressLevel(int compressLevel) {
+ this.compressLevel = compressLevel;
+ }
+
+ public CompressionType getCompressType() {
+ return compressType;
+ }
+
+ public void setCompressType(CompressionType compressType) {
+ this.compressType = compressType;
+ this.compressor = CompressorFactory.getCompressor(compressType);
+ }
+
+ public Compressor getCompressor() {
+ return compressor;
+ }
}
diff --git a/example/src/main/java/org/apache/rocketmq/example/benchmark/BatchProducer.java b/example/src/main/java/org/apache/rocketmq/example/benchmark/BatchProducer.java
index c4a6162a5f5..21a4b3b7e77 100644
--- a/example/src/main/java/org/apache/rocketmq/example/benchmark/BatchProducer.java
+++ b/example/src/main/java/org/apache/rocketmq/example/benchmark/BatchProducer.java
@@ -102,8 +102,8 @@ public static void main(String[] args) throws MQClientException {
String compressType = commandLine.hasOption("ct") ? commandLine.getOptionValue("ct").trim() : "ZLIB";
int compressLevel = commandLine.hasOption("cl") ? Integer.parseInt(commandLine.getOptionValue("cl")) : 5;
int compressOverHowMuch = commandLine.hasOption("ch") ? Integer.parseInt(commandLine.getOptionValue("ch")) : 4096;
- producer.getDefaultMQProducerImpl().setCompressType(CompressionType.of(compressType));
- producer.getDefaultMQProducerImpl().setCompressLevel(compressLevel);
+ producer.setCompressType(CompressionType.of(compressType));
+ producer.setCompressLevel(compressLevel);
producer.setCompressMsgBodyOverHowmuch(compressOverHowMuch);
System.out.printf("compressType: %s compressLevel: %s%n", compressType, compressLevel);
} else {
diff --git a/example/src/main/java/org/apache/rocketmq/example/benchmark/Producer.java b/example/src/main/java/org/apache/rocketmq/example/benchmark/Producer.java
index 480d16b7581..a945283f576 100644
--- a/example/src/main/java/org/apache/rocketmq/example/benchmark/Producer.java
+++ b/example/src/main/java/org/apache/rocketmq/example/benchmark/Producer.java
@@ -160,8 +160,8 @@ public void run() {
String compressType = commandLine.hasOption("ct") ? commandLine.getOptionValue("ct").trim() : "ZLIB";
int compressLevel = commandLine.hasOption("cl") ? Integer.parseInt(commandLine.getOptionValue("cl")) : 5;
int compressOverHowMuch = commandLine.hasOption("ch") ? Integer.parseInt(commandLine.getOptionValue("ch")) : 4096;
- producer.getDefaultMQProducerImpl().setCompressType(CompressionType.of(compressType));
- producer.getDefaultMQProducerImpl().setCompressLevel(compressLevel);
+ producer.setCompressType(CompressionType.of(compressType));
+ producer.setCompressLevel(compressLevel);
producer.setCompressMsgBodyOverHowmuch(compressOverHowMuch);
System.out.printf("compressType: %s compressLevel: %s%n", compressType, compressLevel);
} else {
From b58eefc1a6c272726f17c16b4bb0c2a2666578fa Mon Sep 17 00:00:00 2001
From: Stephanie0002 <55239858+Stephanie0002@users.noreply.github.com>
Date: Thu, 23 May 2024 20:15:20 +0800
Subject: [PATCH 013/265] [ISSUE #8182] Modify variable names to enhance
readability #8182
---
.../org/apache/rocketmq/example/operation/Consumer.java | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/example/src/main/java/org/apache/rocketmq/example/operation/Consumer.java b/example/src/main/java/org/apache/rocketmq/example/operation/Consumer.java
index 90f2e133a1c..378a9769975 100644
--- a/example/src/main/java/org/apache/rocketmq/example/operation/Consumer.java
+++ b/example/src/main/java/org/apache/rocketmq/example/operation/Consumer.java
@@ -36,15 +36,15 @@ public class Consumer {
public static void main(String[] args) throws MQClientException {
CommandLine commandLine = buildCommandline(args);
if (commandLine != null) {
- String group = commandLine.getOptionValue('g');
+ String subGroup = commandLine.getOptionValue('g');
String topic = commandLine.getOptionValue('t');
- String subscription = commandLine.getOptionValue('s');
+ String subExpression = commandLine.getOptionValue('s');
final String returnFailedHalf = commandLine.getOptionValue('f');
- DefaultMQPushConsumer consumer = new DefaultMQPushConsumer(group);
+ DefaultMQPushConsumer consumer = new DefaultMQPushConsumer(subGroup);
consumer.setInstanceName(Long.toString(System.currentTimeMillis()));
- consumer.subscribe(topic, subscription);
+ consumer.subscribe(topic, subExpression);
consumer.registerMessageListener(new MessageListenerConcurrently() {
AtomicLong consumeTimes = new AtomicLong(0);
From bdc7c0ab6cb296c736c2f322b840c6da9613d10e Mon Sep 17 00:00:00 2001
From: weihubeats
Date: Fri, 24 May 2024 10:24:31 +0800
Subject: [PATCH 014/265] [ISSUE #6873] If dns resolve controller address
exception will update controllerAddresses to null (#8180)
* Adding null does not update
* rolling back
* dns resolution failure not updating controllerAddresses
---
.../broker/controller/ReplicasManager.java | 7 ++--
.../controller/ReplicasManagerTest.java | 36 ++++++++++++++++---
2 files changed, 36 insertions(+), 7 deletions(-)
diff --git a/broker/src/main/java/org/apache/rocketmq/broker/controller/ReplicasManager.java b/broker/src/main/java/org/apache/rocketmq/broker/controller/ReplicasManager.java
index a1d711cb275..c294f860ba3 100644
--- a/broker/src/main/java/org/apache/rocketmq/broker/controller/ReplicasManager.java
+++ b/broker/src/main/java/org/apache/rocketmq/broker/controller/ReplicasManager.java
@@ -30,7 +30,7 @@
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
-
+import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.rocketmq.broker.BrokerController;
import org.apache.rocketmq.broker.out.BrokerOuterAPI;
@@ -803,7 +803,10 @@ private void scanAvailableControllerAddresses() {
private void updateControllerAddr() {
if (brokerConfig.isFetchControllerAddrByDnsLookup()) {
- this.controllerAddresses = brokerOuterAPI.dnsLookupAddressByDomain(this.brokerConfig.getControllerAddr());
+ List adders = brokerOuterAPI.dnsLookupAddressByDomain(this.brokerConfig.getControllerAddr());
+ if (CollectionUtils.isNotEmpty(adders)) {
+ this.controllerAddresses = adders;
+ }
} else {
final String controllerPaths = this.brokerConfig.getControllerAddr();
final String[] controllers = controllerPaths.split(";");
diff --git a/broker/src/test/java/org/apache/rocketmq/broker/controller/ReplicasManagerTest.java b/broker/src/test/java/org/apache/rocketmq/broker/controller/ReplicasManagerTest.java
index c863f7ac96c..9f17f2bd593 100644
--- a/broker/src/test/java/org/apache/rocketmq/broker/controller/ReplicasManagerTest.java
+++ b/broker/src/test/java/org/apache/rocketmq/broker/controller/ReplicasManagerTest.java
@@ -17,12 +17,15 @@
package org.apache.rocketmq.broker.controller;
+import com.google.common.collect.Lists;
import java.io.File;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
+import java.util.List;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
-
import org.apache.rocketmq.broker.BrokerController;
import org.apache.rocketmq.broker.out.BrokerOuterAPI;
import org.apache.rocketmq.broker.slave.SlaveSynchronize;
@@ -31,11 +34,11 @@
import org.apache.rocketmq.common.Pair;
import org.apache.rocketmq.common.UtilAll;
import org.apache.rocketmq.remoting.protocol.body.SyncStateSet;
+import org.apache.rocketmq.remoting.protocol.header.controller.ElectMasterResponseHeader;
import org.apache.rocketmq.remoting.protocol.header.controller.GetMetaDataResponseHeader;
import org.apache.rocketmq.remoting.protocol.header.controller.GetReplicaInfoResponseHeader;
import org.apache.rocketmq.remoting.protocol.header.controller.register.ApplyBrokerIdResponseHeader;
import org.apache.rocketmq.remoting.protocol.header.controller.register.GetNextBrokerIdResponseHeader;
-import org.apache.rocketmq.remoting.protocol.header.controller.ElectMasterResponseHeader;
import org.apache.rocketmq.remoting.protocol.header.controller.register.RegisterBrokerToControllerResponseHeader;
import org.apache.rocketmq.store.DefaultMessageStore;
import org.apache.rocketmq.store.RunningFlags;
@@ -52,6 +55,7 @@
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.when;
@RunWith(MockitoJUnitRunner.class)
@@ -189,11 +193,11 @@ public void changeBrokerRoleTest() {
syncStateSetA.add(BROKER_ID_2);
// not equal to localAddress
Assertions.assertThatCode(() -> replicasManager.changeBrokerRole(BROKER_ID_2, NEW_MASTER_ADDRESS, NEW_MASTER_EPOCH, OLD_MASTER_EPOCH, syncStateSetB))
- .doesNotThrowAnyException();
+ .doesNotThrowAnyException();
// equal to localAddress
Assertions.assertThatCode(() -> replicasManager.changeBrokerRole(BROKER_ID_1, OLD_MASTER_ADDRESS, NEW_MASTER_EPOCH, OLD_MASTER_EPOCH, syncStateSetA))
- .doesNotThrowAnyException();
+ .doesNotThrowAnyException();
}
@Test
@@ -206,6 +210,28 @@ public void changeToMasterTest() {
@Test
public void changeToSlaveTest() {
Assertions.assertThatCode(() -> replicasManager.changeToSlave(NEW_MASTER_ADDRESS, NEW_MASTER_EPOCH, BROKER_ID_2))
- .doesNotThrowAnyException();
+ .doesNotThrowAnyException();
}
+
+ @Test
+ public void testUpdateControllerAddr() throws Exception {
+ final String controllerAddr = "192.168.1.1";
+ brokerConfig.setFetchControllerAddrByDnsLookup(true);
+ when(brokerOuterAPI.dnsLookupAddressByDomain(anyString())).thenReturn(Lists.newArrayList(controllerAddr));
+ Method method = ReplicasManager.class.getDeclaredMethod("updateControllerAddr");
+ method.setAccessible(true);
+ method.invoke(replicasManager);
+
+ List addresses = replicasManager.getControllerAddresses();
+ Assertions.assertThat(addresses).contains(controllerAddr);
+
+ // Simulating dns resolution exceptions
+ when(brokerOuterAPI.dnsLookupAddressByDomain(anyString())).thenReturn(new ArrayList<>());
+
+ method.invoke(replicasManager);
+ addresses = replicasManager.getControllerAddresses();
+ Assertions.assertThat(addresses).contains(controllerAddr);
+
+ }
+
}
From 9c8fdb715f774440009b85da2edbd2ab0278831d Mon Sep 17 00:00:00 2001
From: Humkum <1109939087@qq.com>
Date: Fri, 24 May 2024 17:01:41 +0800
Subject: [PATCH 015/265] [ISSUE #8168] fix: There's no need to retry when
async produce already timeout (#8169)
---
.../org/apache/rocketmq/client/impl/MQClientAPIImpl.java | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/client/src/main/java/org/apache/rocketmq/client/impl/MQClientAPIImpl.java b/client/src/main/java/org/apache/rocketmq/client/impl/MQClientAPIImpl.java
index 9b15279cb62..816ae877aca 100644
--- a/client/src/main/java/org/apache/rocketmq/client/impl/MQClientAPIImpl.java
+++ b/client/src/main/java/org/apache/rocketmq/client/impl/MQClientAPIImpl.java
@@ -704,9 +704,10 @@ public void operationFail(Throwable throwable) {
onExceptionImpl(brokerName, msg, timeoutMillis - cost, request, sendCallback, topicPublishInfo, instance,
retryTimesWhenSendFailed, times, ex, context, true, producer);
} else {
- MQClientException ex = new MQClientException("unknow reseaon", throwable);
+ MQClientException ex = new MQClientException("unknown reason", throwable);
+ boolean needRetry = !(throwable instanceof RemotingTooMuchRequestException);
onExceptionImpl(brokerName, msg, timeoutMillis - cost, request, sendCallback, topicPublishInfo, instance,
- retryTimesWhenSendFailed, times, ex, context, true, producer);
+ retryTimesWhenSendFailed, times, ex, context, needRetry, producer);
}
}
});
From 152055632d28f813ca166fd42cc8c3c0183a370c Mon Sep 17 00:00:00 2001
From: yx9o
Date: Thu, 30 May 2024 10:10:03 +0800
Subject: [PATCH 016/265] [ISSUE #8222] Fix spelling errors in comments (#8224)
---
.../org/apache/rocketmq/store/config/MessageStoreConfig.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/store/src/main/java/org/apache/rocketmq/store/config/MessageStoreConfig.java b/store/src/main/java/org/apache/rocketmq/store/config/MessageStoreConfig.java
index 0ba02e4cb9d..9afc02a0c9c 100644
--- a/store/src/main/java/org/apache/rocketmq/store/config/MessageStoreConfig.java
+++ b/store/src/main/java/org/apache/rocketmq/store/config/MessageStoreConfig.java
@@ -50,7 +50,7 @@ public class MessageStoreConfig {
// CommitLog file size,default is 1G
private int mappedFileSizeCommitLog = 1024 * 1024 * 1024;
- // CompactinLog file size, default is 100M
+ // CompactionLog file size, default is 100M
private int compactionMappedFileSize = 100 * 1024 * 1024;
// CompactionLog consumeQueue file size, default is 10M
From db163b431ea9366d1121d04ded4b660fd8a31624 Mon Sep 17 00:00:00 2001
From: yuz10 <845238369@qq.com>
Date: Thu, 30 May 2024 13:52:09 +0800
Subject: [PATCH 017/265] Revert "[ISSUE #7757] Use `CompositeByteBuf` to
prevent memory copy. (#7694)" (#8209)
This reverts commit 7a36d4d736ae8d6d92658e3bdb18f1cd5c0afdb0.
---
.../remoting/netty/FileRegionEncoder.java | 20 ++++---------------
.../remoting/netty/FileRegionEncoderTest.java | 5 ++---
2 files changed, 6 insertions(+), 19 deletions(-)
diff --git a/remoting/src/main/java/org/apache/rocketmq/remoting/netty/FileRegionEncoder.java b/remoting/src/main/java/org/apache/rocketmq/remoting/netty/FileRegionEncoder.java
index 3522c7965c1..7373a560703 100644
--- a/remoting/src/main/java/org/apache/rocketmq/remoting/netty/FileRegionEncoder.java
+++ b/remoting/src/main/java/org/apache/rocketmq/remoting/netty/FileRegionEncoder.java
@@ -18,9 +18,6 @@
package org.apache.rocketmq.remoting.netty;
import io.netty.buffer.ByteBuf;
-import io.netty.buffer.ByteBufAllocator;
-import io.netty.buffer.CompositeByteBuf;
-import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.FileRegion;
import io.netty.handler.codec.MessageToByteEncoder;
@@ -54,12 +51,9 @@ protected void encode(ChannelHandlerContext ctx, FileRegion msg, final ByteBuf o
WritableByteChannel writableByteChannel = new WritableByteChannel() {
@Override
public int write(ByteBuffer src) {
- // To prevent mem_copy.
- CompositeByteBuf b = (CompositeByteBuf) out;
- // Have to increase writerIndex manually.
- ByteBuf unpooled = Unpooled.wrappedBuffer(src);
- b.addComponent(true, unpooled);
- return unpooled.readableBytes();
+ int prev = out.writerIndex();
+ out.writeBytes(src);
+ return out.writerIndex() - prev;
}
@Override
@@ -82,10 +76,4 @@ public void close() throws IOException {
msg.transferTo(writableByteChannel, transferred);
}
}
-
- @Override
- protected ByteBuf allocateBuffer(ChannelHandlerContext ctx, FileRegion msg, boolean preferDirect) throws Exception {
- ByteBufAllocator allocator = ctx.alloc();
- return preferDirect ? allocator.compositeDirectBuffer() : allocator.compositeHeapBuffer();
- }
-}
\ No newline at end of file
+}
diff --git a/remoting/src/test/java/org/apache/rocketmq/remoting/netty/FileRegionEncoderTest.java b/remoting/src/test/java/org/apache/rocketmq/remoting/netty/FileRegionEncoderTest.java
index 0cbe627d801..6c7327f258e 100644
--- a/remoting/src/test/java/org/apache/rocketmq/remoting/netty/FileRegionEncoderTest.java
+++ b/remoting/src/test/java/org/apache/rocketmq/remoting/netty/FileRegionEncoderTest.java
@@ -21,15 +21,14 @@
import io.netty.channel.DefaultFileRegion;
import io.netty.channel.FileRegion;
import io.netty.channel.embedded.EmbeddedChannel;
-import org.junit.Assert;
-import org.junit.Test;
-
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Random;
import java.util.UUID;
+import org.junit.Assert;
+import org.junit.Test;
public class FileRegionEncoderTest {
From 7a5ea90cb79cc28ae86c368f22d1ab7d2f6f24cc Mon Sep 17 00:00:00 2001
From: wuyue
Date: Fri, 31 May 2024 11:10:05 +0800
Subject: [PATCH 018/265] [ISSUE #8053] Return SYSTEM_BUSY if PutMessageStatus
is OS_PAGE_CACHE_BUSY (#8054)
---
.../apache/rocketmq/broker/processor/SendMessageProcessor.java | 2 +-
.../rocketmq/broker/processor/SendMessageProcessorTest.java | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/broker/src/main/java/org/apache/rocketmq/broker/processor/SendMessageProcessor.java b/broker/src/main/java/org/apache/rocketmq/broker/processor/SendMessageProcessor.java
index 912d502eab2..db5b22888dc 100644
--- a/broker/src/main/java/org/apache/rocketmq/broker/processor/SendMessageProcessor.java
+++ b/broker/src/main/java/org/apache/rocketmq/broker/processor/SendMessageProcessor.java
@@ -430,7 +430,7 @@ private RemotingCommand handlePutMessageResult(PutMessageResult putMessageResult
"the broker's disk is full [" + diskUtil() + "], messages are put to the slave, message store has been shut down, etc.");
break;
case OS_PAGE_CACHE_BUSY:
- response.setCode(ResponseCode.SYSTEM_ERROR);
+ response.setCode(ResponseCode.SYSTEM_BUSY);
response.setRemark("[PC_SYNCHRONIZED]broker busy, start flow control for a while");
break;
case LMQ_CONSUME_QUEUE_NUM_EXCEEDED:
diff --git a/broker/src/test/java/org/apache/rocketmq/broker/processor/SendMessageProcessorTest.java b/broker/src/test/java/org/apache/rocketmq/broker/processor/SendMessageProcessorTest.java
index e046c888438..442794dcd26 100644
--- a/broker/src/test/java/org/apache/rocketmq/broker/processor/SendMessageProcessorTest.java
+++ b/broker/src/test/java/org/apache/rocketmq/broker/processor/SendMessageProcessorTest.java
@@ -174,7 +174,7 @@ public void testProcessRequest_FlushSlaveTimeout() throws Exception {
public void testProcessRequest_PageCacheBusy() throws Exception {
when(messageStore.asyncPutMessage(any(MessageExtBrokerInner.class))).
thenReturn(CompletableFuture.completedFuture(new PutMessageResult(PutMessageStatus.OS_PAGE_CACHE_BUSY, new AppendMessageResult(AppendMessageStatus.UNKNOWN_ERROR))));
- assertPutResult(ResponseCode.SYSTEM_ERROR);
+ assertPutResult(ResponseCode.SYSTEM_BUSY);
}
@Test
From 40271394e344df631d288b169befe1a4d7001255 Mon Sep 17 00:00:00 2001
From: Stephanie0002 <55239858+Stephanie0002@users.noreply.github.com>
Date: Fri, 31 May 2024 17:06:00 +0800
Subject: [PATCH 019/265] [ISSUE #8211] Add two metrics
rocketmq_topic_create_execution_time and
rocketmq_consumer_group_create_execution_time (#8212)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* Add tow metric createTopicTime and createSubscriptionTime in broker
* roll back BrokerConfig.java
* Add metric view of createTopicTime and createSubscriptionTime in broker
* Add two metric rocketmq_active_topic_number and rocketmq_active_subscription_number
Signed-off-by: 黄梓淇
---
.../broker/metrics/BrokerMetricsConstant.java | 3 +
.../broker/metrics/BrokerMetricsManager.java | 43 +++++++++
.../broker/metrics/InvocationStatus.java | 33 +++++++
.../processor/AdminBrokerProcessor.java | 90 +++++++++++--------
4 files changed, 134 insertions(+), 35 deletions(-)
create mode 100644 broker/src/main/java/org/apache/rocketmq/broker/metrics/InvocationStatus.java
diff --git a/broker/src/main/java/org/apache/rocketmq/broker/metrics/BrokerMetricsConstant.java b/broker/src/main/java/org/apache/rocketmq/broker/metrics/BrokerMetricsConstant.java
index 5733aa40bac..0af2ac616c4 100644
--- a/broker/src/main/java/org/apache/rocketmq/broker/metrics/BrokerMetricsConstant.java
+++ b/broker/src/main/java/org/apache/rocketmq/broker/metrics/BrokerMetricsConstant.java
@@ -27,6 +27,8 @@ public class BrokerMetricsConstant {
public static final String COUNTER_THROUGHPUT_IN_TOTAL = "rocketmq_throughput_in_total";
public static final String COUNTER_THROUGHPUT_OUT_TOTAL = "rocketmq_throughput_out_total";
public static final String HISTOGRAM_MESSAGE_SIZE = "rocketmq_message_size";
+ public static final String HISTOGRAM_TOPIC_CREATE_EXECUTE_TIME = "rocketmq_topic_create_execution_time";
+ public static final String HISTOGRAM_CONSUMER_GROUP_CREATE_EXECUTE_TIME = "rocketmq_consumer_group_create_execution_time";
public static final String GAUGE_PRODUCER_CONNECTIONS = "rocketmq_producer_connections";
public static final String GAUGE_CONSUMER_CONNECTIONS = "rocketmq_consumer_connections";
@@ -52,6 +54,7 @@ public class BrokerMetricsConstant {
public static final String LABEL_PROCESSOR = "processor";
public static final String LABEL_TOPIC = "topic";
+ public static final String LABEL_INVOCATION_STATUS = "invocation_status";
public static final String LABEL_IS_RETRY = "is_retry";
public static final String LABEL_IS_SYSTEM = "is_system";
public static final String LABEL_CONSUMER_GROUP = "consumer_group";
diff --git a/broker/src/main/java/org/apache/rocketmq/broker/metrics/BrokerMetricsManager.java b/broker/src/main/java/org/apache/rocketmq/broker/metrics/BrokerMetricsManager.java
index fc7e97bda95..0050a0dcd4c 100644
--- a/broker/src/main/java/org/apache/rocketmq/broker/metrics/BrokerMetricsManager.java
+++ b/broker/src/main/java/org/apache/rocketmq/broker/metrics/BrokerMetricsManager.java
@@ -64,6 +64,7 @@
import org.apache.rocketmq.store.metrics.DefaultStoreMetricsConstant;
import org.slf4j.bridge.SLF4JBridgeHandler;
+import java.time.Duration;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
@@ -92,6 +93,8 @@
import static org.apache.rocketmq.broker.metrics.BrokerMetricsConstant.GAUGE_PRODUCER_CONNECTIONS;
import static org.apache.rocketmq.broker.metrics.BrokerMetricsConstant.HISTOGRAM_FINISH_MSG_LATENCY;
import static org.apache.rocketmq.broker.metrics.BrokerMetricsConstant.HISTOGRAM_MESSAGE_SIZE;
+import static org.apache.rocketmq.broker.metrics.BrokerMetricsConstant.HISTOGRAM_TOPIC_CREATE_EXECUTE_TIME;
+import static org.apache.rocketmq.broker.metrics.BrokerMetricsConstant.HISTOGRAM_CONSUMER_GROUP_CREATE_EXECUTE_TIME;
import static org.apache.rocketmq.broker.metrics.BrokerMetricsConstant.LABEL_AGGREGATION;
import static org.apache.rocketmq.broker.metrics.BrokerMetricsConstant.LABEL_CLUSTER_NAME;
import static org.apache.rocketmq.broker.metrics.BrokerMetricsConstant.LABEL_CONSUMER_GROUP;
@@ -135,6 +138,8 @@ public class BrokerMetricsManager {
public static LongCounter throughputInTotal = new NopLongCounter();
public static LongCounter throughputOutTotal = new NopLongCounter();
public static LongHistogram messageSize = new NopLongHistogram();
+ public static LongHistogram topicCreateExecuteTime = new NopLongHistogram();
+ public static LongHistogram consumerGroupCreateExecuteTime = new NopLongHistogram();
// client connection metrics
public static ObservableLongGauge producerConnection = new NopObservableLongGauge();
@@ -381,6 +386,14 @@ private void registerMetricsView(SdkMeterProviderBuilder providerBuilder) {
1d * 12 * 60 * 60, //12h
1d * 24 * 60 * 60 //24h
);
+
+ List createTimeBuckets = Arrays.asList(
+ (double) Duration.ofMillis(10).toMillis(), //10ms
+ (double) Duration.ofMillis(100).toMillis(), //100ms
+ (double) Duration.ofSeconds(1).toMillis(), //1s
+ (double) Duration.ofSeconds(3).toMillis(), //3s
+ (double) Duration.ofSeconds(5).toMillis() //5s
+ );
InstrumentSelector messageSizeSelector = InstrumentSelector.builder()
.setType(InstrumentType.HISTOGRAM)
.setName(HISTOGRAM_MESSAGE_SIZE)
@@ -401,6 +414,24 @@ private void registerMetricsView(SdkMeterProviderBuilder providerBuilder) {
SdkMeterProviderUtil.setCardinalityLimit(commitLatencyViewBuilder, brokerConfig.getMetricsOtelCardinalityLimit());
providerBuilder.registerView(commitLatencySelector, commitLatencyViewBuilder.build());
+ InstrumentSelector createTopicTimeSelector = InstrumentSelector.builder()
+ .setType(InstrumentType.HISTOGRAM)
+ .setName(HISTOGRAM_TOPIC_CREATE_EXECUTE_TIME)
+ .build();
+ InstrumentSelector createSubGroupTimeSelector = InstrumentSelector.builder()
+ .setType(InstrumentType.HISTOGRAM)
+ .setName(HISTOGRAM_CONSUMER_GROUP_CREATE_EXECUTE_TIME)
+ .build();
+ ViewBuilder createTopicTimeViewBuilder = View.builder()
+ .setAggregation(Aggregation.explicitBucketHistogram(createTimeBuckets));
+ ViewBuilder createSubGroupTimeViewBuilder = View.builder()
+ .setAggregation(Aggregation.explicitBucketHistogram(createTimeBuckets));
+ // To config the cardinalityLimit for openTelemetry metrics exporting.
+ SdkMeterProviderUtil.setCardinalityLimit(createTopicTimeViewBuilder, brokerConfig.getMetricsOtelCardinalityLimit());
+ providerBuilder.registerView(createTopicTimeSelector, createTopicTimeViewBuilder.build());
+ SdkMeterProviderUtil.setCardinalityLimit(createSubGroupTimeViewBuilder, brokerConfig.getMetricsOtelCardinalityLimit());
+ providerBuilder.registerView(createSubGroupTimeSelector, createSubGroupTimeViewBuilder.build());
+
for (Pair selectorViewPair : RemotingMetricsManager.getMetricsView()) {
ViewBuilder viewBuilder = selectorViewPair.getObject2();
SdkMeterProviderUtil.setCardinalityLimit(viewBuilder, brokerConfig.getMetricsOtelCardinalityLimit());
@@ -482,6 +513,18 @@ private void initRequestMetrics() {
.setDescription("Incoming messages size")
.ofLongs()
.build();
+
+ topicCreateExecuteTime = brokerMeter.histogramBuilder(HISTOGRAM_TOPIC_CREATE_EXECUTE_TIME)
+ .setDescription("The distribution of create topic time")
+ .ofLongs()
+ .setUnit("milliseconds")
+ .build();
+
+ consumerGroupCreateExecuteTime = brokerMeter.histogramBuilder(HISTOGRAM_CONSUMER_GROUP_CREATE_EXECUTE_TIME)
+ .setDescription("The distribution of create subscription time")
+ .ofLongs()
+ .setUnit("milliseconds")
+ .build();
}
private void initConnectionMetrics() {
diff --git a/broker/src/main/java/org/apache/rocketmq/broker/metrics/InvocationStatus.java b/broker/src/main/java/org/apache/rocketmq/broker/metrics/InvocationStatus.java
new file mode 100644
index 00000000000..c7501e53d96
--- /dev/null
+++ b/broker/src/main/java/org/apache/rocketmq/broker/metrics/InvocationStatus.java
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.rocketmq.broker.metrics;
+
+public enum InvocationStatus {
+ SUCCESS("success"),
+ FAILURE("failure");
+
+ private final String name;
+
+ InvocationStatus(String name) {
+ this.name = name;
+ }
+
+ public String getName() {
+ return name;
+ }
+}
\ No newline at end of file
diff --git a/broker/src/main/java/org/apache/rocketmq/broker/processor/AdminBrokerProcessor.java b/broker/src/main/java/org/apache/rocketmq/broker/processor/AdminBrokerProcessor.java
index a1a6f5bf6ce..40a7a461e89 100644
--- a/broker/src/main/java/org/apache/rocketmq/broker/processor/AdminBrokerProcessor.java
+++ b/broker/src/main/java/org/apache/rocketmq/broker/processor/AdminBrokerProcessor.java
@@ -38,6 +38,7 @@
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
+import io.opentelemetry.api.common.Attributes;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.rocketmq.acl.AccessValidator;
@@ -58,6 +59,8 @@
import org.apache.rocketmq.broker.controller.ReplicasManager;
import org.apache.rocketmq.broker.filter.ConsumerFilterData;
import org.apache.rocketmq.broker.filter.ExpressionMessageFilter;
+import org.apache.rocketmq.broker.metrics.BrokerMetricsManager;
+import org.apache.rocketmq.broker.metrics.InvocationStatus;
import org.apache.rocketmq.broker.plugin.BrokerAttachedPlugin;
import org.apache.rocketmq.broker.subscription.SubscriptionGroupManager;
import org.apache.rocketmq.broker.transaction.queue.TransactionalMessageUtil;
@@ -212,7 +215,8 @@
import org.apache.rocketmq.store.timer.TimerCheckpoint;
import org.apache.rocketmq.store.timer.TimerMessageStore;
import org.apache.rocketmq.store.util.LibC;
-
+import static org.apache.rocketmq.broker.metrics.BrokerMetricsConstant.LABEL_IS_SYSTEM;
+import static org.apache.rocketmq.broker.metrics.BrokerMetricsConstant.LABEL_INVOCATION_STATUS;
import static org.apache.rocketmq.remoting.protocol.RemotingCommand.buildErrorResponse;
public class AdminBrokerProcessor implements NettyRequestProcessor {
@@ -465,45 +469,46 @@ private synchronized RemotingCommand updateAndCreateTopic(ChannelHandlerContext
String topic = requestHeader.getTopic();
- TopicValidator.ValidateTopicResult result = TopicValidator.validateTopic(topic);
- if (!result.isValid()) {
- response.setCode(ResponseCode.SYSTEM_ERROR);
- response.setRemark(result.getRemark());
- return response;
- }
- if (brokerController.getBrokerConfig().isValidateSystemTopicWhenUpdateTopic()) {
- if (TopicValidator.isSystemTopic(topic)) {
+ long executionTime;
+ try {
+ TopicValidator.ValidateTopicResult result = TopicValidator.validateTopic(topic);
+ if (!result.isValid()) {
response.setCode(ResponseCode.SYSTEM_ERROR);
- response.setRemark("The topic[" + topic + "] is conflict with system topic.");
+ response.setRemark(result.getRemark());
return response;
}
- }
-
- TopicConfig topicConfig = new TopicConfig(topic);
- topicConfig.setReadQueueNums(requestHeader.getReadQueueNums());
- topicConfig.setWriteQueueNums(requestHeader.getWriteQueueNums());
- topicConfig.setTopicFilterType(requestHeader.getTopicFilterTypeEnum());
- topicConfig.setPerm(requestHeader.getPerm());
- topicConfig.setTopicSysFlag(requestHeader.getTopicSysFlag() == null ? 0 : requestHeader.getTopicSysFlag());
- topicConfig.setOrder(requestHeader.getOrder());
- String attributesModification = requestHeader.getAttributes();
- topicConfig.setAttributes(AttributeParser.parseToMap(attributesModification));
+ if (brokerController.getBrokerConfig().isValidateSystemTopicWhenUpdateTopic()) {
+ if (TopicValidator.isSystemTopic(topic)) {
+ response.setCode(ResponseCode.SYSTEM_ERROR);
+ response.setRemark("The topic[" + topic + "] is conflict with system topic.");
+ return response;
+ }
+ }
- if (topicConfig.getTopicMessageType() == TopicMessageType.MIXED
- && !brokerController.getBrokerConfig().isEnableMixedMessageType()) {
- response.setCode(ResponseCode.SYSTEM_ERROR);
- response.setRemark("MIXED message type is not supported.");
- return response;
- }
+ TopicConfig topicConfig = new TopicConfig(topic);
+ topicConfig.setReadQueueNums(requestHeader.getReadQueueNums());
+ topicConfig.setWriteQueueNums(requestHeader.getWriteQueueNums());
+ topicConfig.setTopicFilterType(requestHeader.getTopicFilterTypeEnum());
+ topicConfig.setPerm(requestHeader.getPerm());
+ topicConfig.setTopicSysFlag(requestHeader.getTopicSysFlag() == null ? 0 : requestHeader.getTopicSysFlag());
+ topicConfig.setOrder(requestHeader.getOrder());
+ String attributesModification = requestHeader.getAttributes();
+ topicConfig.setAttributes(AttributeParser.parseToMap(attributesModification));
+
+ if (topicConfig.getTopicMessageType() == TopicMessageType.MIXED
+ && !brokerController.getBrokerConfig().isEnableMixedMessageType()) {
+ response.setCode(ResponseCode.SYSTEM_ERROR);
+ response.setRemark("MIXED message type is not supported.");
+ return response;
+ }
- if (topicConfig.equals(this.brokerController.getTopicConfigManager().getTopicConfigTable().get(topic))) {
- LOGGER.info("Broker receive request to update or create topic={}, but topicConfig has no changes , so idempotent, caller address={}",
- requestHeader.getTopic(), RemotingHelper.parseChannelRemoteAddr(ctx.channel()));
- response.setCode(ResponseCode.SUCCESS);
- return response;
- }
+ if (topicConfig.equals(this.brokerController.getTopicConfigManager().getTopicConfigTable().get(topic))) {
+ LOGGER.info("Broker receive request to update or create topic={}, but topicConfig has no changes , so idempotent, caller address={}",
+ requestHeader.getTopic(), RemotingHelper.parseChannelRemoteAddr(ctx.channel()));
+ response.setCode(ResponseCode.SUCCESS);
+ return response;
+ }
- try {
this.brokerController.getTopicConfigManager().updateTopicConfig(topicConfig);
if (brokerController.getBrokerConfig().isEnableSingleTopicRegister()) {
this.brokerController.registerSingleTopicAll(topicConfig);
@@ -517,7 +522,16 @@ private synchronized RemotingCommand updateAndCreateTopic(ChannelHandlerContext
response.setRemark(e.getMessage());
return response;
}
- long executionTime = System.currentTimeMillis() - startTime;
+ finally {
+ executionTime = System.currentTimeMillis() - startTime;
+ InvocationStatus status = response.getCode() == ResponseCode.SUCCESS ?
+ InvocationStatus.SUCCESS : InvocationStatus.FAILURE;
+ Attributes attributes = BrokerMetricsManager.newAttributesBuilder()
+ .put(LABEL_INVOCATION_STATUS, status.getName())
+ .put(LABEL_IS_SYSTEM, TopicValidator.isSystemTopic(topic))
+ .build();
+ BrokerMetricsManager.topicCreateExecuteTime.record(executionTime, attributes);
+ }
LOGGER.info("executionTime of create topic:{} is {} ms" , topic, executionTime);
return response;
}
@@ -1468,6 +1482,12 @@ private RemotingCommand updateAndCreateSubscriptionGroup(ChannelHandlerContext c
response.setRemark(null);
long executionTime = System.currentTimeMillis() - startTime;
LOGGER.info("executionTime of create subscriptionGroup:{} is {} ms" ,config.getGroupName() ,executionTime);
+ InvocationStatus status = response.getCode() == ResponseCode.SUCCESS ?
+ InvocationStatus.SUCCESS : InvocationStatus.FAILURE;
+ Attributes attributes = BrokerMetricsManager.newAttributesBuilder()
+ .put(LABEL_INVOCATION_STATUS, status.getName())
+ .build();
+ BrokerMetricsManager.consumerGroupCreateExecuteTime.record(executionTime, attributes);
return response;
}
From a430796e4b975e9ef724ff61e84e47517e8aee62 Mon Sep 17 00:00:00 2001
From: Stephanie0002 <55239858+Stephanie0002@users.noreply.github.com>
Date: Fri, 31 May 2024 17:18:30 +0800
Subject: [PATCH 020/265] [ISSUE #8223] Add two metrics rocketmq_topic_number
and rocketmq_consumer_group_number (#8225)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* Add tow metric createTopicTime and createSubscriptionTime in broker
* roll back BrokerConfig.java
* Add metric view of createTopicTime and createSubscriptionTime in broker
* Add two metric rocketmq_active_topic_number and rocketmq_active_subscription_number
* Add two metric rocketmq_active_topic_number and rocketmq_active_subscription_number
Signed-off-by: 黄梓淇
---------
Signed-off-by: 黄梓淇
Co-authored-by: 黄梓淇
---
.../broker/metrics/BrokerMetricsConstant.java | 2 ++
.../broker/metrics/BrokerMetricsManager.java | 15 +++++++++++++++
2 files changed, 17 insertions(+)
diff --git a/broker/src/main/java/org/apache/rocketmq/broker/metrics/BrokerMetricsConstant.java b/broker/src/main/java/org/apache/rocketmq/broker/metrics/BrokerMetricsConstant.java
index 0af2ac616c4..4b319f12f6f 100644
--- a/broker/src/main/java/org/apache/rocketmq/broker/metrics/BrokerMetricsConstant.java
+++ b/broker/src/main/java/org/apache/rocketmq/broker/metrics/BrokerMetricsConstant.java
@@ -21,6 +21,8 @@ public class BrokerMetricsConstant {
public static final String GAUGE_PROCESSOR_WATERMARK = "rocketmq_processor_watermark";
public static final String GAUGE_BROKER_PERMISSION = "rocketmq_broker_permission";
+ public static final String GAUGE_TOPIC_NUM = "rocketmq_topic_number";
+ public static final String GAUGE_CONSUMER_GROUP_NUM = "rocketmq_consumer_group_number";
public static final String COUNTER_MESSAGES_IN_TOTAL = "rocketmq_messages_in_total";
public static final String COUNTER_MESSAGES_OUT_TOTAL = "rocketmq_messages_out_total";
diff --git a/broker/src/main/java/org/apache/rocketmq/broker/metrics/BrokerMetricsManager.java b/broker/src/main/java/org/apache/rocketmq/broker/metrics/BrokerMetricsManager.java
index 0050a0dcd4c..d8d94f8e69a 100644
--- a/broker/src/main/java/org/apache/rocketmq/broker/metrics/BrokerMetricsManager.java
+++ b/broker/src/main/java/org/apache/rocketmq/broker/metrics/BrokerMetricsManager.java
@@ -81,6 +81,8 @@
import static org.apache.rocketmq.broker.metrics.BrokerMetricsConstant.COUNTER_ROLLBACK_MESSAGES_TOTAL;
import static org.apache.rocketmq.broker.metrics.BrokerMetricsConstant.COUNTER_THROUGHPUT_IN_TOTAL;
import static org.apache.rocketmq.broker.metrics.BrokerMetricsConstant.COUNTER_THROUGHPUT_OUT_TOTAL;
+import static org.apache.rocketmq.broker.metrics.BrokerMetricsConstant.GAUGE_TOPIC_NUM;
+import static org.apache.rocketmq.broker.metrics.BrokerMetricsConstant.GAUGE_CONSUMER_GROUP_NUM;
import static org.apache.rocketmq.broker.metrics.BrokerMetricsConstant.GAUGE_BROKER_PERMISSION;
import static org.apache.rocketmq.broker.metrics.BrokerMetricsConstant.GAUGE_CONSUMER_CONNECTIONS;
import static org.apache.rocketmq.broker.metrics.BrokerMetricsConstant.GAUGE_CONSUMER_INFLIGHT_MESSAGES;
@@ -131,6 +133,9 @@ public class BrokerMetricsManager {
// broker stats metrics
public static ObservableLongGauge processorWatermark = new NopObservableLongGauge();
public static ObservableLongGauge brokerPermission = new NopObservableLongGauge();
+ public static ObservableLongGauge topicNum = new NopObservableLongGauge();
+ public static ObservableLongGauge consumerGroupNum = new NopObservableLongGauge();
+
// request metrics
public static LongCounter messagesInTotal = new NopLongCounter();
@@ -490,6 +495,16 @@ private void initStatsMetrics() {
.setDescription("Broker permission")
.ofLongs()
.buildWithCallback(measurement -> measurement.record(brokerConfig.getBrokerPermission(), newAttributesBuilder().build()));
+
+ topicNum = brokerMeter.gaugeBuilder(GAUGE_TOPIC_NUM)
+ .setDescription("Active topic number")
+ .ofLongs()
+ .buildWithCallback(measurement -> measurement.record(brokerController.getTopicConfigManager().getTopicConfigTable().size(), newAttributesBuilder().build()));
+
+ consumerGroupNum = brokerMeter.gaugeBuilder(GAUGE_CONSUMER_GROUP_NUM)
+ .setDescription("Active subscription group number")
+ .ofLongs()
+ .buildWithCallback(measurement -> measurement.record(brokerController.getSubscriptionGroupManager().getSubscriptionGroupTable().size(), newAttributesBuilder().build()));
}
private void initRequestMetrics() {
From 144b22ba7d557619275a7b4a343c7350836b0b2c Mon Sep 17 00:00:00 2001
From: mxsm
Date: Sun, 2 Jun 2024 07:13:15 +0800
Subject: [PATCH 021/265] [ISSUE #8235]Add @Override annotation for
handleDiskFlush method (#8236)
---
store/src/main/java/org/apache/rocketmq/store/CommitLog.java | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/store/src/main/java/org/apache/rocketmq/store/CommitLog.java b/store/src/main/java/org/apache/rocketmq/store/CommitLog.java
index cc29cca5d94..1174eca1bab 100644
--- a/store/src/main/java/org/apache/rocketmq/store/CommitLog.java
+++ b/store/src/main/java/org/apache/rocketmq/store/CommitLog.java
@@ -2116,7 +2116,8 @@ public DefaultFlushManager() {
this.commitRealTimeService = new CommitLog.CommitRealTimeService();
}
- @Override public void start() {
+ @Override
+ public void start() {
this.flushCommitLogService.start();
if (defaultMessageStore.isTransientStorePoolEnable()) {
@@ -2124,6 +2125,7 @@ public DefaultFlushManager() {
}
}
+ @Override
public void handleDiskFlush(AppendMessageResult result, PutMessageResult putMessageResult,
MessageExt messageExt) {
// Synchronization flush
From 949991e0aabb0e05b78a087292a1b4e0f3e969cf Mon Sep 17 00:00:00 2001
From: hqbfz <125714719+3424672656@users.noreply.github.com>
Date: Mon, 3 Jun 2024 15:38:33 +0800
Subject: [PATCH 022/265] [ISSUE #8241] Remove duplicate code
---
.../client/impl/consumer/DefaultMQPushConsumerImpl.java | 2 --
1 file changed, 2 deletions(-)
diff --git a/client/src/main/java/org/apache/rocketmq/client/impl/consumer/DefaultMQPushConsumerImpl.java b/client/src/main/java/org/apache/rocketmq/client/impl/consumer/DefaultMQPushConsumerImpl.java
index 3ac33156b04..3e832e5a9a3 100644
--- a/client/src/main/java/org/apache/rocketmq/client/impl/consumer/DefaultMQPushConsumerImpl.java
+++ b/client/src/main/java/org/apache/rocketmq/client/impl/consumer/DefaultMQPushConsumerImpl.java
@@ -581,8 +581,6 @@ public void onSuccess(PopResult popResult) {
DefaultMQPushConsumerImpl.this.executePopPullRequestImmediately(popRequest);
break;
case POLLING_FULL:
- DefaultMQPushConsumerImpl.this.executePopPullRequestLater(popRequest, pullTimeDelayMillsWhenException);
- break;
default:
DefaultMQPushConsumerImpl.this.executePopPullRequestLater(popRequest, pullTimeDelayMillsWhenException);
break;
From 7145964b4a8db5d29a0af51b352efa2c342122aa Mon Sep 17 00:00:00 2001
From: dingshuangxi888
Date: Tue, 4 Jun 2024 13:46:16 +0800
Subject: [PATCH 023/265] [ISSUE 8230] fix the acl for
NotifyClientTerminationRequest because group can be null. (#8231)
---
.../org/apache/rocketmq/acl/plain/PlainAccessResource.java | 5 ++++-
.../builder/DefaultAuthorizationContextBuilder.java | 4 +++-
2 files changed, 7 insertions(+), 2 deletions(-)
diff --git a/acl/src/main/java/org/apache/rocketmq/acl/plain/PlainAccessResource.java b/acl/src/main/java/org/apache/rocketmq/acl/plain/PlainAccessResource.java
index ccf2418e409..ef05fa6adbb 100644
--- a/acl/src/main/java/org/apache/rocketmq/acl/plain/PlainAccessResource.java
+++ b/acl/src/main/java/org/apache/rocketmq/acl/plain/PlainAccessResource.java
@@ -40,6 +40,7 @@
import java.util.SortedMap;
import java.util.TreeMap;
import org.apache.commons.codec.DecoderException;
+import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.rocketmq.acl.AccessResource;
import org.apache.rocketmq.acl.common.AclException;
@@ -268,7 +269,9 @@ public static PlainAccessResource parse(GeneratedMessageV3 messageV3, Authentica
}
} else if (NotifyClientTerminationRequest.getDescriptor().getFullName().equals(rpcFullName)) {
NotifyClientTerminationRequest request = (NotifyClientTerminationRequest) messageV3;
- accessResource.addGroupResourceAndPerm(request.getGroup(), Permission.SUB);
+ if (StringUtils.isNotBlank(request.getGroup().getName())) {
+ accessResource.addGroupResourceAndPerm(request.getGroup(), Permission.SUB);
+ }
} else if (QueryRouteRequest.getDescriptor().getFullName().equals(rpcFullName)) {
QueryRouteRequest request = (QueryRouteRequest) messageV3;
accessResource.addResourceAndPerm(request.getTopic(), Permission.ANY);
diff --git a/auth/src/main/java/org/apache/rocketmq/auth/authorization/builder/DefaultAuthorizationContextBuilder.java b/auth/src/main/java/org/apache/rocketmq/auth/authorization/builder/DefaultAuthorizationContextBuilder.java
index d6d1556ca20..02d5df236f5 100644
--- a/auth/src/main/java/org/apache/rocketmq/auth/authorization/builder/DefaultAuthorizationContextBuilder.java
+++ b/auth/src/main/java/org/apache/rocketmq/auth/authorization/builder/DefaultAuthorizationContextBuilder.java
@@ -129,7 +129,9 @@ public List build(Metadata metadata, GeneratedMessa
}
if (message instanceof NotifyClientTerminationRequest) {
NotifyClientTerminationRequest request = (NotifyClientTerminationRequest) message;
- result = newGroupSubContexts(metadata, request.getGroup());
+ if (StringUtils.isNotBlank(request.getGroup().getName())) {
+ result = newGroupSubContexts(metadata, request.getGroup());
+ }
}
if (message instanceof ChangeInvisibleDurationRequest) {
ChangeInvisibleDurationRequest request = (ChangeInvisibleDurationRequest) message;
From 7558850df1773ffa67abae4f1b2ceaa7d5060e09 Mon Sep 17 00:00:00 2001
From: liuzc9 <90489940+liuzc9@users.noreply.github.com>
Date: Wed, 5 Jun 2024 09:10:56 +0800
Subject: [PATCH 024/265] [ISSUE #8245]Fix typo in user_guide.md
---
docs/cn/msg_trace/user_guide.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/docs/cn/msg_trace/user_guide.md b/docs/cn/msg_trace/user_guide.md
index 9cf139fd347..a04c2601f48 100644
--- a/docs/cn/msg_trace/user_guide.md
+++ b/docs/cn/msg_trace/user_guide.md
@@ -103,7 +103,7 @@ RocketMQ的消息轨迹特性支持两种存储轨迹数据的方式:
### 4.4 使用mqadmin命令发送和查看轨迹
- 发送消息
```shell
-./mqadmin sendMessage -m true --topic some-topic-name -n 127.0.0.1:9876 -p "your meesgae content"
+./mqadmin sendMessage -m true --topic some-topic-name -n 127.0.0.1:9876 -p "your message content"
```
- 查询轨迹
```shell
From 155bcbf23cf026d94a3233d5944571c3532a130d Mon Sep 17 00:00:00 2001
From: lizhimins <707364882@qq.com>
Date: Thu, 6 Jun 2024 15:50:52 +0800
Subject: [PATCH 025/265] [ISSUE #8197] Support fast filter message in tiered
storage (#8198)
---
.../core/MessageStoreFetcherImpl.java | 39 ++++---
.../core/MessageStoreFetcherImplTest.java | 102 +++++++++++++++++-
2 files changed, 125 insertions(+), 16 deletions(-)
diff --git a/tieredstore/src/main/java/org/apache/rocketmq/tieredstore/core/MessageStoreFetcherImpl.java b/tieredstore/src/main/java/org/apache/rocketmq/tieredstore/core/MessageStoreFetcherImpl.java
index 4ecf79658ee..b72ebe86241 100644
--- a/tieredstore/src/main/java/org/apache/rocketmq/tieredstore/core/MessageStoreFetcherImpl.java
+++ b/tieredstore/src/main/java/org/apache/rocketmq/tieredstore/core/MessageStoreFetcherImpl.java
@@ -50,7 +50,7 @@ public class MessageStoreFetcherImpl implements MessageStoreFetcher {
private static final Logger log = LoggerFactory.getLogger(MessageStoreUtil.TIERED_STORE_LOGGER_NAME);
- private static final String CACHE_KEY_FORMAT = "%s@%d@%d";
+ protected static final String CACHE_KEY_FORMAT = "%s@%d@%d";
private final String brokerName;
private final MetadataStore metadataStore;
@@ -113,22 +113,36 @@ protected SelectBufferResult getMessageFromCache(FlatMessageFile flatFile, long
buffer.getByteBuffer().asReadOnlyBuffer(), buffer.getStartOffset(), buffer.getSize(), buffer.getTagCode());
}
- protected GetMessageResultExt getMessageFromCache(FlatMessageFile flatFile, long offset, int maxCount) {
+ protected GetMessageResultExt getMessageFromCache(
+ FlatMessageFile flatFile, long offset, int maxCount, MessageFilter messageFilter) {
GetMessageResultExt result = new GetMessageResultExt();
- for (long i = offset; i < offset + maxCount; i++) {
- SelectBufferResult buffer = getMessageFromCache(flatFile, i);
+ int interval = storeConfig.getReadAheadMessageCountThreshold();
+ for (long current = offset, end = offset + interval; current < end; current++) {
+ SelectBufferResult buffer = getMessageFromCache(flatFile, current);
if (buffer == null) {
+ result.setNextBeginOffset(current);
break;
}
+ result.setNextBeginOffset(current + 1);
+ if (messageFilter != null) {
+ if (!messageFilter.isMatchedByConsumeQueue(buffer.getTagCode(), null)) {
+ continue;
+ }
+ if (!messageFilter.isMatchedByCommitLog(buffer.getByteBuffer().slice(), null)) {
+ continue;
+ }
+ }
SelectMappedBufferResult bufferResult = new SelectMappedBufferResult(
buffer.getStartOffset(), buffer.getByteBuffer(), buffer.getSize(), null);
- result.addMessageExt(bufferResult, i, buffer.getTagCode());
+ result.addMessageExt(bufferResult, current, buffer.getTagCode());
+ if (result.getMessageCount() == maxCount) {
+ break;
+ }
}
result.setStatus(result.getMessageCount() > 0 ?
- GetMessageStatus.FOUND : GetMessageStatus.OFFSET_OVERFLOW_ONE);
+ GetMessageStatus.FOUND : GetMessageStatus.NO_MATCHED_MESSAGE);
result.setMinOffset(flatFile.getConsumeQueueMinOffset());
result.setMaxOffset(flatFile.getConsumeQueueCommitOffset());
- result.setNextBeginOffset(offset + result.getMessageCount());
return result;
}
@@ -161,11 +175,11 @@ protected CompletableFuture fetchMessageThenPutToCache(
});
}
- public CompletableFuture getMessageFromCacheAsync(
- FlatMessageFile flatFile, String group, long queueOffset, int maxCount) {
+ public CompletableFuture getMessageFromCacheAsync(
+ FlatMessageFile flatFile, String group, long queueOffset, int maxCount, MessageFilter messageFilter) {
MessageQueue mq = flatFile.getMessageQueue();
- GetMessageResultExt result = getMessageFromCache(flatFile, queueOffset, maxCount);
+ GetMessageResultExt result = getMessageFromCache(flatFile, queueOffset, maxCount, messageFilter);
if (GetMessageStatus.FOUND.equals(result.getStatus())) {
log.debug("MessageFetcher cache hit, group={}, topic={}, queueId={}, offset={}, maxCount={}, resultSize={}, lag={}",
@@ -179,7 +193,7 @@ public CompletableFuture getMessageFromCacheAsync(
group, mq.getTopic(), mq.getQueueId(), queueOffset, maxCount, result.getMaxOffset() - result.getNextBeginOffset());
return fetchMessageThenPutToCache(flatFile, queueOffset, storeConfig.getReadAheadMessageCountThreshold())
- .thenApply(maxOffset -> getMessageFromCache(flatFile, queueOffset, maxCount));
+ .thenApply(maxOffset -> getMessageFromCache(flatFile, queueOffset, maxCount, messageFilter));
}
public CompletableFuture getMessageFromTieredStoreAsync(
@@ -333,8 +347,7 @@ public CompletableFuture getMessageAsync(
boolean cacheBusy = fetcherCache.estimatedSize() > memoryMaxSize * 0.8;
if (storeConfig.isReadAheadCacheEnable() && !cacheBusy) {
- return getMessageFromCacheAsync(flatFile, group, queueOffset, maxCount)
- .thenApply(messageResultExt -> messageResultExt.doFilterMessage(messageFilter));
+ return getMessageFromCacheAsync(flatFile, group, queueOffset, maxCount, messageFilter);
} else {
return getMessageFromTieredStoreAsync(flatFile, queueOffset, maxCount)
.thenApply(messageResultExt -> messageResultExt.doFilterMessage(messageFilter));
diff --git a/tieredstore/src/test/java/org/apache/rocketmq/tieredstore/core/MessageStoreFetcherImplTest.java b/tieredstore/src/test/java/org/apache/rocketmq/tieredstore/core/MessageStoreFetcherImplTest.java
index 7b8b17d5bbc..fdcdec066fe 100644
--- a/tieredstore/src/test/java/org/apache/rocketmq/tieredstore/core/MessageStoreFetcherImplTest.java
+++ b/tieredstore/src/test/java/org/apache/rocketmq/tieredstore/core/MessageStoreFetcherImplTest.java
@@ -16,24 +16,33 @@
*/
package org.apache.rocketmq.tieredstore.core;
+import com.google.common.collect.Sets;
import java.io.IOException;
+import java.nio.ByteBuffer;
import java.time.Duration;
import java.util.concurrent.atomic.AtomicLong;
import org.apache.rocketmq.common.BoundaryType;
import org.apache.rocketmq.common.message.MessageQueue;
+import org.apache.rocketmq.remoting.protocol.heartbeat.SubscriptionData;
+import org.apache.rocketmq.store.DefaultMessageFilter;
import org.apache.rocketmq.store.GetMessageResult;
import org.apache.rocketmq.store.GetMessageStatus;
+import org.apache.rocketmq.store.MessageFilter;
import org.apache.rocketmq.store.QueryMessageResult;
import org.apache.rocketmq.tieredstore.MessageStoreConfig;
import org.apache.rocketmq.tieredstore.TieredMessageStore;
-import org.apache.rocketmq.tieredstore.common.GetMessageResultExt;
+import org.apache.rocketmq.tieredstore.common.SelectBufferResult;
import org.apache.rocketmq.tieredstore.file.FlatMessageFile;
+import org.apache.rocketmq.tieredstore.util.MessageFormatUtilTest;
import org.apache.rocketmq.tieredstore.util.MessageStoreUtilTest;
import org.awaitility.Awaitility;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
+import org.mockito.Mockito;
+
+import static org.apache.rocketmq.tieredstore.core.MessageStoreFetcherImpl.CACHE_KEY_FORMAT;
public class MessageStoreFetcherImplTest {
@@ -164,8 +173,8 @@ public void getMessageFromCacheTest() throws Exception {
AtomicLong offset = new AtomicLong(100L);
FlatMessageFile flatFile = dispatcherTest.fileStore.getFlatFile(mq);
Awaitility.await().atMost(Duration.ofSeconds(10)).until(() -> {
- GetMessageResultExt getMessageResult =
- fetcher.getMessageFromCacheAsync(flatFile, groupName, offset.get(), batchSize).join();
+ GetMessageResult getMessageResult =
+ fetcher.getMessageFromCacheAsync(flatFile, groupName, offset.get(), batchSize, null).join();
offset.set(getMessageResult.getNextBeginOffset());
times.incrementAndGet();
return offset.get() == 200L;
@@ -173,6 +182,93 @@ public void getMessageFromCacheTest() throws Exception {
Assert.assertEquals(100 / times.get(), batchSize);
}
+ @Test
+ public void getMessageFromCacheTagFilterTest() throws Exception {
+ dispatcherTest.dispatchFromCommitLogTest();
+ mq = dispatcherTest.mq;
+ messageStore = dispatcherTest.messageStore;
+ storeConfig = dispatcherTest.storeConfig;
+
+ storeConfig.setReadAheadCacheEnable(true);
+ fetcher = new MessageStoreFetcherImpl(messageStore);
+
+ FlatMessageFile flatFile = Mockito.mock(FlatMessageFile.class);
+ Mockito.when(flatFile.getMessageQueue()).thenReturn(mq);
+ Mockito.when(flatFile.getConsumeQueueMinOffset()).thenReturn(100L);
+ Mockito.when(flatFile.getConsumeQueueMaxOffset()).thenReturn(200L);
+
+ for (int i = 100; i < 200; i++) {
+ ByteBuffer buffer = MessageFormatUtilTest.buildMockedMessageBuffer();
+ SelectBufferResult bufferResult = new SelectBufferResult(buffer, i, buffer.remaining(), i % 2);
+ fetcher.getFetcherCache().put(
+ String.format(CACHE_KEY_FORMAT, mq.getTopic(), mq.getQueueId(), i), bufferResult);
+ }
+
+ SubscriptionData subscriptionData = new SubscriptionData();
+ subscriptionData.setSubString("1 || 2");
+ subscriptionData.setCodeSet(Sets.newHashSet(1, 2));
+ MessageFilter filter = new DefaultMessageFilter(subscriptionData);
+
+ GetMessageResult getMessageResult =
+ fetcher.getMessageFromCacheAsync(flatFile, groupName, 100L, 32, filter).join();
+ Assert.assertEquals(GetMessageStatus.FOUND, getMessageResult.getStatus());
+ Assert.assertEquals(32, getMessageResult.getMessageCount());
+ Assert.assertEquals(164L, getMessageResult.getNextBeginOffset());
+
+ getMessageResult =
+ fetcher.getMessageFromCacheAsync(flatFile, groupName, 164L, 32, filter).join();
+ Assert.assertEquals(GetMessageStatus.FOUND, getMessageResult.getStatus());
+ Assert.assertEquals(18, getMessageResult.getMessageCount());
+ Assert.assertEquals(200L, getMessageResult.getNextBeginOffset());
+
+ getMessageResult =
+ fetcher.getMessageFromCacheAsync(flatFile, groupName, 200L, 32, filter).join();
+ Assert.assertEquals(GetMessageStatus.NO_MATCHED_MESSAGE, getMessageResult.getStatus());
+ Assert.assertEquals(200L, getMessageResult.getNextBeginOffset());
+
+ subscriptionData.setCodeSet(Sets.newHashSet(0));
+ filter = new DefaultMessageFilter(subscriptionData);
+ getMessageResult =
+ fetcher.getMessageFromCacheAsync(flatFile, groupName, 100L, 32, filter).join();
+ Assert.assertEquals(GetMessageStatus.FOUND, getMessageResult.getStatus());
+ Assert.assertEquals(32, getMessageResult.getMessageCount());
+ Assert.assertEquals(164L - 1L, getMessageResult.getNextBeginOffset());
+ }
+
+ @Test
+ public void getMessageFromCacheTagFilter2Test() throws Exception {
+ dispatcherTest.dispatchFromCommitLogTest();
+ mq = dispatcherTest.mq;
+ messageStore = dispatcherTest.messageStore;
+ storeConfig = dispatcherTest.storeConfig;
+
+ storeConfig.setReadAheadCacheEnable(true);
+ fetcher = new MessageStoreFetcherImpl(messageStore);
+
+ FlatMessageFile flatFile = Mockito.mock(FlatMessageFile.class);
+ Mockito.when(flatFile.getMessageQueue()).thenReturn(mq);
+ Mockito.when(flatFile.getConsumeQueueMinOffset()).thenReturn(100L);
+ Mockito.when(flatFile.getConsumeQueueMaxOffset()).thenReturn(200L);
+
+ for (int i = 100; i < 200; i++) {
+ ByteBuffer buffer = MessageFormatUtilTest.buildMockedMessageBuffer();
+ SelectBufferResult bufferResult = new SelectBufferResult(buffer, i, buffer.remaining(), i - 100L);
+ fetcher.getFetcherCache().put(
+ String.format(CACHE_KEY_FORMAT, mq.getTopic(), mq.getQueueId(), i), bufferResult);
+ }
+
+ SubscriptionData subscriptionData = new SubscriptionData();
+ subscriptionData.setSubString("1 || 2");
+ subscriptionData.setCodeSet(Sets.newHashSet(10, 20));
+ MessageFilter filter = new DefaultMessageFilter(subscriptionData);
+
+ GetMessageResult getMessageResult =
+ fetcher.getMessageFromCacheAsync(flatFile, groupName, 100L, 2, filter).join();
+ Assert.assertEquals(GetMessageStatus.FOUND, getMessageResult.getStatus());
+ Assert.assertEquals(2, getMessageResult.getMessageCount());
+ Assert.assertEquals(121L, getMessageResult.getNextBeginOffset());
+ }
+
@Test
public void testGetMessageStoreTimeStampAsync() throws Exception {
this.getMessageFromTieredStoreTest();
From d1974c55353488095e5122f5ce361c150611f21a Mon Sep 17 00:00:00 2001
From: lizhimins <707364882@qq.com>
Date: Thu, 6 Jun 2024 20:19:06 +0800
Subject: [PATCH 026/265] [ISSUE #8269] Support pop consumption filter in long
polling service (#8271)
---
.../NotifyMessageArrivingListener.java | 11 +++--
.../longpolling/PopLongPollingService.java | 44 ++++++++++++++++---
.../broker/longpolling/PopRequest.java | 25 ++++++++---
.../broker/processor/AckMessageProcessor.java | 13 +++---
.../processor/NotificationProcessor.java | 11 ++++-
.../broker/processor/PopMessageProcessor.java | 40 ++++++++++++-----
6 files changed, 107 insertions(+), 37 deletions(-)
diff --git a/broker/src/main/java/org/apache/rocketmq/broker/longpolling/NotifyMessageArrivingListener.java b/broker/src/main/java/org/apache/rocketmq/broker/longpolling/NotifyMessageArrivingListener.java
index e55ed2778ac..1ddb9f4f8e6 100644
--- a/broker/src/main/java/org/apache/rocketmq/broker/longpolling/NotifyMessageArrivingListener.java
+++ b/broker/src/main/java/org/apache/rocketmq/broker/longpolling/NotifyMessageArrivingListener.java
@@ -36,9 +36,12 @@ public NotifyMessageArrivingListener(final PullRequestHoldService pullRequestHol
@Override
public void arriving(String topic, int queueId, long logicOffset, long tagsCode,
long msgStoreTime, byte[] filterBitMap, Map properties) {
- this.pullRequestHoldService.notifyMessageArriving(topic, queueId, logicOffset, tagsCode,
- msgStoreTime, filterBitMap, properties);
- this.popMessageProcessor.notifyMessageArriving(topic, queueId);
- this.notificationProcessor.notifyMessageArriving(topic, queueId);
+
+ this.pullRequestHoldService.notifyMessageArriving(
+ topic, queueId, logicOffset, tagsCode, msgStoreTime, filterBitMap, properties);
+ this.popMessageProcessor.notifyMessageArriving(
+ topic, queueId, tagsCode, msgStoreTime, filterBitMap, properties);
+ this.notificationProcessor.notifyMessageArriving(
+ topic, queueId, tagsCode, msgStoreTime, filterBitMap, properties);
}
}
diff --git a/broker/src/main/java/org/apache/rocketmq/broker/longpolling/PopLongPollingService.java b/broker/src/main/java/org/apache/rocketmq/broker/longpolling/PopLongPollingService.java
index a768fe4b9c4..b5179114f37 100644
--- a/broker/src/main/java/org/apache/rocketmq/broker/longpolling/PopLongPollingService.java
+++ b/broker/src/main/java/org/apache/rocketmq/broker/longpolling/PopLongPollingService.java
@@ -35,6 +35,9 @@
import org.apache.rocketmq.remoting.netty.NettyRequestProcessor;
import org.apache.rocketmq.remoting.netty.RequestTask;
import org.apache.rocketmq.remoting.protocol.RemotingCommand;
+import org.apache.rocketmq.remoting.protocol.heartbeat.SubscriptionData;
+import org.apache.rocketmq.store.ConsumeQueueExt;
+import org.apache.rocketmq.store.MessageFilter;
import static org.apache.rocketmq.broker.longpolling.PollingResult.NOT_POLLING;
import static org.apache.rocketmq.broker.longpolling.PollingResult.POLLING_FULL;
@@ -147,39 +150,61 @@ public void run() {
}
public void notifyMessageArrivingWithRetryTopic(final String topic, final int queueId) {
+ this.notifyMessageArrivingWithRetryTopic(topic, queueId, null, 0L, null, null);
+ }
+
+ public void notifyMessageArrivingWithRetryTopic(final String topic, final int queueId,
+ Long tagsCode, long msgStoreTime, byte[] filterBitMap, Map properties) {
String notifyTopic;
if (KeyBuilder.isPopRetryTopicV2(topic)) {
notifyTopic = KeyBuilder.parseNormalTopic(topic);
} else {
notifyTopic = topic;
}
- notifyMessageArriving(notifyTopic, queueId);
+ notifyMessageArriving(notifyTopic, queueId, tagsCode, msgStoreTime, filterBitMap, properties);
}
- public void notifyMessageArriving(final String topic, final int queueId) {
+ public void notifyMessageArriving(final String topic, final int queueId,
+ Long tagsCode, long msgStoreTime, byte[] filterBitMap, Map properties) {
ConcurrentHashMap cids = topicCidMap.get(topic);
if (cids == null) {
return;
}
for (Map.Entry cid : cids.entrySet()) {
if (queueId >= 0) {
- notifyMessageArriving(topic, cid.getKey(), -1);
+ notifyMessageArriving(topic, -1, cid.getKey(), tagsCode, msgStoreTime, filterBitMap, properties);
}
- notifyMessageArriving(topic, cid.getKey(), queueId);
+ notifyMessageArriving(topic, queueId, cid.getKey(), tagsCode, msgStoreTime, filterBitMap, properties);
}
}
- public boolean notifyMessageArriving(final String topic, final String cid, final int queueId) {
+ public boolean notifyMessageArriving(final String topic, final int queueId, final String cid,
+ Long tagsCode, long msgStoreTime, byte[] filterBitMap, Map properties) {
ConcurrentSkipListSet remotingCommands = pollingMap.get(KeyBuilder.buildPollingKey(topic, cid, queueId));
if (remotingCommands == null || remotingCommands.isEmpty()) {
return false;
}
+
PopRequest popRequest = pollRemotingCommands(remotingCommands);
if (popRequest == null) {
return false;
}
+
+ if (popRequest.getMessageFilter() != null && popRequest.getSubscriptionData() != null) {
+ boolean match = popRequest.getMessageFilter().isMatchedByConsumeQueue(tagsCode,
+ new ConsumeQueueExt.CqExtUnit(tagsCode, msgStoreTime, filterBitMap));
+ if (match && properties != null) {
+ match = popRequest.getMessageFilter().isMatchedByCommitLog(null, properties);
+ }
+ if (!match) {
+ remotingCommands.add(popRequest);
+ totalPollingNum.incrementAndGet();
+ return false;
+ }
+ }
+
if (brokerController.getBrokerConfig().isEnablePopLog()) {
- POP_LOGGER.info("lock release , new msg arrive , wakeUp : {}", popRequest);
+ POP_LOGGER.info("lock release, new msg arrive, wakeUp: {}", popRequest);
}
return wakeUp(popRequest);
}
@@ -221,6 +246,11 @@ public boolean wakeUp(final PopRequest request) {
*/
public PollingResult polling(final ChannelHandlerContext ctx, RemotingCommand remotingCommand,
final PollingHeader requestHeader) {
+ return this.polling(ctx, remotingCommand, requestHeader, null, null);
+ }
+
+ public PollingResult polling(final ChannelHandlerContext ctx, RemotingCommand remotingCommand,
+ final PollingHeader requestHeader, SubscriptionData subscriptionData, MessageFilter messageFilter) {
if (requestHeader.getPollTime() <= 0 || this.isStopped()) {
return NOT_POLLING;
}
@@ -234,7 +264,7 @@ public PollingResult polling(final ChannelHandlerContext ctx, RemotingCommand re
}
cids.putIfAbsent(requestHeader.getConsumerGroup(), Byte.MIN_VALUE);
long expired = requestHeader.getBornTime() + requestHeader.getPollTime();
- final PopRequest request = new PopRequest(remotingCommand, ctx, expired);
+ final PopRequest request = new PopRequest(remotingCommand, ctx, expired, subscriptionData, messageFilter);
boolean isFull = totalPollingNum.get() >= this.brokerController.getBrokerConfig().getMaxPopPollingSize();
if (isFull) {
POP_LOGGER.info("polling {}, result POLLING_FULL, total:{}", remotingCommand, totalPollingNum.get());
diff --git a/broker/src/main/java/org/apache/rocketmq/broker/longpolling/PopRequest.java b/broker/src/main/java/org/apache/rocketmq/broker/longpolling/PopRequest.java
index a45bcce9f60..0419dbf637d 100644
--- a/broker/src/main/java/org/apache/rocketmq/broker/longpolling/PopRequest.java
+++ b/broker/src/main/java/org/apache/rocketmq/broker/longpolling/PopRequest.java
@@ -16,28 +16,35 @@
*/
package org.apache.rocketmq.broker.longpolling;
+import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import java.util.Comparator;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicLong;
-
import org.apache.rocketmq.remoting.protocol.RemotingCommand;
-
-import io.netty.channel.Channel;
+import org.apache.rocketmq.remoting.protocol.heartbeat.SubscriptionData;
+import org.apache.rocketmq.store.MessageFilter;
public class PopRequest {
private static final AtomicLong COUNTER = new AtomicLong(Long.MIN_VALUE);
private final RemotingCommand remotingCommand;
private final ChannelHandlerContext ctx;
- private final long expired;
private final AtomicBoolean complete = new AtomicBoolean(false);
private final long op = COUNTER.getAndIncrement();
- public PopRequest(RemotingCommand remotingCommand, ChannelHandlerContext ctx, long expired) {
+ private final long expired;
+ private final SubscriptionData subscriptionData;
+ private final MessageFilter messageFilter;
+
+ public PopRequest(RemotingCommand remotingCommand, ChannelHandlerContext ctx,
+ long expired, SubscriptionData subscriptionData, MessageFilter messageFilter) {
+
this.ctx = ctx;
this.remotingCommand = remotingCommand;
this.expired = expired;
+ this.subscriptionData = subscriptionData;
+ this.messageFilter = messageFilter;
}
public Channel getChannel() {
@@ -64,6 +71,14 @@ public long getExpired() {
return expired;
}
+ public SubscriptionData getSubscriptionData() {
+ return subscriptionData;
+ }
+
+ public MessageFilter getMessageFilter() {
+ return messageFilter;
+ }
+
@Override
public String toString() {
final StringBuilder sb = new StringBuilder("PopRequest{");
diff --git a/broker/src/main/java/org/apache/rocketmq/broker/processor/AckMessageProcessor.java b/broker/src/main/java/org/apache/rocketmq/broker/processor/AckMessageProcessor.java
index 9a56498632f..6f7b7e8a24e 100644
--- a/broker/src/main/java/org/apache/rocketmq/broker/processor/AckMessageProcessor.java
+++ b/broker/src/main/java/org/apache/rocketmq/broker/processor/AckMessageProcessor.java
@@ -297,15 +297,12 @@ protected void ackOrderly(String topic, String consumeGroup, int qId, long ackOf
qId, ackOffset,
popTime);
if (nextOffset > -1) {
- if (!this.brokerController.getConsumerOffsetManager().hasOffsetReset(
- topic, consumeGroup, qId)) {
- this.brokerController.getConsumerOffsetManager().commitOffset(channel.remoteAddress().toString(),
- consumeGroup, topic, qId, nextOffset);
+ if (!this.brokerController.getConsumerOffsetManager().hasOffsetReset(topic, consumeGroup, qId)) {
+ this.brokerController.getConsumerOffsetManager().commitOffset(
+ channel.remoteAddress().toString(), consumeGroup, topic, qId, nextOffset);
}
- if (!this.brokerController.getConsumerOrderInfoManager().checkBlock(null, topic,
- consumeGroup, qId, invisibleTime)) {
- this.brokerController.getPopMessageProcessor().notifyMessageArriving(
- topic, consumeGroup, qId);
+ if (!this.brokerController.getConsumerOrderInfoManager().checkBlock(null, topic, consumeGroup, qId, invisibleTime)) {
+ this.brokerController.getPopMessageProcessor().notifyMessageArriving(topic, qId, consumeGroup);
}
} else if (nextOffset == -1) {
String errorInfo = String.format("offset is illegal, key:%s, old:%d, commit:%d, next:%d, %s",
diff --git a/broker/src/main/java/org/apache/rocketmq/broker/processor/NotificationProcessor.java b/broker/src/main/java/org/apache/rocketmq/broker/processor/NotificationProcessor.java
index 6447500cbe6..c82725fe1e0 100644
--- a/broker/src/main/java/org/apache/rocketmq/broker/processor/NotificationProcessor.java
+++ b/broker/src/main/java/org/apache/rocketmq/broker/processor/NotificationProcessor.java
@@ -18,6 +18,7 @@
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
+import java.util.Map;
import java.util.Objects;
import java.util.Random;
import org.apache.rocketmq.broker.BrokerController;
@@ -58,8 +59,16 @@ public boolean rejectRequest() {
return false;
}
+ // When a new message is written to CommitLog, this method would be called.
+ // Suspended long polling will receive notification and be wakeup.
+ public void notifyMessageArriving(final String topic, final int queueId,
+ Long tagsCode, long msgStoreTime, byte[] filterBitMap, Map properties) {
+ this.popLongPollingService.notifyMessageArrivingWithRetryTopic(
+ topic, queueId, tagsCode, msgStoreTime, filterBitMap, properties);
+ }
+
public void notifyMessageArriving(final String topic, final int queueId) {
- popLongPollingService.notifyMessageArrivingWithRetryTopic(topic, queueId);
+ this.popLongPollingService.notifyMessageArrivingWithRetryTopic(topic, queueId);
}
@Override
diff --git a/broker/src/main/java/org/apache/rocketmq/broker/processor/PopMessageProcessor.java b/broker/src/main/java/org/apache/rocketmq/broker/processor/PopMessageProcessor.java
index 93c04a1b8de..3df4bec9842 100644
--- a/broker/src/main/java/org/apache/rocketmq/broker/processor/PopMessageProcessor.java
+++ b/broker/src/main/java/org/apache/rocketmq/broker/processor/PopMessageProcessor.java
@@ -26,6 +26,7 @@
import java.nio.ByteBuffer;
import java.util.Iterator;
import java.util.List;
+import java.util.Map;
import java.util.Map.Entry;
import java.util.Objects;
import java.util.Random;
@@ -167,15 +168,23 @@ public ConcurrentLinkedHashMap> getPol
}
public void notifyLongPollingRequestIfNeed(String topic, String group, int queueId) {
+ this.notifyLongPollingRequestIfNeed(
+ topic, group, queueId, null, 0L, null, null);
+ }
+
+ public void notifyLongPollingRequestIfNeed(String topic, String group, int queueId,
+ Long tagsCode, long msgStoreTime, byte[] filterBitMap, Map properties) {
long popBufferOffset = this.brokerController.getPopMessageProcessor().getPopBufferMergeService().getLatestOffset(topic, group, queueId);
long consumerOffset = this.brokerController.getConsumerOffsetManager().queryOffset(group, topic, queueId);
long maxOffset = this.brokerController.getMessageStore().getMaxOffsetInQueue(topic, queueId);
long offset = Math.max(popBufferOffset, consumerOffset);
if (maxOffset > offset) {
- boolean notifySuccess = popLongPollingService.notifyMessageArriving(topic, group, -1);
+ boolean notifySuccess = popLongPollingService.notifyMessageArriving(
+ topic, -1, group, tagsCode, msgStoreTime, filterBitMap, properties);
if (!notifySuccess) {
// notify pop queue
- notifySuccess = popLongPollingService.notifyMessageArriving(topic, group, queueId);
+ notifySuccess = popLongPollingService.notifyMessageArriving(
+ topic, queueId, group, tagsCode, msgStoreTime, filterBitMap, properties);
}
this.brokerController.getNotificationProcessor().notifyMessageArriving(topic, queueId);
if (this.brokerController.getBrokerConfig().isEnablePopLog()) {
@@ -185,12 +194,15 @@ public void notifyLongPollingRequestIfNeed(String topic, String group, int queue
}
}
- public void notifyMessageArriving(final String topic, final int queueId) {
- popLongPollingService.notifyMessageArrivingWithRetryTopic(topic, queueId);
+ public void notifyMessageArriving(final String topic, final int queueId,
+ Long tagsCode, long msgStoreTime, byte[] filterBitMap, Map properties) {
+ popLongPollingService.notifyMessageArrivingWithRetryTopic(
+ topic, queueId, tagsCode, msgStoreTime, filterBitMap, properties);
}
- public boolean notifyMessageArriving(final String topic, final String cid, final int queueId) {
- return popLongPollingService.notifyMessageArriving(topic, cid, queueId);
+ public void notifyMessageArriving(final String topic, final int queueId, final String cid) {
+ popLongPollingService.notifyMessageArriving(
+ topic, queueId, cid, null, 0L, null, null);
}
@Override
@@ -292,10 +304,11 @@ public RemotingCommand processRequest(final ChannelHandlerContext ctx, RemotingC
}
BrokerConfig brokerConfig = brokerController.getBrokerConfig();
+ SubscriptionData subscriptionData = null;
ExpressionMessageFilter messageFilter = null;
- if (requestHeader.getExp() != null && requestHeader.getExp().length() > 0) {
+ if (requestHeader.getExp() != null && !requestHeader.getExp().isEmpty()) {
try {
- SubscriptionData subscriptionData = FilterAPI.build(requestHeader.getTopic(), requestHeader.getExp(), requestHeader.getExpType());
+ subscriptionData = FilterAPI.build(requestHeader.getTopic(), requestHeader.getExp(), requestHeader.getExpType());
brokerController.getConsumerManager().compensateSubscribeData(requestHeader.getConsumerGroup(),
requestHeader.getTopic(), subscriptionData);
@@ -329,7 +342,7 @@ public RemotingCommand processRequest(final ChannelHandlerContext ctx, RemotingC
}
} else {
try {
- SubscriptionData subscriptionData = FilterAPI.build(requestHeader.getTopic(), "*", ExpressionType.TAG);
+ subscriptionData = FilterAPI.build(requestHeader.getTopic(), "*", ExpressionType.TAG);
brokerController.getConsumerManager().compensateSubscribeData(requestHeader.getConsumerGroup(),
requestHeader.getTopic(), subscriptionData);
@@ -403,17 +416,20 @@ public RemotingCommand processRequest(final ChannelHandlerContext ctx, RemotingC
}
final RemotingCommand finalResponse = response;
+ SubscriptionData finalSubscriptionData = subscriptionData;
getMessageFuture.thenApply(restNum -> {
if (!getMessageResult.getMessageBufferList().isEmpty()) {
finalResponse.setCode(ResponseCode.SUCCESS);
getMessageResult.setStatus(GetMessageStatus.FOUND);
if (restNum > 0) {
// all queue pop can not notify specified queue pop, and vice versa
- popLongPollingService.notifyMessageArriving(requestHeader.getTopic(), requestHeader.getConsumerGroup(),
- requestHeader.getQueueId());
+ popLongPollingService.notifyMessageArriving(
+ requestHeader.getTopic(), requestHeader.getQueueId(), requestHeader.getConsumerGroup(),
+ null, 0L, null, null);
}
} else {
- PollingResult pollingResult = popLongPollingService.polling(ctx, request, new PollingHeader(requestHeader));
+ PollingResult pollingResult = popLongPollingService.polling(
+ ctx, request, new PollingHeader(requestHeader), finalSubscriptionData, finalMessageFilter);
if (PollingResult.POLLING_SUC == pollingResult) {
return null;
} else if (PollingResult.POLLING_FULL == pollingResult) {
From d9ebe887677646ec8e969c03ea0d394a299894e0 Mon Sep 17 00:00:00 2001
From: Zhouxiang Zhan
Date: Thu, 6 Jun 2024 20:29:59 +0800
Subject: [PATCH 027/265] [ISSUE #8268] Fix pop orderly commitOffset when
NO_MATCHED_MESSAGE (#8270)
---
.../broker/processor/PopMessageProcessor.java | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/broker/src/main/java/org/apache/rocketmq/broker/processor/PopMessageProcessor.java b/broker/src/main/java/org/apache/rocketmq/broker/processor/PopMessageProcessor.java
index 3df4bec9842..0304a5dab08 100644
--- a/broker/src/main/java/org/apache/rocketmq/broker/processor/PopMessageProcessor.java
+++ b/broker/src/main/java/org/apache/rocketmq/broker/processor/PopMessageProcessor.java
@@ -638,10 +638,13 @@ private CompletableFuture popMsgFromQueue(String topic, String attemptId,
|| GetMessageStatus.MESSAGE_WAS_REMOVING.equals(result.getStatus())
|| GetMessageStatus.NO_MATCHED_LOGIC_QUEUE.equals(result.getStatus()))
&& result.getNextBeginOffset() > -1) {
- popBufferMergeService.addCkMock(requestHeader.getConsumerGroup(), topic, queueId, finalOffset,
- requestHeader.getInvisibleTime(), popTime, reviveQid, result.getNextBeginOffset(), brokerController.getBrokerConfig().getBrokerName());
-// this.brokerController.getConsumerOffsetManager().commitOffset(channel.remoteAddress().toString(), requestHeader.getConsumerGroup(), topic,
-// queueId, getMessageTmpResult.getNextBeginOffset());
+ if (isOrder) {
+ this.brokerController.getConsumerOffsetManager().commitOffset(channel.remoteAddress().toString(), requestHeader.getConsumerGroup(), topic,
+ queueId, result.getNextBeginOffset());
+ } else {
+ popBufferMergeService.addCkMock(requestHeader.getConsumerGroup(), topic, queueId, finalOffset,
+ requestHeader.getInvisibleTime(), popTime, reviveQid, result.getNextBeginOffset(), brokerController.getBrokerConfig().getBrokerName());
+ }
}
atomicRestNum.set(result.getMaxOffset() - result.getNextBeginOffset() + atomicRestNum.get());
From 4be8fd43720c8635fe135404a7fd000c00bb2a15 Mon Sep 17 00:00:00 2001
From: guyinyou <36399867+guyinyou@users.noreply.github.com>
Date: Fri, 7 Jun 2024 10:28:36 +0800
Subject: [PATCH 028/265] [ISSUE #8265] Implement Batch Creation of Topics in
RocketMQ Admin (#8267)
* add UPDATE_AND_CREATE_TOPIC_LIST
* support creating or updating topic config in batch
---------
Co-authored-by: guyinyou
Co-authored-by: gaoyang.cgy
---
.../processor/AdminBrokerProcessor.java | 81 ++++++++++++
.../broker/topic/TopicConfigManager.java | 11 +-
.../rocketmq/client/impl/MQClientAPIImpl.java | 20 +++
.../client/impl/MQClientAPIImplTest.java | 23 ++++
.../remoting/protocol/RequestCode.java | 1 +
.../body/CreateTopicListRequestBody.java | 42 +++++++
.../header/CreateTopicListRequestHeader.java | 31 +++++
.../tools/admin/DefaultMQAdminExt.java | 5 +
.../tools/admin/DefaultMQAdminExtImpl.java | 6 +
.../rocketmq/tools/admin/MQAdminExt.java | 3 +
.../tools/command/MQAdminStartup.java | 2 +
.../topic/UpdateTopicListSubCommand.java | 118 ++++++++++++++++++
.../topic/UpdateTopicListSubCommandTest.java | 41 ++++++
13 files changed, 383 insertions(+), 1 deletion(-)
create mode 100644 remoting/src/main/java/org/apache/rocketmq/remoting/protocol/body/CreateTopicListRequestBody.java
create mode 100644 remoting/src/main/java/org/apache/rocketmq/remoting/protocol/header/CreateTopicListRequestHeader.java
create mode 100644 tools/src/main/java/org/apache/rocketmq/tools/command/topic/UpdateTopicListSubCommand.java
create mode 100644 tools/src/test/java/org/apache/rocketmq/tools/command/topic/UpdateTopicListSubCommandTest.java
diff --git a/broker/src/main/java/org/apache/rocketmq/broker/processor/AdminBrokerProcessor.java b/broker/src/main/java/org/apache/rocketmq/broker/processor/AdminBrokerProcessor.java
index 40a7a461e89..44bf2a48137 100644
--- a/broker/src/main/java/org/apache/rocketmq/broker/processor/AdminBrokerProcessor.java
+++ b/broker/src/main/java/org/apache/rocketmq/broker/processor/AdminBrokerProcessor.java
@@ -116,6 +116,7 @@
import org.apache.rocketmq.remoting.protocol.body.ConsumeQueueData;
import org.apache.rocketmq.remoting.protocol.body.ConsumeStatsList;
import org.apache.rocketmq.remoting.protocol.body.ConsumerConnection;
+import org.apache.rocketmq.remoting.protocol.body.CreateTopicListRequestBody;
import org.apache.rocketmq.remoting.protocol.body.EpochEntryCache;
import org.apache.rocketmq.remoting.protocol.body.GroupList;
import org.apache.rocketmq.remoting.protocol.body.HARuntimeInfo;
@@ -243,6 +244,8 @@ public RemotingCommand processRequest(ChannelHandlerContext ctx,
switch (request.getCode()) {
case RequestCode.UPDATE_AND_CREATE_TOPIC:
return this.updateAndCreateTopic(ctx, request);
+ case RequestCode.UPDATE_AND_CREATE_TOPIC_LIST:
+ return this.updateAndCreateTopicList(ctx, request);
case RequestCode.DELETE_TOPIC_IN_BROKER:
return this.deleteTopic(ctx, request);
case RequestCode.GET_ALL_TOPIC_CONFIG:
@@ -536,6 +539,84 @@ private synchronized RemotingCommand updateAndCreateTopic(ChannelHandlerContext
return response;
}
+ private synchronized RemotingCommand updateAndCreateTopicList(ChannelHandlerContext ctx,
+ RemotingCommand request) throws RemotingCommandException {
+ long startTime = System.currentTimeMillis();
+
+ final CreateTopicListRequestBody requestBody = CreateTopicListRequestBody.decode(request.getBody(), CreateTopicListRequestBody.class);
+ List topicConfigList = requestBody.getTopicConfigList();
+
+ StringBuilder builder = new StringBuilder();
+ for (TopicConfig topicConfig : topicConfigList) {
+ builder.append(topicConfig.getTopicName()).append(";");
+ }
+ String topicNames = builder.toString();
+ LOGGER.info("AdminBrokerProcessor#updateAndCreateTopicList: topicNames: {}, called by {}", topicNames, RemotingHelper.parseChannelRemoteAddr(ctx.channel()));
+
+ final RemotingCommand response = RemotingCommand.createResponseCommand(null);
+
+ long executionTime;
+
+ try {
+ // Valid topics
+ for (TopicConfig topicConfig : topicConfigList) {
+ String topic = topicConfig.getTopicName();
+ TopicValidator.ValidateTopicResult result = TopicValidator.validateTopic(topic);
+ if (!result.isValid()) {
+ response.setCode(ResponseCode.SYSTEM_ERROR);
+ response.setRemark(result.getRemark());
+ return response;
+ }
+ if (brokerController.getBrokerConfig().isValidateSystemTopicWhenUpdateTopic()) {
+ if (TopicValidator.isSystemTopic(topic)) {
+ response.setCode(ResponseCode.SYSTEM_ERROR);
+ response.setRemark("The topic[" + topic + "] is conflict with system topic.");
+ return response;
+ }
+ }
+ if (topicConfig.getTopicMessageType() == TopicMessageType.MIXED
+ && !brokerController.getBrokerConfig().isEnableMixedMessageType()) {
+ response.setCode(ResponseCode.SYSTEM_ERROR);
+ response.setRemark("MIXED message type is not supported.");
+ return response;
+ }
+ if (topicConfig.equals(this.brokerController.getTopicConfigManager().getTopicConfigTable().get(topic))) {
+ LOGGER.info("Broker receive request to update or create topic={}, but topicConfig has no changes , so idempotent, caller address={}",
+ topic, RemotingHelper.parseChannelRemoteAddr(ctx.channel()));
+ response.setCode(ResponseCode.SUCCESS);
+ return response;
+ }
+ }
+
+ this.brokerController.getTopicConfigManager().updateTopicConfigList(topicConfigList);
+ if (brokerController.getBrokerConfig().isEnableSingleTopicRegister()) {
+ for (TopicConfig topicConfig : topicConfigList) {
+ this.brokerController.registerSingleTopicAll(topicConfig);
+ }
+ } else {
+ this.brokerController.registerIncrementBrokerData(topicConfigList, this.brokerController.getTopicConfigManager().getDataVersion());
+ }
+ response.setCode(ResponseCode.SUCCESS);
+ } catch (Exception e) {
+ LOGGER.error("Update / create topic failed for [{}]", request, e);
+ response.setCode(ResponseCode.SYSTEM_ERROR);
+ response.setRemark(e.getMessage());
+ return response;
+ }
+ finally {
+ executionTime = System.currentTimeMillis() - startTime;
+ InvocationStatus status = response.getCode() == ResponseCode.SUCCESS ?
+ InvocationStatus.SUCCESS : InvocationStatus.FAILURE;
+ Attributes attributes = BrokerMetricsManager.newAttributesBuilder()
+ .put(LABEL_INVOCATION_STATUS, status.getName())
+ .put(LABEL_IS_SYSTEM, TopicValidator.isSystemTopic(topicNames))
+ .build();
+ BrokerMetricsManager.topicCreateExecuteTime.record(executionTime, attributes);
+ }
+ LOGGER.info("executionTime of all topics:{} is {} ms" , topicNames, executionTime);
+ return response;
+ }
+
private synchronized RemotingCommand updateAndCreateStaticTopic(ChannelHandlerContext ctx,
RemotingCommand request) throws RemotingCommandException {
final RemotingCommand response = RemotingCommand.createResponseCommand(null);
diff --git a/broker/src/main/java/org/apache/rocketmq/broker/topic/TopicConfigManager.java b/broker/src/main/java/org/apache/rocketmq/broker/topic/TopicConfigManager.java
index 1ed9cbab5f8..d7c06180e9e 100644
--- a/broker/src/main/java/org/apache/rocketmq/broker/topic/TopicConfigManager.java
+++ b/broker/src/main/java/org/apache/rocketmq/broker/topic/TopicConfigManager.java
@@ -18,6 +18,7 @@
import java.util.HashMap;
import java.util.Iterator;
+import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
@@ -490,7 +491,7 @@ public void updateTopicUnitSubFlag(final String topic, final boolean hasUnitSub)
}
}
- public void updateTopicConfig(final TopicConfig topicConfig) {
+ private void updateSingleTopicConfigWithoutPersist(final TopicConfig topicConfig) {
checkNotNull(topicConfig, "topicConfig shouldn't be null");
Map newAttributes = request(topicConfig);
@@ -515,10 +516,18 @@ public void updateTopicConfig(final TopicConfig topicConfig) {
long stateMachineVersion = brokerController.getMessageStore() != null ? brokerController.getMessageStore().getStateMachineVersion() : 0;
dataVersion.nextVersion(stateMachineVersion);
+ }
+ public void updateTopicConfig(final TopicConfig topicConfig) {
+ updateSingleTopicConfigWithoutPersist(topicConfig);
this.persist(topicConfig.getTopicName(), topicConfig);
}
+ public void updateTopicConfigList(final List topicConfigList) {
+ topicConfigList.forEach(this::updateSingleTopicConfigWithoutPersist);
+ this.persist();
+ }
+
private synchronized void updateTieredStoreTopicMetadata(final TopicConfig topicConfig, Map newAttributes) {
if (!(brokerController.getMessageStore() instanceof TieredMessageStore)) {
if (newAttributes.get(TopicAttributes.TOPIC_RESERVE_TIME_ATTRIBUTE.getName()) != null) {
diff --git a/client/src/main/java/org/apache/rocketmq/client/impl/MQClientAPIImpl.java b/client/src/main/java/org/apache/rocketmq/client/impl/MQClientAPIImpl.java
index 816ae877aca..f3d7e7c70f9 100644
--- a/client/src/main/java/org/apache/rocketmq/client/impl/MQClientAPIImpl.java
+++ b/client/src/main/java/org/apache/rocketmq/client/impl/MQClientAPIImpl.java
@@ -118,6 +118,7 @@
import org.apache.rocketmq.remoting.protocol.body.ConsumeStatsList;
import org.apache.rocketmq.remoting.protocol.body.ConsumerConnection;
import org.apache.rocketmq.remoting.protocol.body.ConsumerRunningInfo;
+import org.apache.rocketmq.remoting.protocol.body.CreateTopicListRequestBody;
import org.apache.rocketmq.remoting.protocol.body.EpochEntryCache;
import org.apache.rocketmq.remoting.protocol.body.GetConsumerStatusBody;
import org.apache.rocketmq.remoting.protocol.body.GroupList;
@@ -150,6 +151,7 @@
import org.apache.rocketmq.remoting.protocol.header.ConsumerSendMsgBackRequestHeader;
import org.apache.rocketmq.remoting.protocol.header.CreateAccessConfigRequestHeader;
import org.apache.rocketmq.remoting.protocol.header.CreateAclRequestHeader;
+import org.apache.rocketmq.remoting.protocol.header.CreateTopicListRequestHeader;
import org.apache.rocketmq.remoting.protocol.header.CreateTopicRequestHeader;
import org.apache.rocketmq.remoting.protocol.header.CreateUserRequestHeader;
import org.apache.rocketmq.remoting.protocol.header.DeleteAccessConfigRequestHeader;
@@ -430,6 +432,24 @@ public void createTopic(final String addr, final String defaultTopic, final Topi
throw new MQClientException(response.getCode(), response.getRemark());
}
+ public void createTopicList(final String address, final List topicConfigList, final long timeoutMillis)
+ throws InterruptedException, RemotingException, MQClientException {
+ CreateTopicListRequestHeader requestHeader = new CreateTopicListRequestHeader();
+ CreateTopicListRequestBody requestBody = new CreateTopicListRequestBody(topicConfigList);
+
+ RemotingCommand request = RemotingCommand.createRequestCommand(RequestCode.UPDATE_AND_CREATE_TOPIC_LIST, requestHeader);
+ request.setBody(requestBody.encode());
+
+ RemotingCommand response = this.remotingClient.invokeSync(
+ MixAll.brokerVIPChannel(this.clientConfig.isVipChannelEnabled(), address), request, timeoutMillis);
+ assert response != null;
+ if (response.getCode() == ResponseCode.SUCCESS) {
+ return;
+ }
+
+ throw new MQClientException(response.getCode(), response.getRemark());
+ }
+
public void createPlainAccessConfig(final String addr, final PlainAccessConfig plainAccessConfig,
final long timeoutMillis)
throws RemotingException, InterruptedException, MQClientException {
diff --git a/client/src/test/java/org/apache/rocketmq/client/impl/MQClientAPIImplTest.java b/client/src/test/java/org/apache/rocketmq/client/impl/MQClientAPIImplTest.java
index 97d8d04e648..b0876c7c0d9 100644
--- a/client/src/test/java/org/apache/rocketmq/client/impl/MQClientAPIImplTest.java
+++ b/client/src/test/java/org/apache/rocketmq/client/impl/MQClientAPIImplTest.java
@@ -19,6 +19,7 @@
import java.lang.reflect.Field;
import java.net.InetSocketAddress;
import java.util.Collections;
+import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import java.util.concurrent.CountDownLatch;
@@ -1068,4 +1069,26 @@ public Object answer(InvocationOnMock invocationOnMock) throws Throwable {
int topicCnt = mqClientAPI.addWritePermOfBroker("127.0.0.1", "default-broker", 1000);
assertThat(topicCnt).isEqualTo(7);
}
+
+ @Test
+ public void testCreateTopicList_Success() throws RemotingException, InterruptedException, MQClientException {
+ doAnswer((Answer) mock -> {
+ RemotingCommand request = mock.getArgument(1);
+
+ RemotingCommand response = RemotingCommand.createResponseCommand(null);
+ response.setCode(ResponseCode.SUCCESS);
+ response.setOpaque(request.getOpaque());
+ return response;
+ }).when(remotingClient).invokeSync(anyString(), any(RemotingCommand.class), anyLong());
+
+ final List topicConfigList = new LinkedList<>();
+ for (int i = 0; i < 16; i++) {
+ TopicConfig topicConfig = new TopicConfig();
+ topicConfig.setTopicName("Topic" + i);
+ topicConfigList.add(topicConfig);
+ }
+
+ mqClientAPI.createTopicList(brokerAddr, topicConfigList, 10000);
+ }
+
}
diff --git a/remoting/src/main/java/org/apache/rocketmq/remoting/protocol/RequestCode.java b/remoting/src/main/java/org/apache/rocketmq/remoting/protocol/RequestCode.java
index 1de724e0f1e..3be22fc56b7 100644
--- a/remoting/src/main/java/org/apache/rocketmq/remoting/protocol/RequestCode.java
+++ b/remoting/src/main/java/org/apache/rocketmq/remoting/protocol/RequestCode.java
@@ -28,6 +28,7 @@ public class RequestCode {
public static final int QUERY_CONSUMER_OFFSET = 14;
public static final int UPDATE_CONSUMER_OFFSET = 15;
public static final int UPDATE_AND_CREATE_TOPIC = 17;
+ public static final int UPDATE_AND_CREATE_TOPIC_LIST = 18;
public static final int GET_ALL_TOPIC_CONFIG = 21;
public static final int GET_TOPIC_CONFIG_LIST = 22;
diff --git a/remoting/src/main/java/org/apache/rocketmq/remoting/protocol/body/CreateTopicListRequestBody.java b/remoting/src/main/java/org/apache/rocketmq/remoting/protocol/body/CreateTopicListRequestBody.java
new file mode 100644
index 00000000000..a72be31ac92
--- /dev/null
+++ b/remoting/src/main/java/org/apache/rocketmq/remoting/protocol/body/CreateTopicListRequestBody.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.rocketmq.remoting.protocol.body;
+
+import java.util.List;
+import org.apache.rocketmq.common.TopicConfig;
+import org.apache.rocketmq.remoting.annotation.CFNotNull;
+import org.apache.rocketmq.remoting.protocol.RemotingSerializable;
+
+public class CreateTopicListRequestBody extends RemotingSerializable {
+ @CFNotNull
+ private List topicConfigList;
+
+ public CreateTopicListRequestBody() {}
+
+ public CreateTopicListRequestBody(List topicConfigList) {
+ this.topicConfigList = topicConfigList;
+ }
+
+ public List getTopicConfigList() {
+ return topicConfigList;
+ }
+
+ public void setTopicConfigList(List topicConfigList) {
+ this.topicConfigList = topicConfigList;
+ }
+
+}
diff --git a/remoting/src/main/java/org/apache/rocketmq/remoting/protocol/header/CreateTopicListRequestHeader.java b/remoting/src/main/java/org/apache/rocketmq/remoting/protocol/header/CreateTopicListRequestHeader.java
new file mode 100644
index 00000000000..615de750c48
--- /dev/null
+++ b/remoting/src/main/java/org/apache/rocketmq/remoting/protocol/header/CreateTopicListRequestHeader.java
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.rocketmq.remoting.protocol.header;
+
+import org.apache.rocketmq.common.action.Action;
+import org.apache.rocketmq.common.action.RocketMQAction;
+import org.apache.rocketmq.remoting.exception.RemotingCommandException;
+import org.apache.rocketmq.remoting.protocol.RequestCode;
+import org.apache.rocketmq.remoting.rpc.RpcRequestHeader;
+
+@RocketMQAction(value = RequestCode.UPDATE_AND_CREATE_TOPIC_LIST, action = Action.CREATE)
+public class CreateTopicListRequestHeader extends RpcRequestHeader {
+ @Override
+ public void checkFields() throws RemotingCommandException {
+
+ }
+}
diff --git a/tools/src/main/java/org/apache/rocketmq/tools/admin/DefaultMQAdminExt.java b/tools/src/main/java/org/apache/rocketmq/tools/admin/DefaultMQAdminExt.java
index a02c878d961..37dd322488f 100644
--- a/tools/src/main/java/org/apache/rocketmq/tools/admin/DefaultMQAdminExt.java
+++ b/tools/src/main/java/org/apache/rocketmq/tools/admin/DefaultMQAdminExt.java
@@ -195,6 +195,11 @@ public void createAndUpdateTopicConfig(String addr, TopicConfig config) throws R
defaultMQAdminExtImpl.createAndUpdateTopicConfig(addr, config);
}
+ @Override
+ public void createAndUpdateTopicConfigList(String addr, List topicConfigList) throws InterruptedException, RemotingException, MQClientException {
+ defaultMQAdminExtImpl.createAndUpdateTopicConfigList(addr, topicConfigList);
+ }
+
@Override
public void createAndUpdatePlainAccessConfig(String addr,
PlainAccessConfig config) throws RemotingException, MQBrokerException, InterruptedException, MQClientException {
diff --git a/tools/src/main/java/org/apache/rocketmq/tools/admin/DefaultMQAdminExtImpl.java b/tools/src/main/java/org/apache/rocketmq/tools/admin/DefaultMQAdminExtImpl.java
index 2046b1a44cb..b5a20673dab 100644
--- a/tools/src/main/java/org/apache/rocketmq/tools/admin/DefaultMQAdminExtImpl.java
+++ b/tools/src/main/java/org/apache/rocketmq/tools/admin/DefaultMQAdminExtImpl.java
@@ -275,6 +275,12 @@ public void createAndUpdateTopicConfig(String addr,
this.mqClientInstance.getMQClientAPIImpl().createTopic(addr, this.defaultMQAdminExt.getCreateTopicKey(), config, timeoutMillis);
}
+ @Override
+ public void createAndUpdateTopicConfigList(final String brokerAddr,
+ final List topicConfigList) throws RemotingException, InterruptedException, MQClientException {
+ this.mqClientInstance.getMQClientAPIImpl().createTopicList(brokerAddr, topicConfigList, timeoutMillis);
+ }
+
@Override
public void createAndUpdatePlainAccessConfig(String addr,
PlainAccessConfig config) throws RemotingException, MQBrokerException, InterruptedException, MQClientException {
diff --git a/tools/src/main/java/org/apache/rocketmq/tools/admin/MQAdminExt.java b/tools/src/main/java/org/apache/rocketmq/tools/admin/MQAdminExt.java
index 50deb7edfc6..96940c38b26 100644
--- a/tools/src/main/java/org/apache/rocketmq/tools/admin/MQAdminExt.java
+++ b/tools/src/main/java/org/apache/rocketmq/tools/admin/MQAdminExt.java
@@ -92,6 +92,9 @@ void createAndUpdateTopicConfig(final String addr,
final TopicConfig config) throws RemotingException, MQBrokerException,
InterruptedException, MQClientException;
+ void createAndUpdateTopicConfigList(final String addr,
+ final List topicConfigList) throws InterruptedException, RemotingException, MQClientException;
+
void createAndUpdatePlainAccessConfig(final String addr,
final PlainAccessConfig plainAccessConfig) throws RemotingException, MQBrokerException,
InterruptedException, MQClientException;
diff --git a/tools/src/main/java/org/apache/rocketmq/tools/command/MQAdminStartup.java b/tools/src/main/java/org/apache/rocketmq/tools/command/MQAdminStartup.java
index f8b8ec248a8..e785934ba37 100644
--- a/tools/src/main/java/org/apache/rocketmq/tools/command/MQAdminStartup.java
+++ b/tools/src/main/java/org/apache/rocketmq/tools/command/MQAdminStartup.java
@@ -113,6 +113,7 @@
import org.apache.rocketmq.tools.command.topic.TopicStatusSubCommand;
import org.apache.rocketmq.tools.command.topic.UpdateOrderConfCommand;
import org.apache.rocketmq.tools.command.topic.UpdateStaticTopicSubCommand;
+import org.apache.rocketmq.tools.command.topic.UpdateTopicListSubCommand;
import org.apache.rocketmq.tools.command.topic.UpdateTopicPermSubCommand;
import org.apache.rocketmq.tools.command.topic.UpdateTopicSubCommand;
@@ -187,6 +188,7 @@ public static void main0(String[] args, RPCHook rpcHook) {
public static void initCommand() {
initCommand(new UpdateTopicSubCommand());
+ initCommand(new UpdateTopicListSubCommand());
initCommand(new DeleteTopicSubCommand());
initCommand(new UpdateSubGroupSubCommand());
initCommand(new SetConsumeModeSubCommand());
diff --git a/tools/src/main/java/org/apache/rocketmq/tools/command/topic/UpdateTopicListSubCommand.java b/tools/src/main/java/org/apache/rocketmq/tools/command/topic/UpdateTopicListSubCommand.java
new file mode 100644
index 00000000000..a246059e117
--- /dev/null
+++ b/tools/src/main/java/org/apache/rocketmq/tools/command/topic/UpdateTopicListSubCommand.java
@@ -0,0 +1,118 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.rocketmq.tools.command.topic;
+
+import com.alibaba.fastjson2.JSON;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.List;
+import java.util.Set;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.OptionGroup;
+import org.apache.commons.cli.Options;
+import org.apache.rocketmq.common.TopicConfig;
+import org.apache.rocketmq.remoting.RPCHook;
+import org.apache.rocketmq.srvutil.ServerUtil;
+import org.apache.rocketmq.tools.admin.DefaultMQAdminExt;
+import org.apache.rocketmq.tools.command.CommandUtil;
+import org.apache.rocketmq.tools.command.SubCommand;
+import org.apache.rocketmq.tools.command.SubCommandException;
+
+public class UpdateTopicListSubCommand implements SubCommand {
+ @Override
+ public String commandName() {
+ return "updateTopicList";
+ }
+
+ @Override
+ public String commandDesc() {
+ return "create or update topic in batch";
+ }
+
+ @Override
+ public Options buildCommandlineOptions(Options options) {
+ final OptionGroup optionGroup = new OptionGroup();
+ Option opt = new Option("b", "brokerAddr", true, "create topic to which broker");
+ optionGroup.addOption(opt);
+ opt = new Option("c", "clusterName", true, "create topic to which cluster");
+ optionGroup.addOption(opt);
+ optionGroup.setRequired(true);
+ options.addOptionGroup(optionGroup);
+
+ opt = new Option("f", "filename", true, "Path to a file with list of org.apache.rocketmq.common.TopicConfig in json format");
+ opt.setRequired(true);
+ options.addOption(opt);
+
+ return options;
+ }
+
+ @Override
+ public void execute(CommandLine commandLine, Options options,
+ RPCHook rpcHook) throws SubCommandException {
+ final DefaultMQAdminExt defaultMQAdminExt = new DefaultMQAdminExt(rpcHook);
+ defaultMQAdminExt.setInstanceName(Long.toString(System.currentTimeMillis()));
+
+ final String fileName = commandLine.getOptionValue('f').trim();
+
+
+ try {
+ final Path filePath = Paths.get(fileName);
+ if (!Files.exists(filePath)) {
+ System.out.printf("the file path %s does not exists%n", fileName);
+ return;
+ }
+ final byte[] topicConfigListBytes = Files.readAllBytes(filePath);
+ final List topicConfigs = JSON.parseArray(topicConfigListBytes, TopicConfig.class);
+ if (null == topicConfigs || topicConfigs.isEmpty()) {
+ return;
+ }
+
+ if (commandLine.hasOption('b')) {
+ String brokerAddress = commandLine.getOptionValue('b').trim();
+ defaultMQAdminExt.start();
+ defaultMQAdminExt.createAndUpdateTopicConfigList(brokerAddress, topicConfigs);
+
+ System.out.printf("submit batch of topic config to %s success, please check the result later.%n",
+ brokerAddress);
+ return;
+
+ } else if (commandLine.hasOption('c')) {
+ final String clusterName = commandLine.getOptionValue('c').trim();
+
+ defaultMQAdminExt.start();
+
+ Set masterSet =
+ CommandUtil.fetchMasterAddrByClusterName(defaultMQAdminExt, clusterName);
+ for (String brokerAddress : masterSet) {
+ defaultMQAdminExt.createAndUpdateTopicConfigList(brokerAddress, topicConfigs);
+
+ System.out.printf("submit batch of topic config to %s success, please check the result later.%n",
+ brokerAddress);
+ }
+ }
+
+ ServerUtil.printCommandLineHelp("mqadmin " + this.commandName(), options);
+ } catch (Exception e) {
+ throw new SubCommandException(this.getClass().getSimpleName() + " command failed", e);
+ } finally {
+ defaultMQAdminExt.shutdown();
+ }
+ }
+}
diff --git a/tools/src/test/java/org/apache/rocketmq/tools/command/topic/UpdateTopicListSubCommandTest.java b/tools/src/test/java/org/apache/rocketmq/tools/command/topic/UpdateTopicListSubCommandTest.java
new file mode 100644
index 00000000000..95bb579da84
--- /dev/null
+++ b/tools/src/test/java/org/apache/rocketmq/tools/command/topic/UpdateTopicListSubCommandTest.java
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.rocketmq.tools.command.topic;
+
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.DefaultParser;
+import org.apache.commons.cli.Options;
+import org.apache.rocketmq.srvutil.ServerUtil;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+class UpdateTopicListSubCommandTest {
+
+ @Test
+ public void testArguments() {
+ UpdateTopicListSubCommand cmd = new UpdateTopicListSubCommand();
+ Options options = ServerUtil.buildCommandlineOptions(new Options());
+ String[] subargs = new String[] {"-b 127.0.0.1:10911", "-f topics.json"};
+ final CommandLine commandLine =
+ ServerUtil.parseCmdLine("mqadmin " + cmd.commandName(), subargs,
+ cmd.buildCommandlineOptions(options), new DefaultParser());
+ assertEquals("127.0.0.1:10911", commandLine.getOptionValue('b').trim());
+ assertEquals("topics.json", commandLine.getOptionValue('f').trim());
+ }
+}
\ No newline at end of file
From d60198f621baac54bffb981d7a797a04dfa0bb5a Mon Sep 17 00:00:00 2001
From: rongtong
Date: Fri, 7 Jun 2024 13:44:13 +0800
Subject: [PATCH 029/265] [ISSUE #8239] Fix the issue of potential message loss
after a crash under synchronous disk flushing configuration. (#8240)
---
.../org/apache/rocketmq/store/CommitLog.java | 2 +-
.../rocketmq/store/DefaultMessageStore.java | 12 +-
.../store/config/MessageStoreConfig.java | 15 +-
.../store/ReputMessageServiceTest.java | 148 ++++++++++++++++++
4 files changed, 171 insertions(+), 6 deletions(-)
create mode 100644 store/src/test/java/org/apache/rocketmq/store/ReputMessageServiceTest.java
diff --git a/store/src/main/java/org/apache/rocketmq/store/CommitLog.java b/store/src/main/java/org/apache/rocketmq/store/CommitLog.java
index 1174eca1bab..c2150d7a321 100644
--- a/store/src/main/java/org/apache/rocketmq/store/CommitLog.java
+++ b/store/src/main/java/org/apache/rocketmq/store/CommitLog.java
@@ -651,7 +651,7 @@ public long getConfirmOffset() {
} else if (this.defaultMessageStore.getMessageStoreConfig().isDuplicationEnable()) {
return this.confirmOffset;
} else {
- return getMaxOffset();
+ return this.defaultMessageStore.isSyncDiskFlush() ? getFlushedWhere() : getMaxOffset();
}
}
diff --git a/store/src/main/java/org/apache/rocketmq/store/DefaultMessageStore.java b/store/src/main/java/org/apache/rocketmq/store/DefaultMessageStore.java
index 97833351d19..a901e850ed6 100644
--- a/store/src/main/java/org/apache/rocketmq/store/DefaultMessageStore.java
+++ b/store/src/main/java/org/apache/rocketmq/store/DefaultMessageStore.java
@@ -2814,7 +2814,11 @@ public long behind() {
}
public boolean isCommitLogAvailable() {
- return this.reputFromOffset < DefaultMessageStore.this.getConfirmOffset();
+ return this.reputFromOffset < getReputEndOffset();
+ }
+
+ protected long getReputEndOffset() {
+ return DefaultMessageStore.this.getMessageStoreConfig().isReadUnCommitted() ? DefaultMessageStore.this.commitLog.getMaxOffset() : DefaultMessageStore.this.commitLog.getConfirmOffset();
}
public void doReput() {
@@ -2834,12 +2838,12 @@ public void doReput() {
try {
this.reputFromOffset = result.getStartOffset();
- for (int readSize = 0; readSize < result.getSize() && reputFromOffset < DefaultMessageStore.this.getConfirmOffset() && doNext; ) {
+ for (int readSize = 0; readSize < result.getSize() && reputFromOffset < getReputEndOffset() && doNext; ) {
DispatchRequest dispatchRequest =
DefaultMessageStore.this.commitLog.checkMessageAndReturnSize(result.getByteBuffer(), false, false, false);
int size = dispatchRequest.getBufferSize() == -1 ? dispatchRequest.getMsgSize() : dispatchRequest.getBufferSize();
- if (reputFromOffset + size > DefaultMessageStore.this.getConfirmOffset()) {
+ if (reputFromOffset + size > getReputEndOffset()) {
doNext = false;
break;
}
@@ -3127,7 +3131,7 @@ public void doReput() {
try {
this.reputFromOffset = result.getStartOffset();
- for (int readSize = 0; readSize < result.getSize() && reputFromOffset < DefaultMessageStore.this.getConfirmOffset() && doNext; ) {
+ for (int readSize = 0; readSize < result.getSize() && reputFromOffset < getReputEndOffset() && doNext; ) {
ByteBuffer byteBuffer = result.getByteBuffer();
int totalSize = preCheckMessageAndReturnSize(byteBuffer);
diff --git a/store/src/main/java/org/apache/rocketmq/store/config/MessageStoreConfig.java b/store/src/main/java/org/apache/rocketmq/store/config/MessageStoreConfig.java
index 9afc02a0c9c..0060b144cff 100644
--- a/store/src/main/java/org/apache/rocketmq/store/config/MessageStoreConfig.java
+++ b/store/src/main/java/org/apache/rocketmq/store/config/MessageStoreConfig.java
@@ -413,6 +413,12 @@ public class MessageStoreConfig {
private int topicQueueLockNum = 32;
+ /**
+ * If readUnCommitted is true, the dispatch of the consume queue will exceed the confirmOffset, which may cause the client to read uncommitted messages.
+ * For example, reput offset exceeding the flush offset during synchronous disk flushing.
+ */
+ private boolean readUnCommitted = false;
+
public boolean isEnabledAppendPropCRC() {
return enabledAppendPropCRC;
}
@@ -672,7 +678,6 @@ public void setForceVerifyPropCRC(boolean forceVerifyPropCRC) {
this.forceVerifyPropCRC = forceVerifyPropCRC;
}
-
public String getStorePathCommitLog() {
if (storePathCommitLog == null) {
return storePathRootDir + File.separator + "commitlog";
@@ -1819,4 +1824,12 @@ public int getTopicQueueLockNum() {
public void setTopicQueueLockNum(int topicQueueLockNum) {
this.topicQueueLockNum = topicQueueLockNum;
}
+
+ public boolean isReadUnCommitted() {
+ return readUnCommitted;
+ }
+
+ public void setReadUnCommitted(boolean readUnCommitted) {
+ this.readUnCommitted = readUnCommitted;
+ }
}
diff --git a/store/src/test/java/org/apache/rocketmq/store/ReputMessageServiceTest.java b/store/src/test/java/org/apache/rocketmq/store/ReputMessageServiceTest.java
new file mode 100644
index 00000000000..d1ce0953331
--- /dev/null
+++ b/store/src/test/java/org/apache/rocketmq/store/ReputMessageServiceTest.java
@@ -0,0 +1,148 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.rocketmq.store;
+
+import java.lang.reflect.Field;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.SocketAddress;
+import java.util.UUID;
+import java.io.File;
+import java.util.concurrent.CompletableFuture;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.rocketmq.common.BrokerConfig;
+import org.apache.rocketmq.common.UtilAll;
+import org.apache.rocketmq.common.message.MessageDecoder;
+
+import org.apache.rocketmq.common.message.MessageExt;
+import org.apache.rocketmq.common.message.MessageExtBrokerInner;
+import org.apache.rocketmq.store.config.FlushDiskType;
+import org.apache.rocketmq.store.config.MessageStoreConfig;
+import org.apache.rocketmq.store.stats.BrokerStatsManager;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.assertTrue;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+import static org.mockito.ArgumentMatchers.any;
+
+public class ReputMessageServiceTest {
+ private DefaultMessageStore syncFlushMessageStore;
+ private DefaultMessageStore asyncFlushMessageStore;
+ private final String topic = "FooBar";
+ private final String tmpdir = System.getProperty("java.io.tmpdir");
+ private final String storePathRootParentDir = (StringUtils.endsWith(tmpdir, File.separator) ? tmpdir : tmpdir + File.separator) + UUID.randomUUID();
+ private SocketAddress bornHost;
+ private SocketAddress storeHost;
+
+ @Before
+ public void init() throws Exception {
+ File file = new File(storePathRootParentDir);
+ UtilAll.deleteFile(file);
+ syncFlushMessageStore = buildMessageStore(FlushDiskType.SYNC_FLUSH);
+ asyncFlushMessageStore = buildMessageStore(FlushDiskType.ASYNC_FLUSH);
+ assertTrue(syncFlushMessageStore.load());
+ assertTrue(asyncFlushMessageStore.load());
+ syncFlushMessageStore.start();
+ asyncFlushMessageStore.start();
+ storeHost = new InetSocketAddress(InetAddress.getLocalHost(), 8123);
+ bornHost = new InetSocketAddress(InetAddress.getByName("127.0.0.1"), 0);
+ }
+
+ private DefaultMessageStore buildMessageStore(FlushDiskType flushDiskType) throws Exception {
+ MessageStoreConfig messageStoreConfig = new MessageStoreConfig();
+ messageStoreConfig.setHaListenPort(0);
+ messageStoreConfig.setFlushDiskType(flushDiskType);
+ messageStoreConfig.setStorePathRootDir(storePathRootParentDir + File.separator + flushDiskType);
+ messageStoreConfig.setStorePathCommitLog(storePathRootParentDir + File.separator + flushDiskType + File.separator + "commitlog");
+ BrokerConfig brokerConfig = new BrokerConfig();
+ brokerConfig.setLongPollingEnable(false);
+ DefaultMessageStore messageStore = new DefaultMessageStore(messageStoreConfig, mock(BrokerStatsManager.class), null, brokerConfig, null);
+ // Mock flush disk service
+ Field field = CommitLog.class.getDeclaredField("flushManager");
+ field.setAccessible(true);
+ FlushManager flushManager = mock(FlushManager.class);
+ CompletableFuture completableFuture = new CompletableFuture<>();
+ completableFuture.complete(PutMessageStatus.PUT_OK);
+ when(flushManager.handleDiskFlush(any(AppendMessageResult.class), any(MessageExt.class))).thenReturn(completableFuture);
+ field.set(messageStore.getCommitLog(), flushManager);
+ return messageStore;
+ }
+
+ @Test
+ public void testReputEndOffset_whenSyncFlush() throws Exception {
+ for (int i = 0; i < 10; i++) {
+ assertEquals(PutMessageStatus.PUT_OK, syncFlushMessageStore.putMessage(buildMessage()).getPutMessageStatus());
+ }
+ assertEquals(1580, syncFlushMessageStore.getMaxPhyOffset());
+ assertEquals(0, syncFlushMessageStore.getCommitLog().getFlushedWhere());
+ // wait for cq dispatch
+ Thread.sleep(3000);
+ assertEquals(0, syncFlushMessageStore.getCommitLog().getFlushedWhere());
+ assertEquals(0, syncFlushMessageStore.getMaxOffsetInQueue(topic, 0));
+ GetMessageResult getMessageResult = syncFlushMessageStore.getMessage("testGroup", topic, 0, 0, 32, null);
+ assertEquals(GetMessageStatus.NO_MESSAGE_IN_QUEUE, getMessageResult.getStatus());
+ }
+
+ @Test
+ public void testReputEndOffset_whenAsyncFlush() throws Exception {
+ for (int i = 0; i < 10; i++) {
+ assertEquals(PutMessageStatus.PUT_OK, asyncFlushMessageStore.putMessage(buildMessage()).getPutMessageStatus());
+ }
+ assertEquals(1580, asyncFlushMessageStore.getMaxPhyOffset());
+ assertEquals(0, asyncFlushMessageStore.getCommitLog().getFlushedWhere());
+ // wait for cq dispatch
+ Thread.sleep(3000);
+ assertEquals(0, asyncFlushMessageStore.getCommitLog().getFlushedWhere());
+ assertEquals(10, asyncFlushMessageStore.getMaxOffsetInQueue(topic, 0));
+ GetMessageResult getMessageResult = asyncFlushMessageStore.getMessage("testGroup", topic, 0, 0, 32, null);
+ assertEquals(10, getMessageResult.getMessageCount());
+ }
+
+ private MessageExtBrokerInner buildMessage() {
+ MessageExtBrokerInner msg = new MessageExtBrokerInner();
+ msg.setTopic(topic);
+ msg.setTags("TAG1");
+ msg.setBody("Once, there was a chance for me!".getBytes());
+ msg.setKeys(String.valueOf(System.currentTimeMillis()));
+ msg.setQueueId(0);
+ msg.setSysFlag(0);
+ msg.setBornTimestamp(System.currentTimeMillis());
+ msg.setStoreHost(storeHost);
+ msg.setBornHost(bornHost);
+ msg.setPropertiesString(MessageDecoder.messageProperties2String(msg.getProperties()));
+ return msg;
+ }
+
+ @After
+ public void destroy() throws Exception {
+ if (this.syncFlushMessageStore != null) {
+ syncFlushMessageStore.shutdown();
+ syncFlushMessageStore.destroy();
+ }
+ if (this.asyncFlushMessageStore != null) {
+ asyncFlushMessageStore.shutdown();
+ asyncFlushMessageStore.destroy();
+ }
+ File file = new File(storePathRootParentDir);
+ UtilAll.deleteFile(file);
+ }
+}
From 3ecc73bcc4f662854549560c12af97480b28bab5 Mon Sep 17 00:00:00 2001
From: hqbfz <125714719+3424672656@users.noreply.github.com>
Date: Tue, 11 Jun 2024 09:08:32 +0800
Subject: [PATCH 030/265] [ISSUE #8278] Fix fail test (#8279)
* fix fail test
* fix fail test
---
.../tools/command/topic/UpdateTopicListSubCommandTest.java | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/tools/src/test/java/org/apache/rocketmq/tools/command/topic/UpdateTopicListSubCommandTest.java b/tools/src/test/java/org/apache/rocketmq/tools/command/topic/UpdateTopicListSubCommandTest.java
index 95bb579da84..71704a7aa8c 100644
--- a/tools/src/test/java/org/apache/rocketmq/tools/command/topic/UpdateTopicListSubCommandTest.java
+++ b/tools/src/test/java/org/apache/rocketmq/tools/command/topic/UpdateTopicListSubCommandTest.java
@@ -21,11 +21,11 @@
import org.apache.commons.cli.DefaultParser;
import org.apache.commons.cli.Options;
import org.apache.rocketmq.srvutil.ServerUtil;
-import org.junit.jupiter.api.Test;
+import org.junit.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
-class UpdateTopicListSubCommandTest {
+public class UpdateTopicListSubCommandTest {
@Test
public void testArguments() {
From b96d6b98e836b4604378b8358d58d8a9a1d2037c Mon Sep 17 00:00:00 2001
From: yx9o
Date: Wed, 12 Jun 2024 09:08:49 +0800
Subject: [PATCH 031/265] [ISSUE #8285] Add more test coverage for
BrokerPreOnlineService (#8286)
---
...t.java => BrokerPreOnlineServiceTest.java} | 63 ++++++++++++++-----
1 file changed, 49 insertions(+), 14 deletions(-)
rename container/src/test/java/org/apache/rocketmq/container/{BrokerPreOnlineTest.java => BrokerPreOnlineServiceTest.java} (63%)
diff --git a/container/src/test/java/org/apache/rocketmq/container/BrokerPreOnlineTest.java b/container/src/test/java/org/apache/rocketmq/container/BrokerPreOnlineServiceTest.java
similarity index 63%
rename from container/src/test/java/org/apache/rocketmq/container/BrokerPreOnlineTest.java
rename to container/src/test/java/org/apache/rocketmq/container/BrokerPreOnlineServiceTest.java
index 2158b8d9aca..6a46ed1f6ff 100644
--- a/container/src/test/java/org/apache/rocketmq/container/BrokerPreOnlineTest.java
+++ b/container/src/test/java/org/apache/rocketmq/container/BrokerPreOnlineServiceTest.java
@@ -17,15 +17,12 @@
package org.apache.rocketmq.container;
-import java.lang.reflect.Field;
-import java.time.Duration;
-import java.util.HashMap;
-import java.util.Map;
import org.apache.rocketmq.broker.BrokerController;
import org.apache.rocketmq.broker.BrokerPreOnlineService;
import org.apache.rocketmq.broker.out.BrokerOuterAPI;
import org.apache.rocketmq.broker.transaction.TransactionalMessageCheckService;
import org.apache.rocketmq.common.BrokerConfig;
+import org.apache.rocketmq.remoting.protocol.BrokerSyncInfo;
import org.apache.rocketmq.remoting.protocol.body.BrokerMemberGroup;
import org.apache.rocketmq.store.DefaultMessageStore;
import org.apache.rocketmq.store.config.MessageStoreConfig;
@@ -34,12 +31,21 @@
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
+import java.lang.reflect.Field;
+import java.time.Duration;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+
import static org.awaitility.Awaitility.await;
+import static org.junit.Assert.assertEquals;
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@RunWith(MockitoJUnitRunner.class)
-public class BrokerPreOnlineTest {
+public class BrokerPreOnlineServiceTest {
@Mock
private BrokerContainer brokerContainer;
@@ -48,25 +54,27 @@ public class BrokerPreOnlineTest {
@Mock
private BrokerOuterAPI brokerOuterAPI;
- public void init() throws Exception {
+ public void init(final long brokerId) throws Exception {
when(brokerContainer.getBrokerOuterAPI()).thenReturn(brokerOuterAPI);
BrokerMemberGroup brokerMemberGroup1 = new BrokerMemberGroup();
Map brokerAddrMap = new HashMap<>();
- brokerAddrMap.put(1L, "127.0.0.1:20911");
+ brokerAddrMap.put(0L, "127.0.0.1:10911");
brokerMemberGroup1.setBrokerAddrs(brokerAddrMap);
BrokerMemberGroup brokerMemberGroup2 = new BrokerMemberGroup();
brokerMemberGroup2.setBrokerAddrs(new HashMap<>());
-
-// when(brokerOuterAPI.syncBrokerMemberGroup(anyString(), anyString()))
-// .thenReturn(brokerMemberGroup1)
-// .thenReturn(brokerMemberGroup2);
-// doNothing().when(brokerOuterAPI).sendBrokerHaInfo(anyString(), anyString(), anyLong(), anyString());
+ when(brokerOuterAPI.syncBrokerMemberGroup(anyString(), anyString(), anyBoolean()))
+ .thenReturn(brokerMemberGroup1)
+ .thenReturn(brokerMemberGroup2);
+ BrokerSyncInfo brokerSyncInfo = mock(BrokerSyncInfo.class);
+ when(brokerOuterAPI.retrieveBrokerHaInfo(anyString())).thenReturn(brokerSyncInfo);
DefaultMessageStore defaultMessageStore = mock(DefaultMessageStore.class);
when(defaultMessageStore.getMessageStoreConfig()).thenReturn(new MessageStoreConfig());
- when(defaultMessageStore.getBrokerConfig()).thenReturn(new BrokerConfig());
+ BrokerConfig brokerConfig = new BrokerConfig();
+ brokerConfig.setBrokerId(brokerId);
+ when(defaultMessageStore.getBrokerConfig()).thenReturn(brokerConfig);
// HAService haService = new DefaultHAService();
// haService.init(defaultMessageStore);
@@ -91,11 +99,38 @@ public void init() throws Exception {
@Test
public void testMasterOnlineConnTimeout() throws Exception {
- init();
+ init(0);
BrokerPreOnlineService brokerPreOnlineService = new BrokerPreOnlineService(innerBrokerController);
brokerPreOnlineService.start();
await().atMost(Duration.ofSeconds(30)).until(() -> !innerBrokerController.isIsolated());
}
+
+ @Test
+ public void testMasterOnlineNormal() throws Exception {
+ init(0);
+ BrokerPreOnlineService brokerPreOnlineService = new BrokerPreOnlineService(innerBrokerController);
+ brokerPreOnlineService.start();
+ TimeUnit.SECONDS.sleep(1);
+ brokerPreOnlineService.shutdown();
+ await().atMost(Duration.ofSeconds(30)).until(brokerPreOnlineService::isStopped);
+ }
+
+ @Test
+ public void testSlaveOnlineNormal() throws Exception {
+ init(1);
+ BrokerPreOnlineService brokerPreOnlineService = new BrokerPreOnlineService(innerBrokerController);
+ brokerPreOnlineService.start();
+ TimeUnit.SECONDS.sleep(1);
+ brokerPreOnlineService.shutdown();
+ await().atMost(Duration.ofSeconds(30)).until(brokerPreOnlineService::isStopped);
+ }
+
+ @Test
+ public void testGetServiceName() throws Exception {
+ init(1);
+ BrokerPreOnlineService brokerPreOnlineService = new BrokerPreOnlineService(innerBrokerController);
+ assertEquals(BrokerPreOnlineService.class.getSimpleName(), brokerPreOnlineService.getServiceName());
+ }
}
From 1a73e015b8c764a39d2a03a5a58bf26a78638986 Mon Sep 17 00:00:00 2001
From: yx9o
Date: Wed, 12 Jun 2024 09:10:33 +0800
Subject: [PATCH 032/265] [ISSUE #8276] Merge duplicate code in
DefaultMQProducer constructor (#8277)
---
.../client/producer/DefaultMQProducer.java | 42 ++++-----
.../producer/DefaultMQProducerTest.java | 92 ++++++++++++++++---
2 files changed, 99 insertions(+), 35 deletions(-)
diff --git a/client/src/main/java/org/apache/rocketmq/client/producer/DefaultMQProducer.java b/client/src/main/java/org/apache/rocketmq/client/producer/DefaultMQProducer.java
index 5304887e380..4fd038663b5 100644
--- a/client/src/main/java/org/apache/rocketmq/client/producer/DefaultMQProducer.java
+++ b/client/src/main/java/org/apache/rocketmq/client/producer/DefaultMQProducer.java
@@ -16,13 +16,6 @@
*/
package org.apache.rocketmq.client.producer;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.CopyOnWriteArraySet;
-import java.util.concurrent.ExecutorService;
import org.apache.rocketmq.client.ClientConfig;
import org.apache.rocketmq.client.QueryResult;
import org.apache.rocketmq.client.Validators;
@@ -46,11 +39,19 @@
import org.apache.rocketmq.common.message.MessageExt;
import org.apache.rocketmq.common.message.MessageQueue;
import org.apache.rocketmq.common.topic.TopicValidator;
+import org.apache.rocketmq.logging.org.slf4j.Logger;
+import org.apache.rocketmq.logging.org.slf4j.LoggerFactory;
import org.apache.rocketmq.remoting.RPCHook;
import org.apache.rocketmq.remoting.exception.RemotingException;
import org.apache.rocketmq.remoting.protocol.ResponseCode;
-import org.apache.rocketmq.logging.org.slf4j.Logger;
-import org.apache.rocketmq.logging.org.slf4j.LoggerFactory;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.CopyOnWriteArraySet;
+import java.util.concurrent.ExecutorService;
/**
* This class is the entry point for applications intending to send messages.
@@ -210,9 +211,7 @@ public DefaultMQProducer(RPCHook rpcHook) {
* @param producerGroup Producer group, see the name-sake field.
*/
public DefaultMQProducer(final String producerGroup) {
- this.producerGroup = producerGroup;
- defaultMQProducerImpl = new DefaultMQProducerImpl(this, null);
- produceAccumulator = MQClientManager.getInstance().getOrCreateProduceAccumulator(this);
+ this(producerGroup, (RPCHook) null);
}
/**
@@ -222,10 +221,7 @@ public DefaultMQProducer(final String producerGroup) {
* @param rpcHook RPC hook to execute per each remoting command execution.
*/
public DefaultMQProducer(final String producerGroup, RPCHook rpcHook) {
- this.producerGroup = producerGroup;
- this.rpcHook = rpcHook;
- defaultMQProducerImpl = new DefaultMQProducerImpl(this, rpcHook);
- produceAccumulator = MQClientManager.getInstance().getOrCreateProduceAccumulator(this);
+ this(producerGroup, rpcHook, null);
}
/**
@@ -237,8 +233,7 @@ public DefaultMQProducer(final String producerGroup, RPCHook rpcHook) {
*/
public DefaultMQProducer(final String producerGroup, RPCHook rpcHook,
final List topics) {
- this(producerGroup, rpcHook);
- this.topics = topics;
+ this(producerGroup, rpcHook, topics, false, null);
}
/**
@@ -264,9 +259,7 @@ public DefaultMQProducer(final String producerGroup, boolean enableMsgTrace, fin
*/
public DefaultMQProducer(final String producerGroup, RPCHook rpcHook, boolean enableMsgTrace,
final String customizedTraceTopic) {
- this(producerGroup, rpcHook);
- this.enableTrace = enableMsgTrace;
- this.traceTopic = customizedTraceTopic;
+ this(producerGroup, rpcHook, null, enableMsgTrace, customizedTraceTopic);
}
/**
@@ -282,8 +275,13 @@ public DefaultMQProducer(final String producerGroup, RPCHook rpcHook, boolean en
*/
public DefaultMQProducer(final String producerGroup, RPCHook rpcHook, final List topics,
boolean enableMsgTrace, final String customizedTraceTopic) {
- this(producerGroup, rpcHook, enableMsgTrace, customizedTraceTopic);
+ this.producerGroup = producerGroup;
+ this.rpcHook = rpcHook;
this.topics = topics;
+ this.enableTrace = enableMsgTrace;
+ this.traceTopic = customizedTraceTopic;
+ defaultMQProducerImpl = new DefaultMQProducerImpl(this, rpcHook);
+ produceAccumulator = MQClientManager.getInstance().getOrCreateProduceAccumulator(this);
}
/**
diff --git a/client/src/test/java/org/apache/rocketmq/client/producer/DefaultMQProducerTest.java b/client/src/test/java/org/apache/rocketmq/client/producer/DefaultMQProducerTest.java
index d4153c7cd97..7e1fad62477 100644
--- a/client/src/test/java/org/apache/rocketmq/client/producer/DefaultMQProducerTest.java
+++ b/client/src/test/java/org/apache/rocketmq/client/producer/DefaultMQProducerTest.java
@@ -16,19 +16,6 @@
*/
package org.apache.rocketmq.client.producer;
-import java.lang.reflect.Field;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.concurrent.atomic.AtomicInteger;
import org.apache.rocketmq.client.ClientConfig;
import org.apache.rocketmq.client.exception.MQBrokerException;
import org.apache.rocketmq.client.exception.MQClientException;
@@ -41,9 +28,11 @@
import org.apache.rocketmq.client.impl.factory.MQClientInstance;
import org.apache.rocketmq.client.impl.producer.DefaultMQProducerImpl;
import org.apache.rocketmq.client.impl.producer.TopicPublishInfo;
+import org.apache.rocketmq.common.UtilAll;
import org.apache.rocketmq.common.message.Message;
import org.apache.rocketmq.common.message.MessageExt;
import org.apache.rocketmq.common.message.MessageQueue;
+import org.apache.rocketmq.remoting.RPCHook;
import org.apache.rocketmq.remoting.exception.RemotingException;
import org.apache.rocketmq.remoting.netty.NettyRemotingClient;
import org.apache.rocketmq.remoting.protocol.header.SendMessageRequestHeader;
@@ -58,13 +47,33 @@
import org.mockito.Spy;
import org.mockito.junit.MockitoJUnitRunner;
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicInteger;
+
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Fail.failBecauseExceptionWasNotThrown;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.nullable;
+import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@RunWith(MockitoJUnitRunner.class)
@@ -596,4 +605,61 @@ public void run() {
}
return assertionErrors[0];
}
+
+ @Test
+ public void assertCreateDefaultMQProducer() {
+ String producerGroupTemp = producerGroupPrefix + System.currentTimeMillis();
+ DefaultMQProducer producer1 = new DefaultMQProducer(producerGroupTemp);
+ assertNotNull(producer1);
+ assertEquals(producerGroupTemp, producer1.getProducerGroup());
+ assertNotNull(producer1.getDefaultMQProducerImpl());
+ assertTrue(producer1.getTotalBatchMaxBytes() > 0);
+ assertTrue(producer1.getBatchMaxBytes() > 0);
+ assertTrue(producer1.getBatchMaxDelayMs() > 0);
+ assertNull(producer1.getTopics());
+ assertFalse(producer1.isEnableTrace());
+ assertTrue(UtilAll.isBlank(producer1.getTraceTopic()));
+ DefaultMQProducer producer2 = new DefaultMQProducer(producerGroupTemp, mock(RPCHook.class));
+ assertNotNull(producer2);
+ assertEquals(producerGroupTemp, producer2.getProducerGroup());
+ assertNotNull(producer2.getDefaultMQProducerImpl());
+ assertTrue(producer2.getTotalBatchMaxBytes() > 0);
+ assertTrue(producer2.getBatchMaxBytes() > 0);
+ assertTrue(producer2.getBatchMaxDelayMs() > 0);
+ assertNull(producer2.getTopics());
+ assertFalse(producer2.isEnableTrace());
+ assertTrue(UtilAll.isBlank(producer2.getTraceTopic()));
+ DefaultMQProducer producer3 = new DefaultMQProducer(producerGroupTemp, mock(RPCHook.class), Collections.singletonList("custom_topic"));
+ assertNotNull(producer3);
+ assertEquals(producerGroupTemp, producer3.getProducerGroup());
+ assertNotNull(producer3.getDefaultMQProducerImpl());
+ assertTrue(producer3.getTotalBatchMaxBytes() > 0);
+ assertTrue(producer3.getBatchMaxBytes() > 0);
+ assertTrue(producer3.getBatchMaxDelayMs() > 0);
+ assertNotNull(producer3.getTopics());
+ assertEquals(1, producer3.getTopics().size());
+ assertFalse(producer3.isEnableTrace());
+ assertTrue(UtilAll.isBlank(producer3.getTraceTopic()));
+ DefaultMQProducer producer4 = new DefaultMQProducer(producerGroupTemp, mock(RPCHook.class), true, "custom_trace_topic");
+ assertNotNull(producer4);
+ assertEquals(producerGroupTemp, producer4.getProducerGroup());
+ assertNotNull(producer4.getDefaultMQProducerImpl());
+ assertTrue(producer4.getTotalBatchMaxBytes() > 0);
+ assertTrue(producer4.getBatchMaxBytes() > 0);
+ assertTrue(producer4.getBatchMaxDelayMs() > 0);
+ assertNull(producer4.getTopics());
+ assertTrue(producer4.isEnableTrace());
+ assertEquals("custom_trace_topic", producer4.getTraceTopic());
+ DefaultMQProducer producer5 = new DefaultMQProducer(producerGroupTemp, mock(RPCHook.class), Collections.singletonList("custom_topic"), true, "custom_trace_topic");
+ assertNotNull(producer5);
+ assertEquals(producerGroupTemp, producer5.getProducerGroup());
+ assertNotNull(producer5.getDefaultMQProducerImpl());
+ assertTrue(producer5.getTotalBatchMaxBytes() > 0);
+ assertTrue(producer5.getBatchMaxBytes() > 0);
+ assertTrue(producer5.getBatchMaxDelayMs() > 0);
+ assertNotNull(producer5.getTopics());
+ assertEquals(1, producer5.getTopics().size());
+ assertTrue(producer5.isEnableTrace());
+ assertEquals("custom_trace_topic", producer5.getTraceTopic());
+ }
}
From 107a8118e5f152f2918aa297c8ad383373b77e7d Mon Sep 17 00:00:00 2001
From: totalo
Date: Thu, 13 Jun 2024 10:15:04 +0800
Subject: [PATCH 033/265] Restrict some actions to be triggered only in the
official repository (#7695)
* build: Restrict the Snapshot Daily Release Automation action to be triggered only in the official repository
* build: Restrict the E2E test for pull request action to be triggered only in the official repository
* build: Restrict the PUSH-CI action to be triggered only in the official repository
* build: update ci
---
.github/workflows/pr-e2e-test.yml | 7 +++++--
.github/workflows/push-ci.yml | 5 ++++-
.github/workflows/snapshot-automation.yml | 1 +
3 files changed, 10 insertions(+), 3 deletions(-)
diff --git a/.github/workflows/pr-e2e-test.yml b/.github/workflows/pr-e2e-test.yml
index d0371e31135..9082b6b2227 100644
--- a/.github/workflows/pr-e2e-test.yml
+++ b/.github/workflows/pr-e2e-test.yml
@@ -13,10 +13,11 @@ env:
jobs:
docker:
- runs-on: ubuntu-latest
if: >
+ github.repository == 'apache/rocketmq' &&
github.event.workflow_run.event == 'pull_request' &&
github.event.workflow_run.conclusion == 'success'
+ runs-on: ubuntu-latest
timeout-minutes: 30
strategy:
matrix:
@@ -74,7 +75,9 @@ jobs:
path: rocketmq-docker/image-build-ci/versionlist/*
list-version:
- if: always()
+ if: >
+ github.repository == 'apache/rocketmq' &&
+ always()
name: List version
needs: [docker]
runs-on: ubuntu-latest
diff --git a/.github/workflows/push-ci.yml b/.github/workflows/push-ci.yml
index ad29a57c8a8..b679d56d2f0 100644
--- a/.github/workflows/push-ci.yml
+++ b/.github/workflows/push-ci.yml
@@ -15,6 +15,7 @@ env:
jobs:
dist-tar:
+ if: github.repository == 'apache/rocketmq'
name: Build dist tar
runs-on: ubuntu-latest
timeout-minutes: 30
@@ -79,7 +80,9 @@ jobs:
list-version:
- if: always()
+ if: >
+ github.repository == 'apache/rocketmq' &&
+ always()
name: List version
needs: [docker]
runs-on: ubuntu-latest
diff --git a/.github/workflows/snapshot-automation.yml b/.github/workflows/snapshot-automation.yml
index 88f5f4e0ccb..99855d3aa0d 100644
--- a/.github/workflows/snapshot-automation.yml
+++ b/.github/workflows/snapshot-automation.yml
@@ -36,6 +36,7 @@ env:
jobs:
dist-tar:
+ if: github.repository == 'apache/rocketmq'
name: Build dist tar
runs-on: ubuntu-latest
timeout-minutes: 30
From 6b591556612566c23afeca1ded14c04dfc9dc43d Mon Sep 17 00:00:00 2001
From: hqbfz <125714719+3424672656@users.noreply.github.com>
Date: Thu, 13 Jun 2024 10:28:02 +0800
Subject: [PATCH 034/265] [ISSUE #7941] add override annotation (#7959)
* increase missing annotation
* Revert "increase missing annotation"
This reverts commit c1f3cef51d781c132d2064e773a58dc496f9c48c.
* increase missing annotation
---
.../util/data/collect/impl/ListDataCollectorImpl.java | 11 +++++++++++
.../util/data/collect/impl/MapDataCollectorImpl.java | 11 +++++++++++
2 files changed, 22 insertions(+)
diff --git a/test/src/main/java/org/apache/rocketmq/test/util/data/collect/impl/ListDataCollectorImpl.java b/test/src/main/java/org/apache/rocketmq/test/util/data/collect/impl/ListDataCollectorImpl.java
index bdd991a335f..b0a1ee3c6ac 100644
--- a/test/src/main/java/org/apache/rocketmq/test/util/data/collect/impl/ListDataCollectorImpl.java
+++ b/test/src/main/java/org/apache/rocketmq/test/util/data/collect/impl/ListDataCollectorImpl.java
@@ -39,19 +39,23 @@ public ListDataCollectorImpl(Collection