diff --git a/.travis.yml b/.travis.yml
index 4a70bccff63ac8d0098fe04a5ad95737f7bdb38b..bcf058cb5c925df845bd623900c053ed3579e99f 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -43,6 +43,7 @@ before_script:
- ulimit -c unlimited
script:
+ - mvn verify -DskipTests
- travis_retry mvn -B clean apache-rat:check
- travis_retry mvn -B package jacoco:report coveralls:report
diff --git a/README.md b/README.md
index 1b1398cb792644acc98420072c1ce844e5cac275..eb20e798ea99068f8dc4baa57b77068ca973fc00 100644
--- a/README.md
+++ b/README.md
@@ -15,7 +15,7 @@ It offers a variety of features:
* Messaging patterns including publish/subscribe, request/reply and streaming
* Financial grade transactional message
* Built-in fault tolerance and high availability configuration options base on [DLedger](https://github.com/openmessaging/openmessaging-storage-dledger)
-* A variety of cross language clients, such as Java, C/C++, Python, Go
+* A variety of cross language clients, such as Java, [C/C++](https://github.com/apache/rocketmq-client-cpp), [Python](https://github.com/apache/rocketmq-client-python), [Go](https://github.com/apache/rocketmq-client-go), [Node.js](https://github.com/apache/rocketmq-client-nodejs)
* Pluggable transport protocols, such as TCP, SSL, AIO
* Built-in message tracing capability, also support opentracing
* Versatile big-data and streaming ecosytem integration
diff --git a/acl/pom.xml b/acl/pom.xml
index f2cbdbe9e2ced4bc97d4a905035beb495421718a..bed3c46340d4d15d4916aab701196919d996f6ab 100644
--- a/acl/pom.xml
+++ b/acl/pom.xml
@@ -13,7 +13,7 @@
org.apache.rocketmq
rocketmq-all
- 4.9.2-SNAPSHOT
+ 4.9.3-SNAPSHOT
rocketmq-acl
rocketmq-acl ${project.version}
diff --git a/acl/src/main/java/org/apache/rocketmq/acl/common/AclUtils.java b/acl/src/main/java/org/apache/rocketmq/acl/common/AclUtils.java
index 77abe0e80fbe734576e1b557a889f0e0a2afae47..b801c69c707ec740b98e9f84d4b05e616d36edb1 100644
--- a/acl/src/main/java/org/apache/rocketmq/acl/common/AclUtils.java
+++ b/acl/src/main/java/org/apache/rocketmq/acl/common/AclUtils.java
@@ -23,7 +23,6 @@ import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
-import java.util.ArrayList;
import java.util.Map;
import java.util.SortedMap;
import org.apache.commons.lang3.StringUtils;
@@ -206,64 +205,35 @@ public class AclUtils {
}
public static String expandIP(String netaddress, int part) {
- boolean compress = false;
- int compressIndex = -1;
- String[] strArray = StringUtils.split(netaddress, ":");
- ArrayList indexes = new ArrayList<>();
- for (int i = 0; i < netaddress.length(); i++) {
- if (netaddress.charAt(i) == ':') {
- if (indexes.size() > 0 && i - indexes.get(indexes.size() - 1) == 1) {
- compressIndex = i;
- compress = true;
- }
- indexes.add(i);
+ netaddress = netaddress.toUpperCase();
+ // expand netaddress
+ int separatorCount = StringUtils.countMatches(netaddress, ":");
+ int padCount = part - separatorCount;
+ if (padCount > 0) {
+ StringBuilder padStr = new StringBuilder(":");
+ for (int i = 0; i < padCount; i++) {
+ padStr.append(":");
}
+ netaddress = StringUtils.replace(netaddress, "::", padStr.toString());
}
+ // pad netaddress
+ String[] strArray = StringUtils.splitPreserveAllTokens(netaddress, ":");
for (int i = 0; i < strArray.length; i++) {
if (strArray[i].length() < 4) {
- strArray[i] = "0000".substring(0, 4 - strArray[i].length()) + strArray[i];
+ strArray[i] = StringUtils.leftPad(strArray[i], 4, '0');
}
}
+ // output
StringBuilder sb = new StringBuilder();
- if (compress) {
- int pos = indexes.indexOf(compressIndex);
- int index = 0;
- if (!netaddress.startsWith(":")) {
- for (int i = 0; i < pos; i++) {
- sb.append(strArray[index]).append(":");
- index += 1;
- }
- }
- int zeroNum = part - strArray.length;
- if (netaddress.endsWith(":")) {
- for (int i = 0; i < zeroNum; i++) {
- sb.append("0000");
- if (i != zeroNum - 1) {
- sb.append(":");
- }
- }
- } else {
- for (int i = 0; i < zeroNum; i++) {
- sb.append("0000").append(":");
- }
- for (int i = index; i < strArray.length; i++) {
- sb.append(strArray[i]);
- if (i != strArray.length - 1) {
- sb.append(":");
- }
- }
- }
- } else {
- for (int i = 0; i < strArray.length; i++) {
- sb.append(strArray[i]);
- if (i != strArray.length - 1) {
- sb.append(":");
- }
+ for (int i = 0; i < strArray.length; i++) {
+ sb.append(strArray[i]);
+ if (i != strArray.length - 1) {
+ sb.append(":");
}
}
- return sb.toString().toUpperCase();
+ return sb.toString();
}
public static T getYamlDataObject(String path, Class clazz) {
@@ -308,7 +278,7 @@ public class AclUtils {
JSONObject yamlDataObject = null;
try {
yamlDataObject = AclUtils.getYamlDataObject(fileName,
- JSONObject.class);
+ JSONObject.class);
} catch (Exception e) {
log.error("Convert yaml file to data object error, ", e);
return null;
diff --git a/acl/src/main/java/org/apache/rocketmq/acl/plain/PlainPermissionManager.java b/acl/src/main/java/org/apache/rocketmq/acl/plain/PlainPermissionManager.java
index 809cc759694e5d3d48917a8c87070fe977ff055b..f7af586df49e2908e0949372e4528317ab3b0daf 100644
--- a/acl/src/main/java/org/apache/rocketmq/acl/plain/PlainPermissionManager.java
+++ b/acl/src/main/java/org/apache/rocketmq/acl/plain/PlainPermissionManager.java
@@ -18,13 +18,6 @@ package org.apache.rocketmq.acl.plain;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
-import java.io.File;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
import org.apache.commons.lang3.StringUtils;
import org.apache.rocketmq.acl.common.AclConstants;
import org.apache.rocketmq.acl.common.AclException;
@@ -39,6 +32,14 @@ import org.apache.rocketmq.logging.InternalLogger;
import org.apache.rocketmq.logging.InternalLoggerFactory;
import org.apache.rocketmq.srvutil.FileWatchService;
+import java.io.File;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
public class PlainPermissionManager {
private static final InternalLogger log = InternalLoggerFactory.getLogger(LoggerName.COMMON_LOGGER_NAME);
@@ -194,9 +195,9 @@ public class PlainPermissionManager {
"The secretKey=%s value length should longer than 6",
plainAccessConfig.getSecretKey()));
}
- newAccountsMap.put(AclConstants.CONFIG_SECRET_KEY, (String) plainAccessConfig.getSecretKey());
+ newAccountsMap.put(AclConstants.CONFIG_SECRET_KEY, plainAccessConfig.getSecretKey());
}
- if (!StringUtils.isEmpty(plainAccessConfig.getWhiteRemoteAddress())) {
+ if (plainAccessConfig.getWhiteRemoteAddress() != null) {
newAccountsMap.put(AclConstants.CONFIG_WHITE_ADDR, plainAccessConfig.getWhiteRemoteAddress());
}
if (!StringUtils.isEmpty(String.valueOf(plainAccessConfig.isAdmin()))) {
@@ -208,10 +209,10 @@ public class PlainPermissionManager {
if (!StringUtils.isEmpty(plainAccessConfig.getDefaultGroupPerm())) {
newAccountsMap.put(AclConstants.CONFIG_DEFAULT_GROUP_PERM, plainAccessConfig.getDefaultGroupPerm());
}
- if (plainAccessConfig.getTopicPerms() != null && !plainAccessConfig.getTopicPerms().isEmpty()) {
+ if (plainAccessConfig.getTopicPerms() != null) {
newAccountsMap.put(AclConstants.CONFIG_TOPIC_PERMS, plainAccessConfig.getTopicPerms());
}
- if (plainAccessConfig.getGroupPerms() != null && !plainAccessConfig.getGroupPerms().isEmpty()) {
+ if (plainAccessConfig.getGroupPerms() != null) {
newAccountsMap.put(AclConstants.CONFIG_GROUP_PERMS, plainAccessConfig.getGroupPerms());
}
diff --git a/acl/src/main/java/org/apache/rocketmq/acl/plain/RemoteAddressStrategyFactory.java b/acl/src/main/java/org/apache/rocketmq/acl/plain/RemoteAddressStrategyFactory.java
index 6ec90ee3fad619f36517f1f96b5c40cf020d324b..1c10fae4b94f676ef3e6d81e8f5d94e42fc48ec2 100644
--- a/acl/src/main/java/org/apache/rocketmq/acl/plain/RemoteAddressStrategyFactory.java
+++ b/acl/src/main/java/org/apache/rocketmq/acl/plain/RemoteAddressStrategyFactory.java
@@ -167,7 +167,7 @@ public class RemoteAddressStrategyFactory {
String[] strArray = StringUtils.split(remoteAddr, ".");
if (analysis(strArray, 1) || analysis(strArray, 2) || analysis(strArray, 3)) {
AclUtils.verify(remoteAddr, index - 1);
- StringBuffer sb = new StringBuffer();
+ StringBuilder sb = new StringBuilder();
for (int j = 0; j < index; j++) {
sb.append(strArray[j].trim()).append(".");
}
diff --git a/acl/src/test/java/org/apache/rocketmq/acl/common/AclUtilsTest.java b/acl/src/test/java/org/apache/rocketmq/acl/common/AclUtilsTest.java
index 7df0afa6393346eccfc4f8bc48e1952d8f746ede..e2a212ada8ec4fd2a399000c110b4e68ff36f72c 100644
--- a/acl/src/test/java/org/apache/rocketmq/acl/common/AclUtilsTest.java
+++ b/acl/src/test/java/org/apache/rocketmq/acl/common/AclUtilsTest.java
@@ -202,6 +202,7 @@ public class AclUtilsTest {
@Test
public void expandIPTest() {
+ Assert.assertEquals(AclUtils.expandIP("::", 8), "0000:0000:0000:0000:0000:0000:0000:0000");
Assert.assertEquals(AclUtils.expandIP("::1", 8), "0000:0000:0000:0000:0000:0000:0000:0001");
Assert.assertEquals(AclUtils.expandIP("3::", 8), "0003:0000:0000:0000:0000:0000:0000:0000");
Assert.assertEquals(AclUtils.expandIP("2::2", 8), "0002:0000:0000:0000:0000:0000:0000:0002");
diff --git a/acl/src/test/java/org/apache/rocketmq/acl/plain/PlainAccessValidatorTest.java b/acl/src/test/java/org/apache/rocketmq/acl/plain/PlainAccessValidatorTest.java
index 056f0119354c0aba3d36ec5e4d18d9b8876b3781..a0eb567b694876dd7f90f12e5b120b3daefe86b4 100644
--- a/acl/src/test/java/org/apache/rocketmq/acl/plain/PlainAccessValidatorTest.java
+++ b/acl/src/test/java/org/apache/rocketmq/acl/plain/PlainAccessValidatorTest.java
@@ -19,6 +19,7 @@ package org.apache.rocketmq.acl.plain;
import java.nio.ByteBuffer;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
@@ -524,7 +525,7 @@ public class PlainAccessValidatorTest {
// Verify the dateversion element is correct or not
List
@@ -158,22 +171,7 @@ public class DefaultMQProducer extends ClientConfig implements MQProducer {
*/
public DefaultMQProducer(final String producerGroup, RPCHook rpcHook, boolean enableMsgTrace,
final String customizedTraceTopic) {
- this.producerGroup = producerGroup;
- defaultMQProducerImpl = new DefaultMQProducerImpl(this, rpcHook);
- //if client open the message trace feature
- if (enableMsgTrace) {
- try {
- AsyncTraceDispatcher dispatcher = new AsyncTraceDispatcher(producerGroup, TraceDispatcher.Type.PRODUCE, customizedTraceTopic, rpcHook);
- dispatcher.setHostProducer(this.defaultMQProducerImpl);
- traceDispatcher = dispatcher;
- this.defaultMQProducerImpl.registerSendMessageHook(
- new SendMessageTraceHookImpl(traceDispatcher));
- this.defaultMQProducerImpl.registerEndTransactionHook(
- new EndTransactionTraceHookImpl(traceDispatcher));
- } catch (Throwable e) {
- log.error("system mqtrace hook init failed ,maybe can't send msg trace data");
- }
- }
+ this(null, producerGroup, rpcHook, enableMsgTrace, customizedTraceTopic);
}
/**
@@ -251,9 +249,9 @@ public class DefaultMQProducer extends ClientConfig implements MQProducer {
if (enableMsgTrace) {
try {
AsyncTraceDispatcher dispatcher = new AsyncTraceDispatcher(producerGroup, TraceDispatcher.Type.PRODUCE, customizedTraceTopic, rpcHook);
- dispatcher.setHostProducer(this.getDefaultMQProducerImpl());
+ dispatcher.setHostProducer(this.defaultMQProducerImpl);
traceDispatcher = dispatcher;
- this.getDefaultMQProducerImpl().registerSendMessageHook(
+ this.defaultMQProducerImpl.registerSendMessageHook(
new SendMessageTraceHookImpl(traceDispatcher));
this.defaultMQProducerImpl.registerEndTransactionHook(
new EndTransactionTraceHookImpl(traceDispatcher));
@@ -263,6 +261,14 @@ public class DefaultMQProducer extends ClientConfig implements MQProducer {
}
}
+ @Override
+ public void setUseTLS(boolean useTLS) {
+ super.setUseTLS(useTLS);
+ if (traceDispatcher != null && traceDispatcher instanceof AsyncTraceDispatcher) {
+ ((AsyncTraceDispatcher) traceDispatcher).getTraceProducer().setUseTLS(useTLS);
+ }
+ }
+
/**
* Start this producer instance.
*
@@ -965,6 +971,15 @@ public class DefaultMQProducer extends ClientConfig implements MQProducer {
this.defaultMQProducerImpl.setAsyncSenderExecutor(asyncSenderExecutor);
}
+ /**
+ * Add response code for retrying.
+ *
+ * @param responseCode response code, {@link ResponseCode}
+ */
+ public void addRetryResponseCode(int responseCode) {
+ this.retryResponseCodes.add(responseCode);
+ }
+
private MessageBatch batch(Collection msgs) throws MQClientException {
MessageBatch msgBatch;
try {
@@ -1095,4 +1110,7 @@ public class DefaultMQProducer extends ClientConfig implements MQProducer {
return traceDispatcher;
}
+ public Set getRetryResponseCodes() {
+ return retryResponseCodes;
+ }
}
diff --git a/client/src/main/java/org/apache/rocketmq/client/trace/TraceDataEncoder.java b/client/src/main/java/org/apache/rocketmq/client/trace/TraceDataEncoder.java
index 10aa2413591309fc72b17f090b7b84af548deb86..b4a49a0564b10b040b6ae7865b38e776630b2427 100644
--- a/client/src/main/java/org/apache/rocketmq/client/trace/TraceDataEncoder.java
+++ b/client/src/main/java/org/apache/rocketmq/client/trace/TraceDataEncoder.java
@@ -188,8 +188,9 @@ public class TraceDataEncoder {
.append(ctx.getCostTime()).append(TraceConstants.CONTENT_SPLITOR)//
.append(ctx.isSuccess()).append(TraceConstants.CONTENT_SPLITOR)//
.append(bean.getKeys()).append(TraceConstants.CONTENT_SPLITOR)//
- .append(ctx.getContextCode()).append(TraceConstants.FIELD_SPLITOR);
-
+ .append(ctx.getContextCode()).append(TraceConstants.CONTENT_SPLITOR)
+ .append(ctx.getTimeStamp()).append(TraceConstants.CONTENT_SPLITOR)
+ .append(ctx.getGroupName()).append(TraceConstants.FIELD_SPLITOR);
}
}
break;
diff --git a/client/src/main/java/org/apache/rocketmq/client/trace/TraceView.java b/client/src/main/java/org/apache/rocketmq/client/trace/TraceView.java
index e78d37ab2cdbd4c5f0ece7d43aca814f1f44eb20..7601221cded8fcda3670f34ab15adad56d927671 100644
--- a/client/src/main/java/org/apache/rocketmq/client/trace/TraceView.java
+++ b/client/src/main/java/org/apache/rocketmq/client/trace/TraceView.java
@@ -17,9 +17,9 @@
package org.apache.rocketmq.client.trace;
+import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
-import org.apache.commons.codec.Charsets;
import org.apache.rocketmq.common.message.MessageExt;
public class TraceView {
@@ -40,7 +40,7 @@ public class TraceView {
public static List decodeFromTraceTransData(String key, MessageExt messageExt) {
List messageTraceViewList = new ArrayList();
- String messageBody = new String(messageExt.getBody(), Charsets.UTF_8);
+ String messageBody = new String(messageExt.getBody(), StandardCharsets.UTF_8);
if (messageBody == null || messageBody.length() <= 0) {
return messageTraceViewList;
}
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 3f00d9e4030473f395c9b2a037e50b7e6fde24f0..e1b3bed76fde8416b4c2c2839ed06cfa91c7f393 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
@@ -16,7 +16,6 @@
*/
package org.apache.rocketmq.client.impl;
-import java.lang.reflect.Field;
import org.apache.rocketmq.client.ClientConfig;
import org.apache.rocketmq.client.exception.MQBrokerException;
import org.apache.rocketmq.client.exception.MQClientException;
@@ -29,9 +28,11 @@ import org.apache.rocketmq.client.producer.SendStatus;
import org.apache.rocketmq.common.PlainAccessConfig;
import org.apache.rocketmq.common.message.Message;
import org.apache.rocketmq.common.message.MessageConst;
+import org.apache.rocketmq.common.protocol.RequestCode;
import org.apache.rocketmq.common.protocol.ResponseCode;
import org.apache.rocketmq.common.protocol.header.SendMessageRequestHeader;
import org.apache.rocketmq.common.protocol.header.SendMessageResponseHeader;
+import org.apache.rocketmq.common.protocol.header.namesrv.AddWritePermOfBrokerResponseHeader;
import org.apache.rocketmq.remoting.InvokeCallback;
import org.apache.rocketmq.remoting.RemotingClient;
import org.apache.rocketmq.remoting.exception.RemotingException;
@@ -48,6 +49,8 @@ import org.mockito.invocation.InvocationOnMock;
import org.mockito.junit.MockitoJUnitRunner;
import org.mockito.stubbing.Answer;
+import java.lang.reflect.Field;
+
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Fail.failBecauseExceptionWasNotThrown;
import static org.mockito.ArgumentMatchers.any;
@@ -442,4 +445,27 @@ public class MQClientAPIImplTest {
requestHeader.setMaxReconsumeTimes(10);
return requestHeader;
}
+
+ @Test
+ public void testAddWritePermOfBroker() throws Exception {
+ doAnswer(new Answer() {
+ @Override
+ public Object answer(InvocationOnMock invocationOnMock) throws Throwable {
+ RemotingCommand request = invocationOnMock.getArgument(1);
+ if (request.getCode() != RequestCode.ADD_WRITE_PERM_OF_BROKER) {
+ return null;
+ }
+
+ RemotingCommand response = RemotingCommand.createResponseCommand(AddWritePermOfBrokerResponseHeader.class);
+ AddWritePermOfBrokerResponseHeader responseHeader = (AddWritePermOfBrokerResponseHeader) response.readCustomHeader();
+ response.setCode(ResponseCode.SUCCESS);
+ responseHeader.setAddTopicCount(7);
+ response.addExtField("addTopicCount", String.valueOf(responseHeader.getAddTopicCount()));
+ return response;
+ }
+ }).when(remotingClient).invokeSync(anyString(), any(RemotingCommand.class), anyLong());
+
+ int topicCnt = mqClientAPI.addWritePermOfBroker("127.0.0.1", "default-broker", 1000);
+ assertThat(topicCnt).isEqualTo(7);
+ }
}
\ No newline at end of file
diff --git a/client/src/test/java/org/apache/rocketmq/client/impl/consumer/ConsumeMessageConcurrentlyServiceTest.java b/client/src/test/java/org/apache/rocketmq/client/impl/consumer/ConsumeMessageConcurrentlyServiceTest.java
index e8feb80dd99f45f4713605f797130fba6e75f9e5..6fa76e0380b471dd654efea292d95670307f4a31 100644
--- a/client/src/test/java/org/apache/rocketmq/client/impl/consumer/ConsumeMessageConcurrentlyServiceTest.java
+++ b/client/src/test/java/org/apache/rocketmq/client/impl/consumer/ConsumeMessageConcurrentlyServiceTest.java
@@ -178,7 +178,7 @@ public class ConsumeMessageConcurrentlyServiceTest {
StatsItemSet itemSet = (StatsItemSet)statItmeSetField.get(mgr);
StatsItem item = itemSet.getAndCreateStatsItem(topic + "@" + pushConsumer.getDefaultMQPushConsumerImpl().groupName());
- assertThat(item.getValue().get()).isGreaterThan(0L);
+ assertThat(item.getValue().sum()).isGreaterThan(0L);
MessageExt msg = messageAtomic.get();
assertThat(msg).isNotNull();
assertThat(msg.getTopic()).isEqualTo(topic);
diff --git a/client/src/test/java/org/apache/rocketmq/client/trace/DefaultMQConsumerWithTraceTest.java b/client/src/test/java/org/apache/rocketmq/client/trace/DefaultMQConsumerWithTraceTest.java
index aec7d2cb0e28e57884bb468b41d831ac23ece99b..976380b27234e862cd66b9d29c4058fecc0ef6f7 100644
--- a/client/src/test/java/org/apache/rocketmq/client/trace/DefaultMQConsumerWithTraceTest.java
+++ b/client/src/test/java/org/apache/rocketmq/client/trace/DefaultMQConsumerWithTraceTest.java
@@ -69,6 +69,7 @@ import org.apache.rocketmq.common.topic.TopicValidator;
import org.apache.rocketmq.remoting.RPCHook;
import org.apache.rocketmq.remoting.exception.RemotingException;
import org.junit.After;
+import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -235,6 +236,14 @@ public class DefaultMQConsumerWithTraceTest {
assertThat(msg.getTopic()).isEqualTo(topic);
assertThat(msg.getBody()).isEqualTo(new byte[] {'a'});
}
+
+ @Test
+ public void testPushConsumerWithTraceTLS() {
+ DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("consumerGroup", true);
+ consumer.setUseTLS(true);
+ AsyncTraceDispatcher asyncTraceDispatcher = (AsyncTraceDispatcher) consumer.getTraceDispatcher();
+ Assert.assertTrue(asyncTraceDispatcher.getTraceProducer().isUseTLS());
+ }
private PullRequest createPullRequest() {
PullRequest pullRequest = new PullRequest();
diff --git a/client/src/test/java/org/apache/rocketmq/client/trace/DefaultMQLitePullConsumerWithTraceTest.java b/client/src/test/java/org/apache/rocketmq/client/trace/DefaultMQLitePullConsumerWithTraceTest.java
index 67ae194b880ce5a497b7d0aaac72566276fb1ec5..ce3b832b006f905a72848c5b34e95d9f67be035e 100644
--- a/client/src/test/java/org/apache/rocketmq/client/trace/DefaultMQLitePullConsumerWithTraceTest.java
+++ b/client/src/test/java/org/apache/rocketmq/client/trace/DefaultMQLitePullConsumerWithTraceTest.java
@@ -52,6 +52,7 @@ import org.apache.rocketmq.common.protocol.route.QueueData;
import org.apache.rocketmq.common.protocol.route.TopicRouteData;
import org.apache.rocketmq.common.topic.TopicValidator;
import org.apache.rocketmq.remoting.RPCHook;
+import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -146,6 +147,15 @@ public class DefaultMQLitePullConsumerWithTraceTest {
}
}
+ @Test
+ public void testLitePullConsumerWithTraceTLS() throws Exception {
+ DefaultLitePullConsumer consumer = new DefaultLitePullConsumer("consumerGroup");
+ consumer.setUseTLS(true);
+ consumer.setEnableMsgTrace(true);
+ consumer.start();
+ AsyncTraceDispatcher asyncTraceDispatcher = (AsyncTraceDispatcher) consumer.getTraceDispatcher();
+ Assert.assertTrue(asyncTraceDispatcher.getTraceProducer().isUseTLS());
+ }
private DefaultLitePullConsumer createLitePullConsumerWithDefaultTraceTopic() throws Exception {
DefaultLitePullConsumer litePullConsumer = new DefaultLitePullConsumer(consumerGroup + System.currentTimeMillis());
@@ -302,4 +312,4 @@ public class DefaultMQLitePullConsumerWithTraceTest {
doReturn(false).when(mQClientFactory).updateTopicRouteInfoFromNameServer(anyString());
}
-}
\ No newline at end of file
+}
diff --git a/client/src/test/java/org/apache/rocketmq/client/trace/DefaultMQProducerWithTraceTest.java b/client/src/test/java/org/apache/rocketmq/client/trace/DefaultMQProducerWithTraceTest.java
index 62b34175aa2dbf5fad30076a16ad2b1696addca2..234e32e6807e67fedea7e3177b9dac72cdd2d0bf 100644
--- a/client/src/test/java/org/apache/rocketmq/client/trace/DefaultMQProducerWithTraceTest.java
+++ b/client/src/test/java/org/apache/rocketmq/client/trace/DefaultMQProducerWithTraceTest.java
@@ -39,6 +39,7 @@ import org.apache.rocketmq.common.protocol.route.TopicRouteData;
import org.apache.rocketmq.common.topic.TopicValidator;
import org.apache.rocketmq.remoting.exception.RemotingException;
import org.junit.After;
+import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -143,6 +144,15 @@ public class DefaultMQProducerWithTraceTest {
}
+
+ @Test
+ public void testProducerWithTraceTLS() {
+ DefaultMQProducer producer = new DefaultMQProducer(producerGroupTemp, true);
+ producer.setUseTLS(true);
+ AsyncTraceDispatcher asyncTraceDispatcher = (AsyncTraceDispatcher) producer.getTraceDispatcher();
+ Assert.assertTrue(asyncTraceDispatcher.getTraceProducer().isUseTLS());
+ }
+
@After
public void terminate() {
producer.shutdown();
diff --git a/client/src/test/java/org/apache/rocketmq/client/trace/TraceDataEncoderTest.java b/client/src/test/java/org/apache/rocketmq/client/trace/TraceDataEncoderTest.java
index e268dff3454eb1a7556972b0bc4514944ce6faa1..03381d01ffcac49c6f792bd9bc2dbb45b7f8e1c2 100644
--- a/client/src/test/java/org/apache/rocketmq/client/trace/TraceDataEncoderTest.java
+++ b/client/src/test/java/org/apache/rocketmq/client/trace/TraceDataEncoderTest.java
@@ -189,6 +189,8 @@ public class TraceDataEncoderTest {
subAfterContext.setRequestId("3455848576927");
subAfterContext.setCostTime(20);
subAfterContext.setSuccess(true);
+ subAfterContext.setTimeStamp(1625883640000L);
+ subAfterContext.setGroupName("GroupName-test");
subAfterContext.setContextCode(98623046);
TraceBean bean = new TraceBean();
bean.setMsgId("AC1415116D1418B4AAC217FE1B4E0000");
@@ -200,7 +202,7 @@ public class TraceDataEncoderTest {
String transData = traceTransferBean.getTransData();
Assert.assertNotNull(transData);
String[] items = transData.split(String.valueOf(TraceConstants.CONTENT_SPLITOR));
- Assert.assertEquals(7, items.length);
+ Assert.assertEquals(9, items.length);
}
diff --git a/client/src/test/java/org/apache/rocketmq/client/trace/TraceViewTest.java b/client/src/test/java/org/apache/rocketmq/client/trace/TraceViewTest.java
index b1fdbaf965ad1d6fe30e35ea9fdcc672a52b29e2..0397db256abf9e3fb7e3dc2d822ee5ab90b1754f 100644
--- a/client/src/test/java/org/apache/rocketmq/client/trace/TraceViewTest.java
+++ b/client/src/test/java/org/apache/rocketmq/client/trace/TraceViewTest.java
@@ -17,12 +17,12 @@
package org.apache.rocketmq.client.trace;
-import org.apache.commons.codec.Charsets;
import org.apache.rocketmq.common.message.MessageExt;
import org.apache.rocketmq.common.message.MessageType;
import org.junit.Assert;
import org.junit.Test;
+import java.nio.charset.StandardCharsets;
import java.util.List;
public class TraceViewTest {
@@ -46,7 +46,7 @@ public class TraceViewTest {
.append(true).append(TraceConstants.FIELD_SPLITOR)
.toString();
MessageExt message = new MessageExt();
- message.setBody(messageBody.getBytes(Charsets.UTF_8));
+ message.setBody(messageBody.getBytes(StandardCharsets.UTF_8));
String key = "AC1415116D1418B4AAC217FE1B4E0000";
List traceViews = TraceView.decodeFromTraceTransData(key, message);
Assert.assertEquals(traceViews.size(), 1);
diff --git a/common/pom.xml b/common/pom.xml
index defddd224f1f32c7f2301fa70f99fc13581518d6..d8274d55b61283e4ca1a3bd5cd1ab7e157ddfd48 100644
--- a/common/pom.xml
+++ b/common/pom.xml
@@ -19,7 +19,7 @@
org.apache.rocketmq
rocketmq-all
- 4.9.2-SNAPSHOT
+ 4.9.3-SNAPSHOT
4.0.0
diff --git a/common/src/main/java/org/apache/rocketmq/common/MQVersion.java b/common/src/main/java/org/apache/rocketmq/common/MQVersion.java
index 1d6d1f5355c651aa828d423affe417af36d528dc..bb30e9a5d44d4263bdebf6a878476261016b2832 100644
--- a/common/src/main/java/org/apache/rocketmq/common/MQVersion.java
+++ b/common/src/main/java/org/apache/rocketmq/common/MQVersion.java
@@ -18,7 +18,7 @@ package org.apache.rocketmq.common;
public class MQVersion {
- public static final int CURRENT_VERSION = Version.V4_9_1.ordinal();
+ public static final int CURRENT_VERSION = Version.V4_9_2.ordinal();
public static String getVersionDesc(int value) {
int length = Version.values().length;
diff --git a/common/src/main/java/org/apache/rocketmq/common/MixAll.java b/common/src/main/java/org/apache/rocketmq/common/MixAll.java
index 9d95ecb5ea4cfaa7d445318f079afcbb658654a9..ec1e1f0245f43f1ac0bad7eaa80fc68088e69002 100644
--- a/common/src/main/java/org/apache/rocketmq/common/MixAll.java
+++ b/common/src/main/java/org/apache/rocketmq/common/MixAll.java
@@ -58,6 +58,7 @@ public class MixAll {
public static final String DEFAULT_PRODUCER_GROUP = "DEFAULT_PRODUCER";
public static final String DEFAULT_CONSUMER_GROUP = "DEFAULT_CONSUMER";
public static final String TOOLS_CONSUMER_GROUP = "TOOLS_CONSUMER";
+ public static final String SCHEDULE_CONSUMER_GROUP = "SCHEDULE_CONSUMER";
public static final String FILTERSRV_CONSUMER_GROUP = "FILTERSRV_CONSUMER";
public static final String MONITOR_CONSUMER_GROUP = "__MONITOR_CONSUMER";
public static final String CLIENT_INNER_PRODUCER_GROUP = "CLIENT_INNER_PRODUCER";
diff --git a/common/src/main/java/org/apache/rocketmq/common/UtilAll.java b/common/src/main/java/org/apache/rocketmq/common/UtilAll.java
index aa6920817f14efeb58a421b4eb33fe33078cadaf..ea22aa7397f18a4899e05573f4696798ec330155 100644
--- a/common/src/main/java/org/apache/rocketmq/common/UtilAll.java
+++ b/common/src/main/java/org/apache/rocketmq/common/UtilAll.java
@@ -21,7 +21,6 @@ import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.lang.management.ManagementFactory;
-import java.lang.management.RuntimeMXBean;
import java.net.Inet4Address;
import java.net.Inet6Address;
import java.net.InetAddress;
@@ -39,7 +38,6 @@ import java.util.Map;
import java.util.zip.CRC32;
import java.util.zip.DeflaterOutputStream;
import java.util.zip.InflaterInputStream;
-import org.apache.commons.lang3.StringUtils;
import org.apache.commons.validator.routines.InetAddressValidator;
import org.apache.rocketmq.common.constant.LoggerName;
import org.apache.rocketmq.logging.InternalLogger;
@@ -53,12 +51,11 @@ public class UtilAll {
public static final String YYYY_MM_DD_HH_MM_SS_SSS = "yyyy-MM-dd#HH:mm:ss:SSS";
public static final String YYYYMMDDHHMMSS = "yyyyMMddHHmmss";
final static char[] HEX_ARRAY = "0123456789ABCDEF".toCharArray();
+ final static String HOST_NAME = ManagementFactory.getRuntimeMXBean().getName(); // format: "pid@hostname"
public static int getPid() {
- RuntimeMXBean runtime = ManagementFactory.getRuntimeMXBean();
- String name = runtime.getName(); // format: "pid@hostname"
try {
- return Integer.parseInt(name.substring(0, name.indexOf('@')));
+ return Integer.parseInt(HOST_NAME.substring(0, HOST_NAME.indexOf('@')));
} catch (Exception e) {
return -1;
}
@@ -199,6 +196,11 @@ public class UtilAll {
cal.get(Calendar.SECOND));
}
+ public static boolean isPathExists(final String path) {
+ File file = new File(path);
+ return file.exists();
+ }
+
public static double getDiskPartitionSpaceUsedPercent(final String path) {
if (null == path || path.isEmpty()) {
log.error("Error when measuring disk space usage, path is null or empty, path : {}", path);
@@ -218,10 +220,15 @@ public class UtilAll {
long totalSpace = file.getTotalSpace();
if (totalSpace > 0) {
- long freeSpace = file.getFreeSpace();
- long usedSpace = totalSpace - freeSpace;
-
- return usedSpace / (double) totalSpace;
+ long usedSpace = totalSpace - file.getFreeSpace();
+ long usableSpace = file.getUsableSpace();
+ long entireSpace = usedSpace + usableSpace;
+ long roundNum = 0;
+ if (usedSpace * 100 % entireSpace != 0) {
+ roundNum = 1;
+ }
+ long result = usedSpace * 100 / entireSpace + roundNum;
+ return result / 100.0;
}
} catch (Exception e) {
log.error("Error when measuring disk space usage, got exception: :", e);
@@ -461,7 +468,7 @@ public class UtilAll {
if (ip.length != 4) {
throw new RuntimeException("illegal ipv4 bytes");
}
-
+
InetAddressValidator validator = InetAddressValidator.getInstance();
return validator.isValidInet4Address(ipToIPv4Str(ip));
}
@@ -561,27 +568,28 @@ public class UtilAll {
}
}
- public static String list2String(List list, String splitor) {
- if (list == null || list.size() == 0) {
+ public static String join(List list, String splitter) {
+ if (list == null) {
return null;
}
- StringBuffer str = new StringBuffer();
+
+ StringBuilder str = new StringBuilder();
for (int i = 0; i < list.size(); i++) {
str.append(list.get(i));
if (i == list.size() - 1) {
- continue;
+ break;
}
- str.append(splitor);
+ str.append(splitter);
}
return str.toString();
}
- public static List string2List(String str, String splitor) {
- if (StringUtils.isEmpty(str)) {
+ public static List split(String str, String splitter) {
+ if (str == null) {
return null;
}
- String[] addrArray = str.split(splitor);
+ String[] addrArray = str.split(splitter);
return Arrays.asList(addrArray);
}
}
diff --git a/common/src/main/java/org/apache/rocketmq/common/message/Message.java b/common/src/main/java/org/apache/rocketmq/common/message/Message.java
index c9a133b4d0cfd4969b936fac7889b0788bc89edb..48e1f45a7f0f6439725a744ce4c6091393f9e739 100644
--- a/common/src/main/java/org/apache/rocketmq/common/message/Message.java
+++ b/common/src/main/java/org/apache/rocketmq/common/message/Message.java
@@ -43,11 +43,13 @@ public class Message implements Serializable {
this.flag = flag;
this.body = body;
- if (tags != null && tags.length() > 0)
+ if (tags != null && tags.length() > 0) {
this.setTags(tags);
+ }
- if (keys != null && keys.length() > 0)
+ if (keys != null && keys.length() > 0) {
this.setKeys(keys);
+ }
this.setWaitStoreMsgOK(waitStoreMsgOK);
}
@@ -127,7 +129,7 @@ public class Message implements Serializable {
}
public void setKeys(Collection keys) {
- StringBuffer sb = new StringBuffer();
+ StringBuilder sb = new StringBuilder();
for (String k : keys) {
sb.append(k);
sb.append(MessageConst.KEY_SEPARATOR);
@@ -151,8 +153,9 @@ public class Message implements Serializable {
public boolean isWaitStoreMsgOK() {
String result = this.getProperty(MessageConst.PROPERTY_WAIT_STORE_MSG_OK);
- if (null == result)
+ if (null == result) {
return true;
+ }
return Boolean.parseBoolean(result);
}
diff --git a/common/src/main/java/org/apache/rocketmq/common/protocol/NamespaceUtil.java b/common/src/main/java/org/apache/rocketmq/common/protocol/NamespaceUtil.java
index 704eb90bd7a583029c6c1bb0bbece9d16272902c..60fadaab181ecc012d4ffcf15c00f96328a1d77c 100644
--- a/common/src/main/java/org/apache/rocketmq/common/protocol/NamespaceUtil.java
+++ b/common/src/main/java/org/apache/rocketmq/common/protocol/NamespaceUtil.java
@@ -120,7 +120,7 @@ public class NamespaceUtil {
return null;
}
- return new StringBuffer()
+ return new StringBuilder()
.append(MixAll.RETRY_GROUP_TOPIC_PREFIX)
.append(wrapNamespace(namespace, consumerGroup))
.toString();
diff --git a/common/src/main/java/org/apache/rocketmq/common/protocol/RequestCode.java b/common/src/main/java/org/apache/rocketmq/common/protocol/RequestCode.java
index 75ceff38cfb9b8bbd086007be095012c0d076f8d..5624a7ec01c7247ac202739b00bf164ed40986f5 100644
--- a/common/src/main/java/org/apache/rocketmq/common/protocol/RequestCode.java
+++ b/common/src/main/java/org/apache/rocketmq/common/protocol/RequestCode.java
@@ -188,4 +188,6 @@ public class RequestCode {
public static final int SEND_REPLY_MESSAGE_V2 = 325;
public static final int PUSH_REPLY_MESSAGE_TO_CLIENT = 326;
+
+ public static final int ADD_WRITE_PERM_OF_BROKER = 327;
}
diff --git a/common/src/main/java/org/apache/rocketmq/common/protocol/header/namesrv/AddWritePermOfBrokerRequestHeader.java b/common/src/main/java/org/apache/rocketmq/common/protocol/header/namesrv/AddWritePermOfBrokerRequestHeader.java
new file mode 100644
index 0000000000000000000000000000000000000000..17fd3f5ea7e887cfbb973834fdcf10665982eb9f
--- /dev/null
+++ b/common/src/main/java/org/apache/rocketmq/common/protocol/header/namesrv/AddWritePermOfBrokerRequestHeader.java
@@ -0,0 +1,39 @@
+/*
+ * 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.common.protocol.header.namesrv;
+
+import org.apache.rocketmq.remoting.CommandCustomHeader;
+import org.apache.rocketmq.remoting.annotation.CFNotNull;
+import org.apache.rocketmq.remoting.exception.RemotingCommandException;
+
+public class AddWritePermOfBrokerRequestHeader implements CommandCustomHeader {
+ @CFNotNull
+ private String brokerName;
+
+ @Override
+ public void checkFields() throws RemotingCommandException {
+
+ }
+
+ public String getBrokerName() {
+ return brokerName;
+ }
+
+ public void setBrokerName(String brokerName) {
+ this.brokerName = brokerName;
+ }
+}
diff --git a/common/src/main/java/org/apache/rocketmq/common/protocol/header/namesrv/AddWritePermOfBrokerResponseHeader.java b/common/src/main/java/org/apache/rocketmq/common/protocol/header/namesrv/AddWritePermOfBrokerResponseHeader.java
new file mode 100644
index 0000000000000000000000000000000000000000..d217206a9403176050404f3a8b53d25b8379c1cf
--- /dev/null
+++ b/common/src/main/java/org/apache/rocketmq/common/protocol/header/namesrv/AddWritePermOfBrokerResponseHeader.java
@@ -0,0 +1,38 @@
+/*
+ * 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.common.protocol.header.namesrv;
+
+import org.apache.rocketmq.remoting.CommandCustomHeader;
+import org.apache.rocketmq.remoting.annotation.CFNotNull;
+import org.apache.rocketmq.remoting.exception.RemotingCommandException;
+
+public class AddWritePermOfBrokerResponseHeader implements CommandCustomHeader {
+ @CFNotNull
+ private Integer addTopicCount;
+
+ @Override
+ public void checkFields() throws RemotingCommandException {
+ }
+
+ public Integer getAddTopicCount() {
+ return addTopicCount;
+ }
+
+ public void setAddTopicCount(Integer addTopicCount) {
+ this.addTopicCount = addTopicCount;
+ }
+}
diff --git a/common/src/main/java/org/apache/rocketmq/common/stats/StatsItem.java b/common/src/main/java/org/apache/rocketmq/common/stats/StatsItem.java
index b078551ad2ca006d2b2c5f84589bbb3e059d068f..d016662afadf8b524b5d2ada564da7e3a0a3784d 100644
--- a/common/src/main/java/org/apache/rocketmq/common/stats/StatsItem.java
+++ b/common/src/main/java/org/apache/rocketmq/common/stats/StatsItem.java
@@ -20,15 +20,16 @@ package org.apache.rocketmq.common.stats;
import java.util.LinkedList;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicLong;
+import java.util.concurrent.atomic.LongAdder;
+
import org.apache.rocketmq.common.UtilAll;
import org.apache.rocketmq.logging.InternalLogger;
public class StatsItem {
- private final AtomicLong value = new AtomicLong(0);
+ private final LongAdder value = new LongAdder();
- private final AtomicLong times = new AtomicLong(0);
+ private final LongAdder times = new LongAdder();
private final LinkedList csListMinute = new LinkedList();
@@ -157,8 +158,8 @@ public class StatsItem {
if (this.csListMinute.size() == 0) {
this.csListMinute.add(new CallSnapshot(System.currentTimeMillis() - 10 * 1000, 0, 0));
}
- this.csListMinute.add(new CallSnapshot(System.currentTimeMillis(), this.times.get(), this.value
- .get()));
+ this.csListMinute.add(new CallSnapshot(System.currentTimeMillis(), this.times.sum(), this.value
+ .sum()));
if (this.csListMinute.size() > 7) {
this.csListMinute.removeFirst();
}
@@ -170,8 +171,8 @@ public class StatsItem {
if (this.csListHour.size() == 0) {
this.csListHour.add(new CallSnapshot(System.currentTimeMillis() - 10 * 60 * 1000, 0, 0));
}
- this.csListHour.add(new CallSnapshot(System.currentTimeMillis(), this.times.get(), this.value
- .get()));
+ this.csListHour.add(new CallSnapshot(System.currentTimeMillis(), this.times.sum(), this.value
+ .sum()));
if (this.csListHour.size() > 7) {
this.csListHour.removeFirst();
}
@@ -183,8 +184,8 @@ public class StatsItem {
if (this.csListDay.size() == 0) {
this.csListDay.add(new CallSnapshot(System.currentTimeMillis() - 1 * 60 * 60 * 1000, 0, 0));
}
- this.csListDay.add(new CallSnapshot(System.currentTimeMillis(), this.times.get(), this.value
- .get()));
+ this.csListDay.add(new CallSnapshot(System.currentTimeMillis(), this.times.sum(), this.value
+ .sum()));
if (this.csListDay.size() > 25) {
this.csListDay.removeFirst();
}
@@ -214,7 +215,7 @@ public class StatsItem {
ss.getAvgpt());
}
- public AtomicLong getValue() {
+ public LongAdder getValue() {
return value;
}
@@ -226,7 +227,7 @@ public class StatsItem {
return statsName;
}
- public AtomicLong getTimes() {
+ public LongAdder getTimes() {
return times;
}
}
diff --git a/common/src/main/java/org/apache/rocketmq/common/stats/StatsItemSet.java b/common/src/main/java/org/apache/rocketmq/common/stats/StatsItemSet.java
index a28d008d3e2d07dd2be3b1dcda20a0241d8b023c..8d5418ef6ce448e01eae7ec6c00686e0a277da62 100644
--- a/common/src/main/java/org/apache/rocketmq/common/stats/StatsItemSet.java
+++ b/common/src/main/java/org/apache/rocketmq/common/stats/StatsItemSet.java
@@ -154,14 +154,14 @@ public class StatsItemSet {
public void addValue(final String statsKey, final int incValue, final int incTimes) {
StatsItem statsItem = this.getAndCreateStatsItem(statsKey);
- statsItem.getValue().addAndGet(incValue);
- statsItem.getTimes().addAndGet(incTimes);
+ statsItem.getValue().add(incValue);
+ statsItem.getTimes().add(incTimes);
}
public void addRTValue(final String statsKey, final int incValue, final int incTimes) {
StatsItem statsItem = this.getAndCreateRTStatsItem(statsKey);
- statsItem.getValue().addAndGet(incValue);
- statsItem.getTimes().addAndGet(incTimes);
+ statsItem.getValue().add(incValue);
+ statsItem.getTimes().add(incTimes);
}
public void delValue(final String statsKey) {
diff --git a/common/src/test/java/org/apache/rocketmq/common/RemotingUtilTest.java b/common/src/test/java/org/apache/rocketmq/common/RemotingUtilTest.java
index 586689637b3c826b90da37c1675fc713eed2eaed..19346e6bca21316ba463734e069b573a361b5b14 100644
--- a/common/src/test/java/org/apache/rocketmq/common/RemotingUtilTest.java
+++ b/common/src/test/java/org/apache/rocketmq/common/RemotingUtilTest.java
@@ -28,4 +28,16 @@ public class RemotingUtilTest {
assertThat(localAddress).isNotNull();
assertThat(localAddress.length()).isGreaterThan(0);
}
+
+ @Test
+ public void testConvert2IpStringWithIp() {
+ String result = RemotingUtil.convert2IpString("127.0.0.1:9876");
+ assertThat(result).isEqualTo("127.0.0.1:9876");
+ }
+
+ @Test
+ public void testConvert2IpStringWithHost() {
+ String result = RemotingUtil.convert2IpString("localhost:9876");
+ assertThat(result).isEqualTo("127.0.0.1:9876");
+ }
}
diff --git a/common/src/test/java/org/apache/rocketmq/common/UtilAllTest.java b/common/src/test/java/org/apache/rocketmq/common/UtilAllTest.java
index b854099a5bd757a984d402e86d6da06b0119ae12..ffbcd33e4c1c71ff9a53d7e0cdaa79759871a8f7 100644
--- a/common/src/test/java/org/apache/rocketmq/common/UtilAllTest.java
+++ b/common/src/test/java/org/apache/rocketmq/common/UtilAllTest.java
@@ -19,11 +19,15 @@ package org.apache.rocketmq.common;
import java.net.InetAddress;
import java.net.UnknownHostException;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
import java.util.Properties;
import org.junit.Test;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.within;
+import static org.junit.Assert.assertEquals;
public class UtilAllTest {
@@ -109,6 +113,15 @@ public class UtilAllTest {
assertThat(UtilAll.ipToIPv6Str(nonInternal.getAddress()).toUpperCase()).isEqualTo("2408:4004:0180:8100:3FAA:1DDE:2B3F:898A");
}
+ @Test
+ public void testJoin() {
+ List list = Arrays.asList("groupA=DENY", "groupB=PUB|SUB", "groupC=SUB");
+ String comma = ",";
+ assertEquals("groupA=DENY,groupB=PUB|SUB,groupC=SUB", UtilAll.join(list, comma));
+ assertEquals(null, UtilAll.join(null, comma));
+ assertEquals("", UtilAll.join(Collections.emptyList(), comma));
+ }
+
static class DemoConfig {
private int demoWidth = 0;
private int demoLength = 0;
diff --git a/common/src/test/java/org/apache/rocketmq/common/stats/StatsItemSetTest.java b/common/src/test/java/org/apache/rocketmq/common/stats/StatsItemSetTest.java
index 5b4c5d823d3357f38fb98601b2d2fb61f3190ca5..d834160d63c37116ebf5c72ef3fea87bc9641a36 100644
--- a/common/src/test/java/org/apache/rocketmq/common/stats/StatsItemSetTest.java
+++ b/common/src/test/java/org/apache/rocketmq/common/stats/StatsItemSetTest.java
@@ -23,6 +23,8 @@ import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;
+import java.util.concurrent.atomic.LongAdder;
+
import org.apache.rocketmq.common.ThreadFactoryImpl;
import org.junit.After;
import org.junit.Test;
@@ -95,7 +97,7 @@ public class StatsItemSetTest {
}
}
- private AtomicLong test_unit() throws InterruptedException {
+ private LongAdder test_unit() throws InterruptedException {
final StatsItemSet statsItemSet = new StatsItemSet("topicTest", scheduler, null);
executor = new ThreadPoolExecutor(10, 20, 10, TimeUnit.SECONDS,
new ArrayBlockingQueue(100), new ThreadFactoryImpl("testMultiThread"));
diff --git a/common/src/test/java/org/apache/rocketmq/common/utils/IOTinyUtilsTest.java b/common/src/test/java/org/apache/rocketmq/common/utils/IOTinyUtilsTest.java
index e03e0b9648e88305ea78135f167b3a2e85d49505..6a63eecc2230a5477aec8cc7cd729d01f609a8ea 100644
--- a/common/src/test/java/org/apache/rocketmq/common/utils/IOTinyUtilsTest.java
+++ b/common/src/test/java/org/apache/rocketmq/common/utils/IOTinyUtilsTest.java
@@ -82,7 +82,7 @@ public class IOTinyUtilsTest {
@Test
public void testReadLines() throws Exception {
- StringBuffer sb = new StringBuffer();
+ StringBuilder sb = new StringBuilder();
for (int i = 0; i < 10; i++) {
sb.append("testReadLines").append("\n");
}
@@ -95,7 +95,7 @@ public class IOTinyUtilsTest {
@Test
public void testToBufferedReader() throws Exception {
- StringBuffer sb = new StringBuffer();
+ StringBuilder sb = new StringBuilder();
for (int i = 0; i < 10; i++) {
sb.append("testToBufferedReader").append("\n");
}
diff --git a/distribution/bin/export.sh b/distribution/bin/export.sh
new file mode 100644
index 0000000000000000000000000000000000000000..2b323e8b21d3d0a6b225abd5a10e5f749827c442
--- /dev/null
+++ b/distribution/bin/export.sh
@@ -0,0 +1,89 @@
+#!/bin/bash
+
+# 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.
+
+if [ -z "$ROCKETMQ_HOME" ]; then
+ ## resolve links - $0 may be a link to maven's home
+ PRG="$0"
+
+ # need this for relative symlinks
+ while [ -h "$PRG" ]; do
+ ls=$(ls -ld "$PRG")
+ link=$(expr "$ls" : '.*-> \(.*\)$')
+ if expr "$link" : '/.*' >/dev/null; then
+ PRG="$link"
+ else
+ PRG="$(dirname "$PRG")/$link"
+ fi
+ done
+
+ saveddir=$(pwd)
+
+ ROCKETMQ_HOME=$(dirname "$PRG")/..
+
+ # make it fully qualified
+ ROCKETMQ_HOME=$(cd "$ROCKETMQ_HOME" && pwd)
+
+ cd "$saveddir"
+fi
+
+export ROCKETMQ_HOME
+
+namesrvAddr=
+while [ -z "${namesrvAddr}" ]; do
+ read -p "Enter name server address list:" namesrvAddr
+done
+
+clusterName=
+while [ -z "${clusterName}" ]; do
+ read -p "Choose a cluster to export:" clusterName
+done
+
+read -p "Enter file path to export [default /tmp/rocketmq/export]:" filePath
+if [ -z "${filePath}" ]; then
+ filePath="/tmp/rocketmq/config"
+fi
+
+if [[ -e ${filePath} ]]; then
+ rm -rf ${filePath}
+fi
+
+sh ${ROCKETMQ_HOME}/bin/mqadmin exportMetrics -c ${clusterName} -n ${namesrvAddr} -f ${filePath}
+sh ${ROCKETMQ_HOME}/bin/mqadmin exportConfigs -c ${clusterName} -n ${namesrvAddr} -f ${filePath}
+sh ${ROCKETMQ_HOME}/bin/mqadmin exportMetadata -c ${clusterName} -n ${namesrvAddr} -f ${filePath}
+
+cd ${filePath} || exit
+
+configs=$(cat ./configs.json)
+if [ -z "$configs" ]; then
+ configs="{}"
+fi
+metadata=$(cat ./metadata.json)
+if [ -z "$metadata" ]; then
+ metadata="{}"
+fi
+metrics=$(cat ./metrics.json)
+if [ -z "$metrics" ]; then
+ metrics="{}"
+fi
+
+echo "{
+ \"configs\": ${configs},
+ \"metadata\": ${metadata},
+ \"metrics\": ${metrics}
+ }" >rocketmq-metadata-export.json
+
+echo -e "[INFO] The RocketMQ metadata has been exported to the file:${filePath}/rocketmq-metadata-export.json"
diff --git a/distribution/pom.xml b/distribution/pom.xml
index 6f10ff4f9ade0f7e618a4dbfcc31eed20e9fd389..df5ddc4647ad1853ebfac5b507226e8975afd748 100644
--- a/distribution/pom.xml
+++ b/distribution/pom.xml
@@ -20,7 +20,7 @@
org.apache.rocketmq
rocketmq-all
- 4.9.2-SNAPSHOT
+ 4.9.3-SNAPSHOT
rocketmq-distribution
rocketmq-distribution ${project.version}
diff --git a/docs/cn/RocketMQ_Example.md b/docs/cn/RocketMQ_Example.md
index d924ce1d7d1f54e8c68ed63ddaa040ad5445f13d..e26bcdf043d4b826181e276410bb42dde67353c7 100644
--- a/docs/cn/RocketMQ_Example.md
+++ b/docs/cn/RocketMQ_Example.md
@@ -54,7 +54,7 @@
org.apache.rocketmq
rocketmq-client
- 4.3.0
+ 4.9.1
```
`gradle`
@@ -120,13 +120,15 @@ public class AsyncProducer {
producer.send(msg, new SendCallback() {
@Override
public void onSuccess(SendResult sendResult) {
+ countDownLatch.countDown();
System.out.printf("%-10d OK %s %n", index,
sendResult.getMsgId());
}
@Override
public void onException(Throwable e) {
- System.out.printf("%-10d Exception %s %n", index, e);
- e.printStackTrace();
+ countDownLatch.countDown();
+ System.out.printf("%-10d Exception %s %n", index, e);
+ e.printStackTrace();
}
});
}
@@ -570,7 +572,7 @@ public class ListSplitter implements Iterator> {
return currIndex;
}
private int calcMessageSize(Message message) {
- int tmpSize = message.getTopic().length() + message.getBody().length();
+ int tmpSize = message.getTopic().length() + message.getBody().length;
Map properties = message.getProperties();
for (Map.Entry entry : properties.entrySet()) {
tmpSize += entry.getKey().length() + entry.getValue().length();
diff --git a/docs/cn/operation.md b/docs/cn/operation.md
index bc2d38527fce649921818ce19928cbe07c01462b..e5275887b5ffc2ef22400aa3d3829c89b9a9b94f 100644
--- a/docs/cn/operation.md
+++ b/docs/cn/operation.md
@@ -25,7 +25,7 @@ The Name Server boot success...
### 启动Broker
$ nohup sh bin/mqbroker -n localhost:9876 &
-### 验证Name Server 是否启动成功,例如Broker的IP为:192.168.1.2,且名称为broker-a
+### 验证Broker是否启动成功,例如Broker的IP为:192.168.1.2,且名称为broker-a
$ tail -f ~/logs/rocketmqlogs/broker.log
The broker[broker-a, 192.169.1.2:10911] boot success...
```
@@ -566,6 +566,14 @@ $ nohup sh mqbroker -n 192.168.1.1:9876 -c $ROCKETMQ_HOME/conf/2m-2s-sync/broker
-b |
BrokerName |
+
+ addWritePerm |
+ 从NameServer上添加 Broker写权限 |
+ -b |
+ BrokerName |
+
-n |
NameServer 服务地址,格式 ip:port |
diff --git a/docs/en/CLITools.md b/docs/en/CLITools.md
index 47ba69e57124f2cfa387c513f0ffdb4b3016853c..c53b69bf8c0297f4bca0c83d277c3245f60d15d0 100644
--- a/docs/en/CLITools.md
+++ b/docs/en/CLITools.md
@@ -426,6 +426,14 @@ Before introducing the mqadmin management tool, the following points need to be
-b |
Declare the BrokerName |
+
+ addWritePerm |
+ Add write permissions for broker from nameServer |
+ -b |
+ Declare the BrokerName |
+
-n |
Service address used to specify nameServer and formatted as ip:port |
diff --git a/docs/en/Example_Batch.md b/docs/en/Example_Batch.md
index 11bb42ffbe27b28046795892c30b7adcf14f8213..06461bb51d75ec02869453e735fb0d19558bb1f6 100644
--- a/docs/en/Example_Batch.md
+++ b/docs/en/Example_Batch.md
@@ -57,7 +57,7 @@ public class ListSplitter implements Iterator> {
return currIndex;
}
private int calcMessageSize(Message message) {
- int tmpSize = message.getTopic().length() + message.getBody().length();
+ int tmpSize = message.getTopic().length() + message.getBody().length;
Map properties = message.getProperties();
for (Map.Entry entry : properties.entrySet()) {
tmpSize += entry.getKey().length() + entry.getValue().length();
@@ -78,4 +78,4 @@ while (splitter.hasNext()) {
// handle the error
}
}
-```
\ No newline at end of file
+```
diff --git a/docs/en/operation.md b/docs/en/operation.md
index 1d41e984443fcf958aed4a4527767b9a82695515..1b8375fb6c391d33c6c56bdcb83d198fa3a45e90 100644
--- a/docs/en/operation.md
+++ b/docs/en/operation.md
@@ -25,7 +25,7 @@ The Name Server boot success...
### start Broker
$ nohup sh bin/mqbroker -n localhost:9876 &
-### check whether Name Server is successfully started, eg: Broker's IP is 192.168.1.2, Broker's name is broker-a
+### check whether Broker is successfully started, eg: Broker's IP is 192.168.1.2, Broker's name is broker-a
$ tail -f ~/logs/rocketmqlogs/Broker.log
The broker[broker-a, 192.169.1.2:10911] boot success...
```
diff --git a/example/pom.xml b/example/pom.xml
index 9d6aec6433bc64c225ee4e26b0deef02c3066944..5c2548285042174999d9e0c61374af3c9423b1eb 100644
--- a/example/pom.xml
+++ b/example/pom.xml
@@ -19,7 +19,7 @@
rocketmq-all
org.apache.rocketmq
- 4.9.2-SNAPSHOT
+ 4.9.3-SNAPSHOT
4.0.0
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 843b84bf8ed6d0f9de83e770bfdbd6069003fe6b..cf207cd4518c9c2112e031c7a8005381871bfc99 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
@@ -16,7 +16,7 @@
*/
package org.apache.rocketmq.example.benchmark;
-import java.io.UnsupportedEncodingException;
+import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
@@ -26,11 +26,14 @@ import java.util.TimerTask;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicLong;
+import java.util.concurrent.atomic.LongAdder;
+
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.PosixParser;
import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.lang3.RandomStringUtils;
import org.apache.rocketmq.acl.common.AclClientRPCHook;
import org.apache.rocketmq.acl.common.SessionCredentials;
import org.apache.rocketmq.client.exception.MQBrokerException;
@@ -42,13 +45,14 @@ import org.apache.rocketmq.client.producer.SendStatus;
import org.apache.rocketmq.logging.InternalLogger;
import org.apache.rocketmq.common.message.Message;
import org.apache.rocketmq.remoting.RPCHook;
-import org.apache.rocketmq.remoting.common.RemotingHelper;
import org.apache.rocketmq.remoting.exception.RemotingException;
import org.apache.rocketmq.srvutil.ServerUtil;
public class BatchProducer {
- public static void main(String[] args) throws MQClientException, UnsupportedEncodingException {
+ private static byte[] msgBody;
+
+ public static void main(String[] args) throws MQClientException {
Options options = ServerUtil.buildCommandlineOptions(new Options());
CommandLine commandLine = ServerUtil.parseCmdLine("benchmarkBatchProducer", args, buildCommandlineOptions(options), new PosixParser());
@@ -72,6 +76,12 @@ public class BatchProducer {
System.out.printf("topic: %s threadCount: %d messageSize: %d batchSize: %d keyEnable: %s propertySize: %d tagCount: %d traceEnable: %s aclEnable: %s%n",
topic, threadCount, messageSize, batchSize, keyEnable, propertySize, tagCount, msgTraceEnable, aclEnable);
+ StringBuilder sb = new StringBuilder(messageSize);
+ for (int i = 0; i < messageSize; i++) {
+ sb.append(RandomStringUtils.randomAlphanumeric(1));
+ }
+ msgBody = sb.toString().getBytes(StandardCharsets.UTF_8);
+
final StatsBenchmarkBatchProducer statsBenchmark = new StatsBenchmarkBatchProducer();
statsBenchmark.start();
@@ -85,14 +95,7 @@ public class BatchProducer {
@Override
public void run() {
while (true) {
- List msgs;
-
- try {
- msgs = buildBathMessage(batchSize, messageSize, topic);
- } catch (UnsupportedEncodingException e) {
- e.printStackTrace();
- return;
- }
+ List msgs = buildBathMessage(batchSize, topic);
if (CollectionUtils.isEmpty(msgs)) {
return;
@@ -100,22 +103,22 @@ public class BatchProducer {
try {
long beginTimestamp = System.currentTimeMillis();
- long sendSucCount = statsBenchmark.getSendMessageSuccessCount().get();
+ long sendSucCount = statsBenchmark.getSendMessageSuccessCount().longValue();
setKeys(keyEnable, msgs, String.valueOf(beginTimestamp / 1000));
setTags(tagCount, msgs, sendSucCount);
setProperties(propertySize, msgs);
SendResult sendResult = producer.send(msgs);
if (sendResult.getSendStatus() == SendStatus.SEND_OK) {
- statsBenchmark.getSendRequestSuccessCount().incrementAndGet();
- statsBenchmark.getSendMessageSuccessCount().addAndGet(msgs.size());
+ statsBenchmark.getSendRequestSuccessCount().increment();
+ statsBenchmark.getSendMessageSuccessCount().add(msgs.size());
} else {
- statsBenchmark.getSendRequestFailedCount().incrementAndGet();
- statsBenchmark.getSendMessageFailedCount().addAndGet(msgs.size());
+ statsBenchmark.getSendRequestFailedCount().increment();
+ statsBenchmark.getSendMessageFailedCount().add(msgs.size());
}
long currentRT = System.currentTimeMillis() - beginTimestamp;
- statsBenchmark.getSendMessageSuccessTimeTotal().addAndGet(currentRT);
- long prevMaxRT = statsBenchmark.getSendMessageMaxRT().get();
+ statsBenchmark.getSendMessageSuccessTimeTotal().add(currentRT);
+ long prevMaxRT = statsBenchmark.getSendMessageMaxRT().longValue();
while (currentRT > prevMaxRT) {
boolean updated = statsBenchmark.getSendMessageMaxRT().compareAndSet(prevMaxRT, currentRT);
if (updated) {
@@ -125,8 +128,8 @@ public class BatchProducer {
prevMaxRT = statsBenchmark.getSendMessageMaxRT().get();
}
} catch (RemotingException e) {
- statsBenchmark.getSendRequestFailedCount().incrementAndGet();
- statsBenchmark.getSendMessageFailedCount().addAndGet(msgs.size());
+ statsBenchmark.getSendRequestFailedCount().increment();
+ statsBenchmark.getSendMessageFailedCount().add(msgs.size());
log.error("[BENCHMARK_PRODUCER] Send Exception", e);
try {
@@ -134,22 +137,22 @@ public class BatchProducer {
} catch (InterruptedException ignored) {
}
} catch (InterruptedException e) {
- statsBenchmark.getSendRequestFailedCount().incrementAndGet();
- statsBenchmark.getSendMessageFailedCount().addAndGet(msgs.size());
+ statsBenchmark.getSendRequestFailedCount().increment();
+ statsBenchmark.getSendMessageFailedCount().add(msgs.size());
try {
Thread.sleep(3000);
} catch (InterruptedException e1) {
}
- statsBenchmark.getSendRequestFailedCount().incrementAndGet();
- statsBenchmark.getSendMessageFailedCount().addAndGet(msgs.size());
+ statsBenchmark.getSendRequestFailedCount().increment();
+ statsBenchmark.getSendMessageFailedCount().add(msgs.size());
log.error("[BENCHMARK_PRODUCER] Send Exception", e);
} catch (MQClientException e) {
- statsBenchmark.getSendRequestFailedCount().incrementAndGet();
- statsBenchmark.getSendMessageFailedCount().addAndGet(msgs.size());
+ statsBenchmark.getSendRequestFailedCount().increment();
+ statsBenchmark.getSendMessageFailedCount().add(msgs.size());
log.error("[BENCHMARK_PRODUCER] Send Exception", e);
} catch (MQBrokerException e) {
- statsBenchmark.getSendRequestFailedCount().incrementAndGet();
- statsBenchmark.getSendMessageFailedCount().addAndGet(msgs.size());
+ statsBenchmark.getSendRequestFailedCount().increment();
+ statsBenchmark.getSendMessageFailedCount().add(msgs.size());
log.error("[BENCHMARK_PRODUCER] Send Exception", e);
try {
Thread.sleep(3000);
@@ -234,23 +237,12 @@ public class BatchProducer {
return defaultValue;
}
- private static List buildBathMessage(int batchSize, int messageSize,
- String topic) throws UnsupportedEncodingException {
+ private static List buildBathMessage(final int batchSize, final String topic) {
List batchMessage = new ArrayList<>(batchSize);
-
for (int i = 0; i < batchSize; i++) {
- Message msg = new Message();
- msg.setTopic(topic);
-
- StringBuilder sb = new StringBuilder();
- for (int j = 0; j < messageSize; j += 10) {
- sb.append("hello baby");
- }
-
- msg.setBody(sb.toString().getBytes(RemotingHelper.DEFAULT_CHARSET));
+ Message msg = new Message(topic, msgBody);
batchMessage.add(msg);
}
-
return batchMessage;
}
@@ -313,17 +305,17 @@ public class BatchProducer {
class StatsBenchmarkBatchProducer {
- private final AtomicLong sendRequestSuccessCount = new AtomicLong(0L);
+ private final LongAdder sendRequestSuccessCount = new LongAdder();
- private final AtomicLong sendRequestFailedCount = new AtomicLong(0L);
+ private final LongAdder sendRequestFailedCount = new LongAdder();
- private final AtomicLong sendMessageSuccessTimeTotal = new AtomicLong(0L);
+ private final LongAdder sendMessageSuccessTimeTotal = new LongAdder();
private final AtomicLong sendMessageMaxRT = new AtomicLong(0L);
- private final AtomicLong sendMessageSuccessCount = new AtomicLong(0L);
+ private final LongAdder sendMessageSuccessCount = new LongAdder();
- private final AtomicLong sendMessageFailedCount = new AtomicLong(0L);
+ private final LongAdder sendMessageFailedCount = new LongAdder();
private final Timer timer = new Timer("BenchmarkTimerThread", true);
@@ -332,25 +324,25 @@ class StatsBenchmarkBatchProducer {
public Long[] createSnapshot() {
Long[] snap = new Long[] {
System.currentTimeMillis(),
- this.sendRequestSuccessCount.get(),
- this.sendRequestFailedCount.get(),
- this.sendMessageSuccessCount.get(),
- this.sendMessageFailedCount.get(),
- this.sendMessageSuccessTimeTotal.get(),
+ this.sendRequestSuccessCount.longValue(),
+ this.sendRequestFailedCount.longValue(),
+ this.sendMessageSuccessCount.longValue(),
+ this.sendMessageFailedCount.longValue(),
+ this.sendMessageSuccessTimeTotal.longValue(),
};
return snap;
}
- public AtomicLong getSendRequestSuccessCount() {
+ public LongAdder getSendRequestSuccessCount() {
return sendRequestSuccessCount;
}
- public AtomicLong getSendRequestFailedCount() {
+ public LongAdder getSendRequestFailedCount() {
return sendRequestFailedCount;
}
- public AtomicLong getSendMessageSuccessTimeTotal() {
+ public LongAdder getSendMessageSuccessTimeTotal() {
return sendMessageSuccessTimeTotal;
}
@@ -358,11 +350,11 @@ class StatsBenchmarkBatchProducer {
return sendMessageMaxRT;
}
- public AtomicLong getSendMessageSuccessCount() {
+ public LongAdder getSendMessageSuccessCount() {
return sendMessageSuccessCount;
}
- public AtomicLong getSendMessageFailedCount() {
+ public LongAdder getSendMessageFailedCount() {
return sendMessageFailedCount;
}
@@ -390,7 +382,7 @@ class StatsBenchmarkBatchProducer {
final double averageMsgRT = (end[5] - begin[5]) / (double) (end[3] - begin[3]);
System.out.printf("Current Time: %s Send TPS: %d Send MPS: %d Max RT(ms): %d Average RT(ms): %7.3f Average Message RT(ms): %7.3f Send Failed: %d Send Message Failed: %d%n",
- System.currentTimeMillis(), sendTps, sendMps, getSendMessageMaxRT().get(), averageRT, averageMsgRT, end[2], end[4]);
+ System.currentTimeMillis(), sendTps, sendMps, getSendMessageMaxRT().longValue(), averageRT, averageMsgRT, end[2], end[4]);
}
}
diff --git a/example/src/main/java/org/apache/rocketmq/example/benchmark/Consumer.java b/example/src/main/java/org/apache/rocketmq/example/benchmark/Consumer.java
index d3ac36c2046042090bc6bac1f08ce306810bb846..7d26509d2bc2dc8bc393f789c7147009b38fc8ea 100644
--- a/example/src/main/java/org/apache/rocketmq/example/benchmark/Consumer.java
+++ b/example/src/main/java/org/apache/rocketmq/example/benchmark/Consumer.java
@@ -17,18 +17,12 @@
package org.apache.rocketmq.example.benchmark;
-import java.io.IOException;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Timer;
-import java.util.TimerTask;
-import java.util.concurrent.ThreadLocalRandom;
-import java.util.concurrent.atomic.AtomicLong;
-
+import java.util.concurrent.atomic.LongAdder;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.PosixParser;
+import org.apache.commons.lang3.concurrent.BasicThreadFactory;
import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer;
import org.apache.rocketmq.client.consumer.MessageSelector;
import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyContext;
@@ -42,6 +36,16 @@ import org.apache.rocketmq.common.message.MessageExt;
import org.apache.rocketmq.remoting.RPCHook;
import org.apache.rocketmq.srvutil.ServerUtil;
+import java.io.IOException;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.TimerTask;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.ScheduledThreadPoolExecutor;
+import java.util.concurrent.ThreadLocalRandom;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicLong;
+
public class Consumer {
public static void main(String[] args) throws MQClientException, IOException {
@@ -71,11 +75,12 @@ public class Consumer {
final StatsBenchmarkConsumer statsBenchmarkConsumer = new StatsBenchmarkConsumer();
- final Timer timer = new Timer("BenchmarkTimerThread", true);
+ ScheduledExecutorService executorService = new ScheduledThreadPoolExecutor(1,
+ new BasicThreadFactory.Builder().namingPattern("BenchmarkTimerThread-%d").daemon(true).build());
final LinkedList snapshotList = new LinkedList();
- timer.scheduleAtFixedRate(new TimerTask() {
+ executorService.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
snapshotList.addLast(statsBenchmarkConsumer.createSnapshot());
@@ -83,9 +88,9 @@ public class Consumer {
snapshotList.removeFirst();
}
}
- }, 1000, 1000);
+ }, 1000, 1000, TimeUnit.MILLISECONDS);
- timer.scheduleAtFixedRate(new TimerTask() {
+ executorService.scheduleAtFixedRate(new TimerTask() {
private void printStats() {
if (snapshotList.size() >= 10) {
Long[] begin = snapshotList.getFirst();
@@ -116,7 +121,7 @@ public class Consumer {
e.printStackTrace();
}
}
- }, 10000, 10000);
+ }, 10000, 10000, TimeUnit.MILLISECONDS);
RPCHook rpcHook = aclEnable ? AclClient.getAclRPCHook() : null;
DefaultMQPushConsumer consumer = new DefaultMQPushConsumer(group, rpcHook, new AllocateMessageQueueAveragely(), msgTraceEnable, null);
@@ -151,20 +156,20 @@ public class Consumer {
MessageExt msg = msgs.get(0);
long now = System.currentTimeMillis();
- statsBenchmarkConsumer.getReceiveMessageTotalCount().incrementAndGet();
+ statsBenchmarkConsumer.getReceiveMessageTotalCount().increment();
long born2ConsumerRT = now - msg.getBornTimestamp();
- statsBenchmarkConsumer.getBorn2ConsumerTotalRT().addAndGet(born2ConsumerRT);
+ statsBenchmarkConsumer.getBorn2ConsumerTotalRT().add(born2ConsumerRT);
long store2ConsumerRT = now - msg.getStoreTimestamp();
- statsBenchmarkConsumer.getStore2ConsumerTotalRT().addAndGet(store2ConsumerRT);
+ statsBenchmarkConsumer.getStore2ConsumerTotalRT().add(store2ConsumerRT);
compareAndSetMax(statsBenchmarkConsumer.getBorn2ConsumerMaxRT(), born2ConsumerRT);
compareAndSetMax(statsBenchmarkConsumer.getStore2ConsumerMaxRT(), store2ConsumerRT);
if (ThreadLocalRandom.current().nextDouble() < failRate) {
- statsBenchmarkConsumer.getFailCount().incrementAndGet();
+ statsBenchmarkConsumer.getFailCount().increment();
return ConsumeConcurrentlyStatus.RECONSUME_LATER;
} else {
return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
@@ -229,39 +234,39 @@ public class Consumer {
}
class StatsBenchmarkConsumer {
- private final AtomicLong receiveMessageTotalCount = new AtomicLong(0L);
+ private final LongAdder receiveMessageTotalCount = new LongAdder();
- private final AtomicLong born2ConsumerTotalRT = new AtomicLong(0L);
+ private final LongAdder born2ConsumerTotalRT = new LongAdder();
- private final AtomicLong store2ConsumerTotalRT = new AtomicLong(0L);
+ private final LongAdder store2ConsumerTotalRT = new LongAdder();
private final AtomicLong born2ConsumerMaxRT = new AtomicLong(0L);
private final AtomicLong store2ConsumerMaxRT = new AtomicLong(0L);
- private final AtomicLong failCount = new AtomicLong(0L);
+ private final LongAdder failCount = new LongAdder();
public Long[] createSnapshot() {
Long[] snap = new Long[] {
System.currentTimeMillis(),
- this.receiveMessageTotalCount.get(),
- this.born2ConsumerTotalRT.get(),
- this.store2ConsumerTotalRT.get(),
- this.failCount.get()
+ this.receiveMessageTotalCount.longValue(),
+ this.born2ConsumerTotalRT.longValue(),
+ this.store2ConsumerTotalRT.longValue(),
+ this.failCount.longValue()
};
return snap;
}
- public AtomicLong getReceiveMessageTotalCount() {
+ public LongAdder getReceiveMessageTotalCount() {
return receiveMessageTotalCount;
}
- public AtomicLong getBorn2ConsumerTotalRT() {
+ public LongAdder getBorn2ConsumerTotalRT() {
return born2ConsumerTotalRT;
}
- public AtomicLong getStore2ConsumerTotalRT() {
+ public LongAdder getStore2ConsumerTotalRT() {
return store2ConsumerTotalRT;
}
@@ -273,7 +278,7 @@ class StatsBenchmarkConsumer {
return store2ConsumerMaxRT;
}
- public AtomicLong getFailCount() {
+ public LongAdder getFailCount() {
return failCount;
}
}
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 32d4b9f7462eb9e3a5ad373295fffc6932970e3a..feb25cd910c1dc8e88786e54296ebac6fa75ffe6 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
@@ -16,35 +16,40 @@
*/
package org.apache.rocketmq.example.benchmark;
-import java.io.UnsupportedEncodingException;
-import java.util.Arrays;
-import java.util.LinkedList;
-import java.util.Random;
-import java.util.Timer;
-import java.util.TimerTask;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicLong;
-
+import java.nio.charset.StandardCharsets;
+import java.util.concurrent.atomic.LongAdder;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.PosixParser;
+import org.apache.commons.lang3.RandomStringUtils;
+import org.apache.commons.lang3.concurrent.BasicThreadFactory;
import org.apache.rocketmq.client.exception.MQBrokerException;
import org.apache.rocketmq.client.exception.MQClientException;
import org.apache.rocketmq.client.log.ClientLogger;
import org.apache.rocketmq.client.producer.DefaultMQProducer;
-import org.apache.rocketmq.logging.InternalLogger;
import org.apache.rocketmq.common.message.Message;
+import org.apache.rocketmq.logging.InternalLogger;
import org.apache.rocketmq.remoting.RPCHook;
-import org.apache.rocketmq.remoting.common.RemotingHelper;
import org.apache.rocketmq.remoting.exception.RemotingException;
import org.apache.rocketmq.srvutil.ServerUtil;
+import java.util.Arrays;
+import java.util.LinkedList;
+import java.util.Random;
+import java.util.TimerTask;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.ScheduledThreadPoolExecutor;
+import java.util.concurrent.atomic.AtomicLong;
+
public class Producer {
- public static void main(String[] args) throws MQClientException, UnsupportedEncodingException {
+ private static byte[] msgBody;
+
+ public static void main(String[] args) throws MQClientException {
Options options = ServerUtil.buildCommandlineOptions(new Options());
CommandLine commandLine = ServerUtil.parseCmdLine("benchmarkProducer", args, buildCommandlineOptions(options), new PosixParser());
@@ -67,13 +72,20 @@ public class Producer {
System.out.printf("topic: %s threadCount: %d messageSize: %d keyEnable: %s propertySize: %d tagCount: %d traceEnable: %s aclEnable: %s messageQuantity: %d%n delayEnable: %s%n delayLevel: %s%n",
topic, threadCount, messageSize, keyEnable, propertySize, tagCount, msgTraceEnable, aclEnable, messageNum, delayEnable, delayLevel);
+ StringBuilder sb = new StringBuilder(messageSize);
+ for (int i = 0; i < messageSize; i++) {
+ sb.append(RandomStringUtils.randomAlphanumeric(1));
+ }
+ msgBody = sb.toString().getBytes(StandardCharsets.UTF_8);
+
final InternalLogger log = ClientLogger.getLog();
final ExecutorService sendThreadPool = Executors.newFixedThreadPool(threadCount);
final StatsBenchmarkProducer statsBenchmark = new StatsBenchmarkProducer();
- final Timer timer = new Timer("BenchmarkTimerThread", true);
+ ScheduledExecutorService executorService = new ScheduledThreadPoolExecutor(1,
+ new BasicThreadFactory.Builder().namingPattern("BenchmarkTimerThread-%d").daemon(true).build());
final LinkedList snapshotList = new LinkedList();
@@ -87,7 +99,7 @@ public class Producer {
}
}
- timer.scheduleAtFixedRate(new TimerTask() {
+ executorService.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
snapshotList.addLast(statsBenchmark.createSnapshot());
@@ -95,9 +107,9 @@ public class Producer {
snapshotList.removeFirst();
}
}
- }, 1000, 1000);
+ }, 1000, 1000, TimeUnit.MILLISECONDS);
- timer.scheduleAtFixedRate(new TimerTask() {
+ executorService.scheduleAtFixedRate(new TimerTask() {
private void printStats() {
if (snapshotList.size() >= 10) {
doPrintStats(snapshotList, statsBenchmark, false);
@@ -112,7 +124,7 @@ public class Producer {
e.printStackTrace();
}
}
- }, 10000, 10000);
+ }, 10000, 10000, TimeUnit.MILLISECONDS);
RPCHook rpcHook = aclEnable ? AclClient.getAclRPCHook() : null;
final DefaultMQProducer producer = new DefaultMQProducer("benchmark_producer", rpcHook, msgTraceEnable, null);
@@ -138,13 +150,7 @@ public class Producer {
int num = 0;
while (true) {
try {
- final Message msg;
- try {
- msg = buildMessage(messageSize, topic);
- } catch (UnsupportedEncodingException e) {
- e.printStackTrace();
- return;
- }
+ final Message msg = buildMessage(topic);
final long beginTimestamp = System.currentTimeMillis();
if (keyEnable) {
msg.setKeys(String.valueOf(beginTimestamp / 1000));
@@ -153,8 +159,7 @@ public class Producer {
msg.setDelayTimeLevel(delayLevel);
}
if (tagCount > 0) {
- long sendSucCount = statsBenchmark.getReceiveResponseSuccessCount().get();
- msg.setTags(String.format("tag%d", sendSucCount % tagCount));
+ msg.setTags(String.format("tag%d", System.currentTimeMillis() % tagCount));
}
if (propertySize > 0) {
if (msg.getProperties() != null) {
@@ -177,20 +182,20 @@ public class Producer {
}
}
producer.send(msg);
- statsBenchmark.getSendRequestSuccessCount().incrementAndGet();
- statsBenchmark.getReceiveResponseSuccessCount().incrementAndGet();
+ statsBenchmark.getSendRequestSuccessCount().increment();
+ statsBenchmark.getReceiveResponseSuccessCount().increment();
final long currentRT = System.currentTimeMillis() - beginTimestamp;
- statsBenchmark.getSendMessageSuccessTimeTotal().addAndGet(currentRT);
- long prevMaxRT = statsBenchmark.getSendMessageMaxRT().get();
+ statsBenchmark.getSendMessageSuccessTimeTotal().add(currentRT);
+ long prevMaxRT = statsBenchmark.getSendMessageMaxRT().longValue();
while (currentRT > prevMaxRT) {
boolean updated = statsBenchmark.getSendMessageMaxRT().compareAndSet(prevMaxRT, currentRT);
if (updated)
break;
- prevMaxRT = statsBenchmark.getSendMessageMaxRT().get();
+ prevMaxRT = statsBenchmark.getSendMessageMaxRT().longValue();
}
} catch (RemotingException e) {
- statsBenchmark.getSendRequestFailedCount().incrementAndGet();
+ statsBenchmark.getSendRequestFailedCount().increment();
log.error("[BENCHMARK_PRODUCER] Send Exception", e);
try {
@@ -198,16 +203,16 @@ public class Producer {
} catch (InterruptedException ignored) {
}
} catch (InterruptedException e) {
- statsBenchmark.getSendRequestFailedCount().incrementAndGet();
+ statsBenchmark.getSendRequestFailedCount().increment();
try {
Thread.sleep(3000);
} catch (InterruptedException e1) {
}
} catch (MQClientException e) {
- statsBenchmark.getSendRequestFailedCount().incrementAndGet();
+ statsBenchmark.getSendRequestFailedCount().increment();
log.error("[BENCHMARK_PRODUCER] Send Exception", e);
} catch (MQBrokerException e) {
- statsBenchmark.getReceiveResponseFailedCount().incrementAndGet();
+ statsBenchmark.getReceiveResponseFailedCount().increment();
log.error("[BENCHMARK_PRODUCER] Send Exception", e);
try {
Thread.sleep(3000);
@@ -224,13 +229,18 @@ public class Producer {
try {
sendThreadPool.shutdown();
sendThreadPool.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS);
- timer.cancel();
+ executorService.shutdown();
+ try {
+ executorService.awaitTermination(5000, TimeUnit.MILLISECONDS);
+ } catch (InterruptedException e) {
+ }
+
if (snapshotList.size() > 1) {
doPrintStats(snapshotList, statsBenchmark, true);
} else {
System.out.printf("[Complete] Send Total: %d Send Failed: %d Response Failed: %d%n",
- statsBenchmark.getSendRequestSuccessCount().get() + statsBenchmark.getSendRequestFailedCount().get(),
- statsBenchmark.getSendRequestFailedCount().get(), statsBenchmark.getReceiveResponseFailedCount().get());
+ statsBenchmark.getSendRequestSuccessCount().longValue() + statsBenchmark.getSendRequestFailedCount().longValue(),
+ statsBenchmark.getSendRequestFailedCount().longValue(), statsBenchmark.getReceiveResponseFailedCount().longValue());
}
producer.shutdown();
} catch (InterruptedException e) {
@@ -282,18 +292,8 @@ public class Producer {
return options;
}
- private static Message buildMessage(final int messageSize, final String topic) throws UnsupportedEncodingException {
- Message msg = new Message();
- msg.setTopic(topic);
-
- StringBuilder sb = new StringBuilder();
- for (int i = 0; i < messageSize; i += 10) {
- sb.append("hello baby");
- }
-
- msg.setBody(sb.toString().getBytes(RemotingHelper.DEFAULT_CHARSET));
-
- return msg;
+ private static Message buildMessage(final String topic) {
+ return new Message(topic, msgBody);
}
private static void doPrintStats(final LinkedList snapshotList, final StatsBenchmarkProducer statsBenchmark, boolean done) {
@@ -305,58 +305,58 @@ public class Producer {
if (done) {
System.out.printf("[Complete] Send Total: %d Send TPS: %d Max RT(ms): %d Average RT(ms): %7.3f Send Failed: %d Response Failed: %d%n",
- statsBenchmark.getSendRequestSuccessCount().get() + statsBenchmark.getSendRequestFailedCount().get(),
- sendTps, statsBenchmark.getSendMessageMaxRT().get(), averageRT, end[2], end[4]);
+ statsBenchmark.getSendRequestSuccessCount().longValue() + statsBenchmark.getSendRequestFailedCount().longValue(),
+ sendTps, statsBenchmark.getSendMessageMaxRT().longValue(), averageRT, end[2], end[4]);
} else {
System.out.printf("Current Time: %s Send TPS: %d Max RT(ms): %d Average RT(ms): %7.3f Send Failed: %d Response Failed: %d%n",
- System.currentTimeMillis(), sendTps, statsBenchmark.getSendMessageMaxRT().get(), averageRT, end[2], end[4]);
+ System.currentTimeMillis(), sendTps, statsBenchmark.getSendMessageMaxRT().longValue(), averageRT, end[2], end[4]);
}
}
}
class StatsBenchmarkProducer {
- private final AtomicLong sendRequestSuccessCount = new AtomicLong(0L);
+ private final LongAdder sendRequestSuccessCount = new LongAdder();
- private final AtomicLong sendRequestFailedCount = new AtomicLong(0L);
+ private final LongAdder sendRequestFailedCount = new LongAdder();
- private final AtomicLong receiveResponseSuccessCount = new AtomicLong(0L);
+ private final LongAdder receiveResponseSuccessCount = new LongAdder();
- private final AtomicLong receiveResponseFailedCount = new AtomicLong(0L);
+ private final LongAdder receiveResponseFailedCount = new LongAdder();
- private final AtomicLong sendMessageSuccessTimeTotal = new AtomicLong(0L);
+ private final LongAdder sendMessageSuccessTimeTotal = new LongAdder();
private final AtomicLong sendMessageMaxRT = new AtomicLong(0L);
public Long[] createSnapshot() {
Long[] snap = new Long[] {
System.currentTimeMillis(),
- this.sendRequestSuccessCount.get(),
- this.sendRequestFailedCount.get(),
- this.receiveResponseSuccessCount.get(),
- this.receiveResponseFailedCount.get(),
- this.sendMessageSuccessTimeTotal.get(),
+ this.sendRequestSuccessCount.longValue(),
+ this.sendRequestFailedCount.longValue(),
+ this.receiveResponseSuccessCount.longValue(),
+ this.receiveResponseFailedCount.longValue(),
+ this.sendMessageSuccessTimeTotal.longValue(),
};
return snap;
}
- public AtomicLong getSendRequestSuccessCount() {
+ public LongAdder getSendRequestSuccessCount() {
return sendRequestSuccessCount;
}
- public AtomicLong getSendRequestFailedCount() {
+ public LongAdder getSendRequestFailedCount() {
return sendRequestFailedCount;
}
- public AtomicLong getReceiveResponseSuccessCount() {
+ public LongAdder getReceiveResponseSuccessCount() {
return receiveResponseSuccessCount;
}
- public AtomicLong getReceiveResponseFailedCount() {
+ public LongAdder getReceiveResponseFailedCount() {
return receiveResponseFailedCount;
}
- public AtomicLong getSendMessageSuccessTimeTotal() {
+ public LongAdder getSendMessageSuccessTimeTotal() {
return sendMessageSuccessTimeTotal;
}
diff --git a/example/src/main/java/org/apache/rocketmq/example/benchmark/TransactionProducer.java b/example/src/main/java/org/apache/rocketmq/example/benchmark/TransactionProducer.java
index 1b511d8a9e5ffef29452badc44176ad5833855a7..767a96b40bb33482bf402d27f48e0754fb4b9db7 100644
--- a/example/src/main/java/org/apache/rocketmq/example/benchmark/TransactionProducer.java
+++ b/example/src/main/java/org/apache/rocketmq/example/benchmark/TransactionProducer.java
@@ -17,26 +17,11 @@
package org.apache.rocketmq.example.benchmark;
-import java.io.UnsupportedEncodingException;
-import java.nio.ByteBuffer;
-import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.LinkedHashMap;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Timer;
-import java.util.TimerTask;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.ThreadLocalRandom;
-import java.util.concurrent.atomic.AtomicLong;
-
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.PosixParser;
+import org.apache.commons.lang3.concurrent.BasicThreadFactory;
import org.apache.rocketmq.client.exception.MQClientException;
import org.apache.rocketmq.client.producer.LocalTransactionState;
import org.apache.rocketmq.client.producer.SendResult;
@@ -48,9 +33,28 @@ import org.apache.rocketmq.common.message.MessageConst;
import org.apache.rocketmq.common.message.MessageExt;
import org.apache.rocketmq.srvutil.ServerUtil;
+import java.io.UnsupportedEncodingException;
+import java.nio.ByteBuffer;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.LinkedHashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.TimerTask;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ThreadLocalRandom;
+import java.util.concurrent.atomic.AtomicLong;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.ScheduledThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.LongAdder;
+
public class TransactionProducer {
private static final long START_TIME = System.currentTimeMillis();
- private static final AtomicLong MSG_COUNT = new AtomicLong(0);
+ private static final LongAdder MSG_COUNT = new LongAdder();
//broker max check times should less than this value
static final int MAX_CHECK_RESULT_IN_MSG = 20;
@@ -75,11 +79,12 @@ public class TransactionProducer {
final StatsBenchmarkTProducer statsBenchmark = new StatsBenchmarkTProducer();
- final Timer timer = new Timer("BenchmarkTimerThread", true);
+ ScheduledExecutorService executorService = new ScheduledThreadPoolExecutor(1,
+ new BasicThreadFactory.Builder().namingPattern("BenchmarkTimerThread-%d").daemon(true).build());
final LinkedList snapshotList = new LinkedList<>();
- timer.scheduleAtFixedRate(new TimerTask() {
+ executorService.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
snapshotList.addLast(statsBenchmark.createSnapshot());
@@ -87,9 +92,9 @@ public class TransactionProducer {
snapshotList.removeFirst();
}
}
- }, 1000, 1000);
+ }, 1000, 1000, TimeUnit.MILLISECONDS);
- timer.scheduleAtFixedRate(new TimerTask() {
+ executorService.scheduleAtFixedRate(new TimerTask() {
private void printStats() {
if (snapshotList.size() >= 10) {
Snapshot begin = snapshotList.getFirst();
@@ -121,7 +126,7 @@ public class TransactionProducer {
e.printStackTrace();
}
}
- }, 10000, 10000);
+ }, 10000, 10000, TimeUnit.MILLISECONDS);
final TransactionListener transactionCheckListener = new TransactionListenerImpl(statsBenchmark, config);
final TransactionMQProducer producer = new TransactionMQProducer(
@@ -154,7 +159,7 @@ public class TransactionProducer {
success = false;
} finally {
final long currentRT = System.currentTimeMillis() - beginTimestamp;
- statsBenchmark.getSendMessageTimeTotal().addAndGet(currentRT);
+ statsBenchmark.getSendMessageTimeTotal().add(currentRT);
long prevMaxRT = statsBenchmark.getSendMessageMaxRT().get();
while (currentRT > prevMaxRT) {
boolean updated = statsBenchmark.getSendMessageMaxRT()
@@ -165,9 +170,9 @@ public class TransactionProducer {
prevMaxRT = statsBenchmark.getSendMessageMaxRT().get();
}
if (success) {
- statsBenchmark.getSendRequestSuccessCount().incrementAndGet();
+ statsBenchmark.getSendRequestSuccessCount().increment();
} else {
- statsBenchmark.getSendRequestFailedCount().incrementAndGet();
+ statsBenchmark.getSendRequestFailedCount().increment();
}
if (config.sendInterval > 0) {
try {
@@ -190,7 +195,9 @@ public class TransactionProducer {
ByteBuffer buf = ByteBuffer.wrap(bs);
buf.putLong(config.batchId);
long sendMachineId = START_TIME << 32;
- long msgId = sendMachineId | MSG_COUNT.getAndIncrement();
+ long count = MSG_COUNT.longValue();
+ long msgId = sendMachineId | count;
+ MSG_COUNT.increment();
buf.putLong(msgId);
// save send tx result in message
@@ -312,7 +319,7 @@ class TransactionListenerImpl implements TransactionListener {
// message not generated in this test
return LocalTransactionState.ROLLBACK_MESSAGE;
}
- statBenchmark.getCheckCount().incrementAndGet();
+ statBenchmark.getCheckCount().increment();
int times = 0;
try {
@@ -335,7 +342,7 @@ class TransactionListenerImpl implements TransactionListener {
dup = newCheckLog.equals(oldCheckLog);
}
if (dup) {
- statBenchmark.getDuplicatedCheckCount().incrementAndGet();
+ statBenchmark.getDuplicatedCheckCount().increment();
}
if (msgMeta.sendResult != LocalTransactionState.UNKNOW) {
System.out.printf("%s unexpected check: msgId=%s,txId=%s,checkTimes=%s,sendResult=%s\n",
@@ -343,7 +350,7 @@ class TransactionListenerImpl implements TransactionListener {
msg.getMsgId(), msg.getTransactionId(),
msg.getUserProperty(MessageConst.PROPERTY_TRANSACTION_CHECK_TIMES),
msgMeta.sendResult.toString());
- statBenchmark.getUnexpectedCheckCount().incrementAndGet();
+ statBenchmark.getUnexpectedCheckCount().increment();
return msgMeta.sendResult;
}
@@ -354,7 +361,7 @@ class TransactionListenerImpl implements TransactionListener {
new SimpleDateFormat("HH:mm:ss,SSS").format(new Date()),
msg.getMsgId(), msg.getTransactionId(),
msg.getUserProperty(MessageConst.PROPERTY_TRANSACTION_CHECK_TIMES), s);
- statBenchmark.getUnexpectedCheckCount().incrementAndGet();
+ statBenchmark.getUnexpectedCheckCount().increment();
return s;
}
}
@@ -381,42 +388,42 @@ class Snapshot {
}
class StatsBenchmarkTProducer {
- private final AtomicLong sendRequestSuccessCount = new AtomicLong(0L);
+ private final LongAdder sendRequestSuccessCount = new LongAdder();
- private final AtomicLong sendRequestFailedCount = new AtomicLong(0L);
+ private final LongAdder sendRequestFailedCount = new LongAdder();
- private final AtomicLong sendMessageTimeTotal = new AtomicLong(0L);
+ private final LongAdder sendMessageTimeTotal = new LongAdder();
private final AtomicLong sendMessageMaxRT = new AtomicLong(0L);
- private final AtomicLong checkCount = new AtomicLong(0L);
+ private final LongAdder checkCount = new LongAdder();
- private final AtomicLong unexpectedCheckCount = new AtomicLong(0L);
+ private final LongAdder unexpectedCheckCount = new LongAdder();
- private final AtomicLong duplicatedCheckCount = new AtomicLong(0);
+ private final LongAdder duplicatedCheckCount = new LongAdder();
public Snapshot createSnapshot() {
Snapshot s = new Snapshot();
s.endTime = System.currentTimeMillis();
- s.sendRequestSuccessCount = sendRequestSuccessCount.get();
- s.sendRequestFailedCount = sendRequestFailedCount.get();
- s.sendMessageTimeTotal = sendMessageTimeTotal.get();
+ s.sendRequestSuccessCount = sendRequestSuccessCount.longValue();
+ s.sendRequestFailedCount = sendRequestFailedCount.longValue();
+ s.sendMessageTimeTotal = sendMessageTimeTotal.longValue();
s.sendMessageMaxRT = sendMessageMaxRT.get();
- s.checkCount = checkCount.get();
- s.unexpectedCheckCount = unexpectedCheckCount.get();
- s.duplicatedCheck = duplicatedCheckCount.get();
+ s.checkCount = checkCount.longValue();
+ s.unexpectedCheckCount = unexpectedCheckCount.longValue();
+ s.duplicatedCheck = duplicatedCheckCount.longValue();
return s;
}
- public AtomicLong getSendRequestSuccessCount() {
+ public LongAdder getSendRequestSuccessCount() {
return sendRequestSuccessCount;
}
- public AtomicLong getSendRequestFailedCount() {
+ public LongAdder getSendRequestFailedCount() {
return sendRequestFailedCount;
}
- public AtomicLong getSendMessageTimeTotal() {
+ public LongAdder getSendMessageTimeTotal() {
return sendMessageTimeTotal;
}
@@ -424,15 +431,15 @@ class StatsBenchmarkTProducer {
return sendMessageMaxRT;
}
- public AtomicLong getCheckCount() {
+ public LongAdder getCheckCount() {
return checkCount;
}
- public AtomicLong getUnexpectedCheckCount() {
+ public LongAdder getUnexpectedCheckCount() {
return unexpectedCheckCount;
}
- public AtomicLong getDuplicatedCheckCount() {
+ public LongAdder getDuplicatedCheckCount() {
return duplicatedCheckCount;
}
}
diff --git a/example/src/main/java/org/apache/rocketmq/example/simple/PullConsumer.java b/example/src/main/java/org/apache/rocketmq/example/simple/PullConsumer.java
index 8aec7e30934a8c07d9a36bb827a7f6dc66d364cf..4bc63383954ec3c44db62b9b6398bb5dfba41c89 100644
--- a/example/src/main/java/org/apache/rocketmq/example/simple/PullConsumer.java
+++ b/example/src/main/java/org/apache/rocketmq/example/simple/PullConsumer.java
@@ -16,63 +16,133 @@
*/
package org.apache.rocketmq.example.simple;
-import java.util.HashMap;
-import java.util.Map;
+import java.util.HashSet;
+import java.util.List;
import java.util.Set;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ThreadFactory;
+
import org.apache.rocketmq.client.consumer.DefaultMQPullConsumer;
import org.apache.rocketmq.client.consumer.PullResult;
+import org.apache.rocketmq.client.consumer.store.ReadOffsetType;
+import org.apache.rocketmq.client.exception.MQBrokerException;
import org.apache.rocketmq.client.exception.MQClientException;
+import org.apache.rocketmq.common.message.MessageExt;
import org.apache.rocketmq.common.message.MessageQueue;
+import org.apache.rocketmq.remoting.exception.RemotingException;
+@SuppressWarnings("deprecation")
public class PullConsumer {
- private static final Map OFFSE_TABLE = new HashMap();
public static void main(String[] args) throws MQClientException {
+
DefaultMQPullConsumer consumer = new DefaultMQPullConsumer("please_rename_unique_group_name_5");
consumer.setNamesrvAddr("127.0.0.1:9876");
+ Set topics = new HashSet<>();
+ //You would better to register topics,It will use in rebalance when starting
+ topics.add("TopicTest");
+ consumer.setRegisterTopics(topics);
consumer.start();
- Set mqs = consumer.fetchSubscribeMessageQueues("broker-a");
- for (MessageQueue mq : mqs) {
- System.out.printf("Consume from the queue: %s%n", mq);
- SINGLE_MQ:
- while (true) {
- try {
- PullResult pullResult =
- consumer.pullBlockIfNotFound(mq, null, getMessageQueueOffset(mq), 32);
- System.out.printf("%s%n", pullResult);
- putMessageQueueOffset(mq, pullResult.getNextBeginOffset());
- switch (pullResult.getPullStatus()) {
- case FOUND:
- break;
- case NO_MATCHED_MSG:
- break;
- case NO_NEW_MSG:
- break SINGLE_MQ;
- case OFFSET_ILLEGAL:
- break;
- default:
- break;
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
+ ExecutorService executors = Executors.newFixedThreadPool(topics.size(), new ThreadFactory() {
+ @Override
+ public Thread newThread(Runnable r) {
+ return new Thread(r, "PullConsumerThread");
}
- }
+ });
+ for (String topic : consumer.getRegisterTopics()) {
- consumer.shutdown();
- }
+ executors.execute(new Runnable() {
- private static long getMessageQueueOffset(MessageQueue mq) {
- Long offset = OFFSE_TABLE.get(mq);
- if (offset != null)
- return offset;
+ public void doSomething(List msgs) {
+ //do you business
- return 0;
- }
+ }
- private static void putMessageQueueOffset(MessageQueue mq, long offset) {
- OFFSE_TABLE.put(mq, offset);
- }
+ @Override
+ public void run() {
+ while (true) {
+ try {
+ Set messageQueues = consumer.fetchMessageQueuesInBalance(topic);
+ if (messageQueues == null || messageQueues.isEmpty()) {
+ Thread.sleep(1000);
+ continue;
+ }
+ PullResult pullResult = null;
+ for (MessageQueue messageQueue : messageQueues) {
+ try {
+ long offset = this.consumeFromOffset(messageQueue);
+ pullResult = consumer.pull(messageQueue, "*", offset, 32);
+ switch (pullResult.getPullStatus()) {
+ case FOUND:
+ List msgs = pullResult.getMsgFoundList();
+ if (msgs != null && !msgs.isEmpty()) {
+ this.doSomething(msgs);
+ //update offset to broker
+ consumer.updateConsumeOffset(messageQueue, pullResult.getNextBeginOffset());
+ //print pull tps
+ this.incPullTPS(topic, pullResult.getMsgFoundList().size());
+ }
+ break;
+ case OFFSET_ILLEGAL:
+ consumer.updateConsumeOffset(messageQueue, pullResult.getNextBeginOffset());
+ break;
+ case NO_NEW_MSG:
+ Thread.sleep(1);
+ consumer.updateConsumeOffset(messageQueue, pullResult.getNextBeginOffset());
+ break;
+ case NO_MATCHED_MSG:
+ consumer.updateConsumeOffset(messageQueue, pullResult.getNextBeginOffset());
+ break;
+ default:
+ }
+ } catch (RemotingException e) {
+ e.printStackTrace();
+ } catch (MQBrokerException e) {
+ e.printStackTrace();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ } catch (MQClientException e) {
+ //reblance error
+ e.printStackTrace();
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ public long consumeFromOffset(MessageQueue messageQueue) throws MQClientException {
+ //-1 when started
+ long offset = consumer.getOffsetStore().readOffset(messageQueue, ReadOffsetType.READ_FROM_MEMORY);
+ if (offset < 0) {
+ //query from broker
+ offset = consumer.getOffsetStore().readOffset(messageQueue, ReadOffsetType.READ_FROM_STORE);
+ }
+ if (offset < 0) {
+ //first time start from last offset
+ offset = consumer.maxOffset(messageQueue);
+ }
+ //make sure
+ if (offset < 0) {
+ offset = 0;
+ }
+ return offset;
+ }
+
+ public void incPullTPS(String topic, int pullSize) {
+ consumer.getDefaultMQPullConsumerImpl().getRebalanceImpl().getmQClientFactory()
+ .getConsumerStatsManager().incPullTPS(consumer.getConsumerGroup(), topic, pullSize);
+ }
+ });
+
+ }
+// executors.shutdown();
+// consumer.shutdown();
+ }
}
diff --git a/filter/pom.xml b/filter/pom.xml
index 2dd396e782f4d9ae8c8e62467904bda2d54b1d20..3f7ad3da99a5401c4a54ede3ad08ce19fe088f34 100644
--- a/filter/pom.xml
+++ b/filter/pom.xml
@@ -20,7 +20,7 @@
rocketmq-all
org.apache.rocketmq
- 4.9.2-SNAPSHOT
+ 4.9.3-SNAPSHOT
4.0.0
diff --git a/filter/src/main/java/org/apache/rocketmq/filter/expression/UnaryExpression.java b/filter/src/main/java/org/apache/rocketmq/filter/expression/UnaryExpression.java
index 24845fc058952bf5556372be7e0af8207016da13..7f18ddd54130b080b474b4a5977b25b9ba4715a0 100644
--- a/filter/src/main/java/org/apache/rocketmq/filter/expression/UnaryExpression.java
+++ b/filter/src/main/java/org/apache/rocketmq/filter/expression/UnaryExpression.java
@@ -53,6 +53,7 @@ public abstract class UnaryExpression implements Expression {
public static Expression createNegate(Expression left) {
return new UnaryExpression(left, UnaryType.NEGATE) {
+ @Override
public Object evaluate(EvaluationContext context) throws Exception {
Object rvalue = right.evaluate(context);
if (rvalue == null) {
@@ -64,6 +65,7 @@ public abstract class UnaryExpression implements Expression {
return null;
}
+ @Override
public String getExpressionSymbol() {
return "-";
}
@@ -85,6 +87,7 @@ public abstract class UnaryExpression implements Expression {
final Collection inList = t;
return new UnaryInExpression(right, UnaryType.IN, inList, not) {
+ @Override
public Object evaluate(EvaluationContext context) throws Exception {
Object rvalue = right.evaluate(context);
@@ -103,8 +106,9 @@ public abstract class UnaryExpression implements Expression {
}
+ @Override
public String toString() {
- StringBuffer answer = new StringBuffer();
+ StringBuilder answer = new StringBuilder();
answer.append(right);
answer.append(" ");
answer.append(getExpressionSymbol());
@@ -124,6 +128,7 @@ public abstract class UnaryExpression implements Expression {
return answer.toString();
}
+ @Override
public String getExpressionSymbol() {
if (not) {
return "NOT IN";
@@ -139,6 +144,7 @@ public abstract class UnaryExpression implements Expression {
super(left, unaryType);
}
+ @Override
public boolean matches(EvaluationContext context) throws Exception {
Object object = evaluate(context);
return object != null && object == Boolean.TRUE;
@@ -147,6 +153,7 @@ public abstract class UnaryExpression implements Expression {
public static BooleanExpression createNOT(BooleanExpression left) {
return new BooleanUnaryExpression(left, UnaryType.NOT) {
+ @Override
public Object evaluate(EvaluationContext context) throws Exception {
Boolean lvalue = (Boolean) right.evaluate(context);
if (lvalue == null) {
@@ -155,6 +162,7 @@ public abstract class UnaryExpression implements Expression {
return lvalue.booleanValue() ? Boolean.FALSE : Boolean.TRUE;
}
+ @Override
public String getExpressionSymbol() {
return "NOT";
}
@@ -163,6 +171,7 @@ public abstract class UnaryExpression implements Expression {
public static BooleanExpression createBooleanCast(Expression left) {
return new BooleanUnaryExpression(left, UnaryType.BOOLEANCAST) {
+ @Override
public Object evaluate(EvaluationContext context) throws Exception {
Object rvalue = right.evaluate(context);
if (rvalue == null) {
@@ -174,10 +183,12 @@ public abstract class UnaryExpression implements Expression {
return ((Boolean) rvalue).booleanValue() ? Boolean.TRUE : Boolean.FALSE;
}
+ @Override
public String toString() {
return right.toString();
}
+ @Override
public String getExpressionSymbol() {
return "";
}
@@ -233,6 +244,7 @@ public abstract class UnaryExpression implements Expression {
/**
* @see Object#toString()
*/
+ @Override
public String toString() {
return "(" + getExpressionSymbol() + " " + right.toString() + ")";
}
@@ -240,6 +252,7 @@ public abstract class UnaryExpression implements Expression {
/**
* @see Object#hashCode()
*/
+ @Override
public int hashCode() {
return toString().hashCode();
}
@@ -247,6 +260,7 @@ public abstract class UnaryExpression implements Expression {
/**
* @see Object#equals(Object)
*/
+ @Override
public boolean equals(Object o) {
if (o == null || !this.getClass().equals(o.getClass())) {
diff --git a/filter/src/main/java/org/apache/rocketmq/filter/parser/ParseException.java b/filter/src/main/java/org/apache/rocketmq/filter/parser/ParseException.java
index 06014cbcbed6e0a8d2e521c5ae05c575dcb991f5..0a327bea1c05bec62ba24ddfd4b191819b534217 100644
--- a/filter/src/main/java/org/apache/rocketmq/filter/parser/ParseException.java
+++ b/filter/src/main/java/org/apache/rocketmq/filter/parser/ParseException.java
@@ -106,7 +106,7 @@ public class ParseException extends Exception {
int[][] expectedTokenSequences,
String[] tokenImage) {
String eol = System.getProperty("line.separator", "\n");
- StringBuffer expected = new StringBuffer();
+ StringBuilder expected = new StringBuilder();
int maxSize = 0;
for (int i = 0; i < expectedTokenSequences.length; i++) {
if (maxSize < expectedTokenSequences[i].length) {
@@ -123,8 +123,9 @@ public class ParseException extends Exception {
String retval = "Encountered \"";
Token tok = currentToken.next;
for (int i = 0; i < maxSize; i++) {
- if (i != 0)
+ if (i != 0) {
retval += " ";
+ }
if (tok.kind == 0) {
retval += tokenImage[0];
break;
@@ -157,7 +158,7 @@ public class ParseException extends Exception {
* string literal.
*/
static String add_escapes(String str) {
- StringBuffer retval = new StringBuffer();
+ StringBuilder retval = new StringBuilder();
char ch;
for (int i = 0; i < str.length(); i++) {
switch (str.charAt(i)) {
diff --git a/filter/src/main/java/org/apache/rocketmq/filter/parser/TokenMgrError.java b/filter/src/main/java/org/apache/rocketmq/filter/parser/TokenMgrError.java
index e8132df5aac561730e62e9fe199f68e1ee7c0d53..0aeb27cf4caaf88f2460fc8f92303b19141883fd 100644
--- a/filter/src/main/java/org/apache/rocketmq/filter/parser/TokenMgrError.java
+++ b/filter/src/main/java/org/apache/rocketmq/filter/parser/TokenMgrError.java
@@ -66,7 +66,7 @@ public class TokenMgrError extends Error {
* equivalents in the given string
*/
protected static final String addEscapes(String str) {
- StringBuffer retval = new StringBuffer();
+ StringBuilder retval = new StringBuilder();
char ch;
for (int i = 0; i < str.length(); i++) {
switch (str.charAt(i)) {
@@ -141,6 +141,7 @@ public class TokenMgrError extends Error {
*
* from this method for such cases in the release version of your parser.
*/
+ @Override
public String getMessage() {
return super.getMessage();
}
diff --git a/filter/src/test/java/org/apache/rocketmq/filter/ParserTest.java b/filter/src/test/java/org/apache/rocketmq/filter/ParserTest.java
index 115632faa0a6741d4b112872d15b71800451f587..7dc2ab25468523e32c341f798378dc5368d11e63 100644
--- a/filter/src/test/java/org/apache/rocketmq/filter/ParserTest.java
+++ b/filter/src/test/java/org/apache/rocketmq/filter/ParserTest.java
@@ -84,7 +84,7 @@ public class ParserTest {
@Test
public void testParse_floatOverFlow() {
try {
- StringBuffer sb = new StringBuffer(210000);
+ StringBuilder sb = new StringBuilder(210000);
sb.append("1");
for (int i = 0; i < 2048; i ++) {
sb.append("111111111111111111111111111111111111111111111111111");
diff --git a/logappender/pom.xml b/logappender/pom.xml
index 2a1111a624edd9cba230fe900b9d7510b3d51d93..306edc7a1aeb05e716dc31190b0a2717b2ae8c3c 100644
--- a/logappender/pom.xml
+++ b/logappender/pom.xml
@@ -19,7 +19,7 @@
org.apache.rocketmq
rocketmq-all
- 4.9.2-SNAPSHOT
+ 4.9.3-SNAPSHOT
4.0.0
rocketmq-logappender
diff --git a/logging/pom.xml b/logging/pom.xml
index 88c8e24ee3215a67aaba6d655fe2cb38d1cdbddd..268e017351170d765244a67c6ed7eb37df8b4658 100644
--- a/logging/pom.xml
+++ b/logging/pom.xml
@@ -19,7 +19,7 @@
org.apache.rocketmq
rocketmq-all
- 4.9.2-SNAPSHOT
+ 4.9.3-SNAPSHOT
4.0.0
diff --git a/namesrv/pom.xml b/namesrv/pom.xml
index dade790f020d738f04b62ea1850aedbfb83d22f3..32ebda33f56f6d5484751abb0ac63ae372ec3b8f 100644
--- a/namesrv/pom.xml
+++ b/namesrv/pom.xml
@@ -19,7 +19,7 @@
org.apache.rocketmq
rocketmq-all
- 4.9.2-SNAPSHOT
+ 4.9.3-SNAPSHOT
4.0.0
diff --git a/namesrv/src/main/java/org/apache/rocketmq/namesrv/processor/DefaultRequestProcessor.java b/namesrv/src/main/java/org/apache/rocketmq/namesrv/processor/DefaultRequestProcessor.java
index f8bc55e7aab38e1f27abc75c674c28eab0a9d02b..98e96dfe7db5ca74fe42537415834e815b586c29 100644
--- a/namesrv/src/main/java/org/apache/rocketmq/namesrv/processor/DefaultRequestProcessor.java
+++ b/namesrv/src/main/java/org/apache/rocketmq/namesrv/processor/DefaultRequestProcessor.java
@@ -27,6 +27,8 @@ import org.apache.rocketmq.common.MixAll;
import org.apache.rocketmq.common.UtilAll;
import org.apache.rocketmq.common.constant.LoggerName;
import org.apache.rocketmq.common.help.FAQUrl;
+import org.apache.rocketmq.common.protocol.header.namesrv.AddWritePermOfBrokerRequestHeader;
+import org.apache.rocketmq.common.protocol.header.namesrv.AddWritePermOfBrokerResponseHeader;
import org.apache.rocketmq.logging.InternalLogger;
import org.apache.rocketmq.logging.InternalLoggerFactory;
import org.apache.rocketmq.common.namesrv.NamesrvUtil;
@@ -103,6 +105,8 @@ public class DefaultRequestProcessor extends AsyncNettyRequestProcessor implemen
return this.getBrokerClusterInfo(ctx, request);
case RequestCode.WIPE_WRITE_PERM_OF_BROKER:
return this.wipeWritePermOfBroker(ctx, request);
+ case RequestCode.ADD_WRITE_PERM_OF_BROKER:
+ return this.addWritePermOfBroker(ctx, request);
case RequestCode.GET_ALL_TOPIC_LIST_FROM_NAMESERVER:
return getAllTopicListFromNameserver(ctx, request);
case RequestCode.DELETE_TOPIC_IN_NAMESRV:
@@ -402,6 +406,24 @@ public class DefaultRequestProcessor extends AsyncNettyRequestProcessor implemen
return response;
}
+ private RemotingCommand addWritePermOfBroker(ChannelHandlerContext ctx, RemotingCommand request) throws RemotingCommandException {
+ final RemotingCommand response = RemotingCommand.createResponseCommand(AddWritePermOfBrokerResponseHeader.class);
+ final AddWritePermOfBrokerResponseHeader responseHeader = (AddWritePermOfBrokerResponseHeader) response.readCustomHeader();
+ final AddWritePermOfBrokerRequestHeader requestHeader = (AddWritePermOfBrokerRequestHeader) request.decodeCommandCustomHeader(AddWritePermOfBrokerRequestHeader.class);
+
+ int addTopicCnt = this.namesrvController.getRouteInfoManager().addWritePermOfBrokerByLock(requestHeader.getBrokerName());
+
+ log.info("add write perm of broker[{}], client: {}, {}",
+ requestHeader.getBrokerName(),
+ RemotingHelper.parseChannelRemoteAddr(ctx.channel()),
+ addTopicCnt);
+
+ responseHeader.setAddTopicCount(addTopicCnt);
+ response.setCode(ResponseCode.SUCCESS);
+ response.setRemark(null);
+ return response;
+ }
+
private RemotingCommand getAllTopicListFromNameserver(ChannelHandlerContext ctx, RemotingCommand request) {
final RemotingCommand response = RemotingCommand.createResponseCommand(null);
diff --git a/namesrv/src/main/java/org/apache/rocketmq/namesrv/routeinfo/RouteInfoManager.java b/namesrv/src/main/java/org/apache/rocketmq/namesrv/routeinfo/RouteInfoManager.java
index edef87ce2d7e5d18f00610ad2619a55357d7a5d5..982d5439469d6da1f418d18996cace47543f51f2 100644
--- a/namesrv/src/main/java/org/apache/rocketmq/namesrv/routeinfo/RouteInfoManager.java
+++ b/namesrv/src/main/java/org/apache/rocketmq/namesrv/routeinfo/RouteInfoManager.java
@@ -33,6 +33,7 @@ import org.apache.rocketmq.common.MixAll;
import org.apache.rocketmq.common.TopicConfig;
import org.apache.rocketmq.common.constant.LoggerName;
import org.apache.rocketmq.common.constant.PermName;
+import org.apache.rocketmq.common.protocol.RequestCode;
import org.apache.rocketmq.logging.InternalLogger;
import org.apache.rocketmq.logging.InternalLoggerFactory;
import org.apache.rocketmq.common.namesrv.RegisterBrokerResult;
@@ -252,40 +253,52 @@ public class RouteInfoManager {
}
public int wipeWritePermOfBrokerByLock(final String brokerName) {
+ return operateWritePermOfBrokerByLock(brokerName, RequestCode.WIPE_WRITE_PERM_OF_BROKER);
+ }
+
+ public int addWritePermOfBrokerByLock(final String brokerName) {
+ return operateWritePermOfBrokerByLock(brokerName, RequestCode.ADD_WRITE_PERM_OF_BROKER);
+ }
+
+ private int operateWritePermOfBrokerByLock(final String brokerName, final int requestCode) {
try {
try {
this.lock.writeLock().lockInterruptibly();
- return wipeWritePermOfBroker(brokerName);
+ return operateWritePermOfBroker(brokerName, requestCode);
} finally {
this.lock.writeLock().unlock();
}
} catch (Exception e) {
- log.error("wipeWritePermOfBrokerByLock Exception", e);
+ log.error("operateWritePermOfBrokerByLock Exception", e);
}
return 0;
}
- private int wipeWritePermOfBroker(final String brokerName) {
- int wipeTopicCnt = 0;
- Iterator>> itTopic = this.topicQueueTable.entrySet().iterator();
- while (itTopic.hasNext()) {
- Entry> entry = itTopic.next();
+
+ private int operateWritePermOfBroker(final String brokerName, final int requestCode) {
+ int topicCnt = 0;
+ for (Entry> entry : this.topicQueueTable.entrySet()) {
List qdList = entry.getValue();
- Iterator it = qdList.iterator();
- while (it.hasNext()) {
- QueueData qd = it.next();
+ for (QueueData qd : qdList) {
if (qd.getBrokerName().equals(brokerName)) {
int perm = qd.getPerm();
- perm &= ~PermName.PERM_WRITE;
+ switch (requestCode) {
+ case RequestCode.WIPE_WRITE_PERM_OF_BROKER:
+ perm &= ~PermName.PERM_WRITE;
+ break;
+ case RequestCode.ADD_WRITE_PERM_OF_BROKER:
+ perm = PermName.PERM_READ | PermName.PERM_WRITE;
+ break;
+ }
qd.setPerm(perm);
- wipeTopicCnt++;
+ topicCnt++;
}
}
}
- return wipeTopicCnt;
+ return topicCnt;
}
public void unregisterBroker(
diff --git a/namesrv/src/test/java/org/apache/rocketmq/namesrv/routeinfo/RouteInfoManagerTest.java b/namesrv/src/test/java/org/apache/rocketmq/namesrv/routeinfo/RouteInfoManagerTest.java
index 5ab77be1ebe115cf60c4290b5fc44a8e28aec01c..e0d9e1871c04aabc25cd626edebdeb2b08b8d315 100644
--- a/namesrv/src/test/java/org/apache/rocketmq/namesrv/routeinfo/RouteInfoManagerTest.java
+++ b/namesrv/src/test/java/org/apache/rocketmq/namesrv/routeinfo/RouteInfoManagerTest.java
@@ -17,17 +17,23 @@
package org.apache.rocketmq.namesrv.routeinfo;
import io.netty.channel.Channel;
-import java.util.ArrayList;
-import java.util.concurrent.ConcurrentHashMap;
import org.apache.rocketmq.common.TopicConfig;
+import org.apache.rocketmq.common.constant.PermName;
import org.apache.rocketmq.common.namesrv.RegisterBrokerResult;
import org.apache.rocketmq.common.protocol.body.TopicConfigSerializeWrapper;
+import org.apache.rocketmq.common.protocol.route.QueueData;
import org.apache.rocketmq.common.protocol.route.TopicRouteData;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.concurrent.ConcurrentHashMap;
+
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
@@ -74,14 +80,28 @@ public class RouteInfoManagerTest {
topicConfigSerializeWrapper.setTopicConfigTable(topicConfigConcurrentHashMap);
Channel channel = mock(Channel.class);
RegisterBrokerResult registerBrokerResult = routeInfoManager.registerBroker("default-cluster", "127.0.0.1:10911", "default-broker", 1234, "127.0.0.1:1001",
- topicConfigSerializeWrapper, new ArrayList(), channel);
+ topicConfigSerializeWrapper, new ArrayList(), channel);
assertThat(registerBrokerResult).isNotNull();
}
@Test
- public void testWipeWritePermOfBrokerByLock() {
- int result = routeInfoManager.wipeWritePermOfBrokerByLock("default-broker");
- assertThat(result).isEqualTo(0);
+ public void testWipeWritePermOfBrokerByLock() throws Exception {
+ List qdList = new ArrayList<>();
+ QueueData qd = new QueueData();
+ qd.setPerm(PermName.PERM_READ | PermName.PERM_WRITE);
+ qd.setBrokerName("broker-a");
+ qdList.add(qd);
+ HashMap> topicQueueTable = new HashMap<>();
+ topicQueueTable.put("topic-a", qdList);
+
+ Field filed = RouteInfoManager.class.getDeclaredField("topicQueueTable");
+ filed.setAccessible(true);
+ filed.set(routeInfoManager, topicQueueTable);
+
+ int addTopicCnt = routeInfoManager.wipeWritePermOfBrokerByLock("broker-a");
+ assertThat(addTopicCnt).isEqualTo(1);
+ assertThat(qd.getPerm()).isEqualTo(PermName.PERM_READ);
+
}
@Test
@@ -119,4 +139,24 @@ public class RouteInfoManagerTest {
byte[] topicList = routeInfoManager.getHasUnitSubUnUnitTopicList();
assertThat(topicList).isNotNull();
}
+
+ @Test
+ public void testAddWritePermOfBrokerByLock() throws Exception {
+ List qdList = new ArrayList<>();
+ QueueData qd = new QueueData();
+ qd.setPerm(PermName.PERM_READ);
+ qd.setBrokerName("broker-a");
+ qdList.add(qd);
+ HashMap> topicQueueTable = new HashMap<>();
+ topicQueueTable.put("topic-a", qdList);
+
+ Field filed = RouteInfoManager.class.getDeclaredField("topicQueueTable");
+ filed.setAccessible(true);
+ filed.set(routeInfoManager, topicQueueTable);
+
+ int addTopicCnt = routeInfoManager.addWritePermOfBrokerByLock("broker-a");
+ assertThat(addTopicCnt).isEqualTo(1);
+ assertThat(qd.getPerm()).isEqualTo(PermName.PERM_READ | PermName.PERM_WRITE);
+
+ }
}
\ No newline at end of file
diff --git a/openmessaging/pom.xml b/openmessaging/pom.xml
index dfa0780c05f3ef9be1a0935adddeaba0a8d6dedb..0882c7f5c49539f22cec03e61a7656d627f6e554 100644
--- a/openmessaging/pom.xml
+++ b/openmessaging/pom.xml
@@ -20,7 +20,7 @@
rocketmq-all
org.apache.rocketmq
- 4.9.2-SNAPSHOT
+ 4.9.3-SNAPSHOT
4.0.0
diff --git a/pom.xml b/pom.xml
index af0db5c52cd110b3cf353a15e76adf8d0cda056d..e17a5899164b389d36fd71af980f0e87ec3a943a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -29,7 +29,7 @@
2012
org.apache.rocketmq
rocketmq-all
- 4.9.2-SNAPSHOT
+ 4.9.3-SNAPSHOT
pom
Apache RocketMQ ${project.version}
http://rocketmq.apache.org/
diff --git a/remoting/pom.xml b/remoting/pom.xml
index a019a4d624175fd8434e8fd6e672d06dac5b8b87..a0e00ec0a4ae57280c1a757dce817bd2c071145b 100644
--- a/remoting/pom.xml
+++ b/remoting/pom.xml
@@ -19,7 +19,7 @@
org.apache.rocketmq
rocketmq-all
- 4.9.2-SNAPSHOT
+ 4.9.3-SNAPSHOT
4.0.0
diff --git a/remoting/src/main/java/org/apache/rocketmq/remoting/common/RemotingHelper.java b/remoting/src/main/java/org/apache/rocketmq/remoting/common/RemotingHelper.java
index f244bf4c853551ad8b4810f95a78b039ae6d239b..7dacea9c132360d6c54bd6b77c3b2da26b43b911 100644
--- a/remoting/src/main/java/org/apache/rocketmq/remoting/common/RemotingHelper.java
+++ b/remoting/src/main/java/org/apache/rocketmq/remoting/common/RemotingHelper.java
@@ -36,7 +36,7 @@ public class RemotingHelper {
private static final InternalLogger log = InternalLoggerFactory.getLogger(ROCKETMQ_REMOTING);
public static String exceptionSimpleDesc(final Throwable e) {
- StringBuffer sb = new StringBuffer();
+ StringBuilder sb = new StringBuilder();
if (e != null) {
sb.append(e.toString());
diff --git a/remoting/src/main/java/org/apache/rocketmq/remoting/common/RemotingUtil.java b/remoting/src/main/java/org/apache/rocketmq/remoting/common/RemotingUtil.java
index d936c3bf696ab0399a323ea028e9ee12ee46ce5a..3914314f0e2ad4768da0d3e8a9caf5e2de442e9b 100644
--- a/remoting/src/main/java/org/apache/rocketmq/remoting/common/RemotingUtil.java
+++ b/remoting/src/main/java/org/apache/rocketmq/remoting/common/RemotingUtil.java
@@ -165,6 +165,10 @@ public class RemotingUtil {
return sb.toString();
}
+ public static String convert2IpString(final String addr) {
+ return socketAddress2String(string2SocketAddress(addr));
+ }
+
private static boolean isBridge(NetworkInterface networkInterface) {
try {
if (isLinuxPlatform()) {
diff --git a/remoting/src/main/java/org/apache/rocketmq/remoting/netty/NettyRemotingAbstract.java b/remoting/src/main/java/org/apache/rocketmq/remoting/netty/NettyRemotingAbstract.java
index c9b39946c07f64d8322c2617fc7431bbb1f9d828..b2e7294bf32e6489e1dfced51dbbdeeb066a717a 100644
--- a/remoting/src/main/java/org/apache/rocketmq/remoting/netty/NettyRemotingAbstract.java
+++ b/remoting/src/main/java/org/apache/rocketmq/remoting/netty/NettyRemotingAbstract.java
@@ -199,11 +199,12 @@ public abstract class NettyRemotingAbstract {
@Override
public void run() {
try {
- doBeforeRpcHooks(RemotingHelper.parseChannelRemoteAddr(ctx.channel()), cmd);
+ String remoteAddr = RemotingHelper.parseChannelRemoteAddr(ctx.channel());
+ doBeforeRpcHooks(remoteAddr, cmd);
final RemotingResponseCallback callback = new RemotingResponseCallback() {
@Override
public void callback(RemotingCommand response) {
- doAfterRpcHooks(RemotingHelper.parseChannelRemoteAddr(ctx.channel()), cmd, response);
+ doAfterRpcHooks(remoteAddr, cmd, response);
if (!cmd.isOnewayRPC()) {
if (response != null) {
response.setOpaque(opaque);
diff --git a/srvutil/pom.xml b/srvutil/pom.xml
index 5ba70577bbfa0cb8a677834c7bd3cef310e9ca0d..e9e755b070024ce9488fa69ab38ba37af12cdbab 100644
--- a/srvutil/pom.xml
+++ b/srvutil/pom.xml
@@ -19,7 +19,7 @@
org.apache.rocketmq
rocketmq-all
- 4.9.2-SNAPSHOT
+ 4.9.3-SNAPSHOT
4.0.0
diff --git a/store/pom.xml b/store/pom.xml
index 09f3dba9f338eec1a1a206578d82ef39e648fcba..a37c986f7c60bfa119a828be0e1d2485ea305867 100644
--- a/store/pom.xml
+++ b/store/pom.xml
@@ -19,7 +19,7 @@
org.apache.rocketmq
rocketmq-all
- 4.9.2-SNAPSHOT
+ 4.9.3-SNAPSHOT
4.0.0
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 5e92654aceae912bc9a013f876a7400d0119bae9..3a89dc849954c49c0b5071d8985c5fa4fc7a7291 100644
--- a/store/src/main/java/org/apache/rocketmq/store/CommitLog.java
+++ b/store/src/main/java/org/apache/rocketmq/store/CommitLog.java
@@ -22,10 +22,12 @@ import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.nio.ByteBuffer;
+import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.function.Supplier;
@@ -43,6 +45,7 @@ import org.apache.rocketmq.logging.InternalLogger;
import org.apache.rocketmq.logging.InternalLoggerFactory;
import org.apache.rocketmq.store.config.BrokerRole;
import org.apache.rocketmq.store.config.FlushDiskType;
+import org.apache.rocketmq.store.config.MessageStoreConfig;
import org.apache.rocketmq.store.ha.HAService;
import org.apache.rocketmq.store.schedule.ScheduleMessageService;
@@ -71,9 +74,20 @@ public class CommitLog {
protected final PutMessageLock putMessageLock;
+ private volatile Set fullStorePaths = Collections.emptySet();
+
public CommitLog(final DefaultMessageStore defaultMessageStore) {
- this.mappedFileQueue = new MappedFileQueue(defaultMessageStore.getMessageStoreConfig().getStorePathCommitLog(),
- defaultMessageStore.getMessageStoreConfig().getMappedFileSizeCommitLog(), defaultMessageStore.getAllocateMappedFileService());
+ String storePath = defaultMessageStore.getMessageStoreConfig().getStorePathCommitLog();
+ if (storePath.contains(MessageStoreConfig.MULTI_PATH_SPLITTER)) {
+ this.mappedFileQueue = new MultiPathMappedFileQueue(defaultMessageStore.getMessageStoreConfig(),
+ defaultMessageStore.getMessageStoreConfig().getMappedFileSizeCommitLog(),
+ defaultMessageStore.getAllocateMappedFileService(), this::getFullStorePaths);
+ } else {
+ this.mappedFileQueue = new MappedFileQueue(storePath,
+ defaultMessageStore.getMessageStoreConfig().getMappedFileSizeCommitLog(),
+ defaultMessageStore.getAllocateMappedFileService());
+ }
+
this.defaultMessageStore = defaultMessageStore;
if (FlushDiskType.SYNC_FLUSH == defaultMessageStore.getMessageStoreConfig().getFlushDiskType()) {
@@ -95,6 +109,14 @@ public class CommitLog {
}
+ public void setFullStorePaths(Set fullStorePaths) {
+ this.fullStorePaths = fullStorePaths;
+ }
+
+ public Set getFullStorePaths() {
+ return fullStorePaths;
+ }
+
public boolean load() {
boolean result = this.mappedFileQueue.load();
log.info("load commit log " + (result ? "OK" : "Failed"));
@@ -685,8 +707,8 @@ public class CommitLog {
PutMessageResult putMessageResult = new PutMessageResult(PutMessageStatus.PUT_OK, result);
// Statistics
- storeStatsService.getSinglePutMessageTopicTimesTotal(msg.getTopic()).incrementAndGet();
- storeStatsService.getSinglePutMessageTopicSizeTotal(topic).addAndGet(result.getWroteBytes());
+ storeStatsService.getSinglePutMessageTopicTimesTotal(msg.getTopic()).add(1);
+ storeStatsService.getSinglePutMessageTopicSizeTotal(topic).add(result.getWroteBytes());
CompletableFuture flushResultFuture = submitFlushRequest(result, msg);
CompletableFuture replicaResultFuture = submitReplicaRequest(result, msg);
@@ -802,8 +824,8 @@ public class CommitLog {
PutMessageResult putMessageResult = new PutMessageResult(PutMessageStatus.PUT_OK, result);
// Statistics
- storeStatsService.getSinglePutMessageTopicTimesTotal(messageExtBatch.getTopic()).addAndGet(result.getMsgNum());
- storeStatsService.getSinglePutMessageTopicSizeTotal(messageExtBatch.getTopic()).addAndGet(result.getWroteBytes());
+ storeStatsService.getSinglePutMessageTopicTimesTotal(messageExtBatch.getTopic()).add(result.getMsgNum());
+ storeStatsService.getSinglePutMessageTopicSizeTotal(messageExtBatch.getTopic()).add(result.getWroteBytes());
CompletableFuture flushOKFuture = submitFlushRequest(result, messageExtBatch);
CompletableFuture replicaOKFuture = submitReplicaRequest(result, messageExtBatch);
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 69019c15490f0ad0b2ea6aa5a749899ef524ea70..09e153494df51627910f9cf46cbc6f7fbaf99197 100644
--- a/store/src/main/java/org/apache/rocketmq/store/DefaultMessageStore.java
+++ b/store/src/main/java/org/apache/rocketmq/store/DefaultMessageStore.java
@@ -26,6 +26,7 @@ import java.nio.ByteBuffer;
import java.nio.channels.FileLock;
import java.util.Collections;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Map;
@@ -163,6 +164,8 @@ public class DefaultMessageStore implements MessageStore {
File file = new File(StorePathConfigHelper.getLockFile(messageStoreConfig.getStorePathRootDir()));
MappedFile.ensureDirOK(file.getParent());
+ MappedFile.ensureDirOK(getStorePathPhysic());
+ MappedFile.ensureDirOK(getStorePathLogic());
lockFile = new RandomAccessFile(file, "rw");
}
@@ -186,10 +189,6 @@ public class DefaultMessageStore implements MessageStore {
boolean lastExitOK = !this.isTempFileExist();
log.info("last shutdown {}", lastExitOK ? "normally" : "abnormally");
- if (null != scheduleMessageService) {
- result = result && this.scheduleMessageService.load();
- }
-
// load Commit Log
result = result && this.commitLog.load();
@@ -205,7 +204,12 @@ public class DefaultMessageStore implements MessageStore {
this.recover(lastExitOK);
log.info("load over, and the max phy offset = {}", this.getMaxPhyOffset());
+
+ if (null != scheduleMessageService) {
+ result = this.scheduleMessageService.load();
+ }
}
+
} catch (Exception e) {
log.error("load exception", e);
result = false;
@@ -438,7 +442,7 @@ public class DefaultMessageStore implements MessageStore {
this.storeStatsService.setPutMessageEntireTimeMax(elapsedTime);
if (null == result || !result.isOk()) {
- this.storeStatsService.getPutMessageFailedTimes().incrementAndGet();
+ this.storeStatsService.getPutMessageFailedTimes().add(1);
}
});
@@ -468,7 +472,7 @@ public class DefaultMessageStore implements MessageStore {
this.storeStatsService.setPutMessageEntireTimeMax(elapsedTime);
if (null == result || !result.isOk()) {
- this.storeStatsService.getPutMessageFailedTimes().incrementAndGet();
+ this.storeStatsService.getPutMessageFailedTimes().add(1);
}
});
@@ -535,7 +539,8 @@ public class DefaultMessageStore implements MessageStore {
long minOffset = 0;
long maxOffset = 0;
- GetMessageResult getResult = new GetMessageResult();
+ // lazy init when find msg.
+ GetMessageResult getResult = null;
final long maxOffsetPy = this.commitLog.getMaxOffset();
@@ -572,6 +577,9 @@ public class DefaultMessageStore implements MessageStore {
int i = 0;
final int maxFilterMessageCount = Math.max(16000, maxMsgNums * ConsumeQueue.CQ_STORE_UNIT_SIZE);
final boolean diskFallRecorded = this.messageStoreConfig.isDiskFallRecorded();
+
+ getResult = new GetMessageResult(maxMsgNums);
+
ConsumeQueueExt.CqExtUnit cqExtUnit = new ConsumeQueueExt.CqExtUnit();
for (; i < bufferConsumeQueue.getSize() && i < maxFilterMessageCount; i += ConsumeQueue.CQ_STORE_UNIT_SIZE) {
long offsetPy = bufferConsumeQueue.getByteBuffer().getLong();
@@ -634,7 +642,7 @@ public class DefaultMessageStore implements MessageStore {
continue;
}
- this.storeStatsService.getGetMessageTransferedMsgCount().incrementAndGet();
+ this.storeStatsService.getGetMessageTransferedMsgCount().add(1);
getResult.addMessage(selectResult);
status = GetMessageStatus.FOUND;
nextPhyFileStartOffset = Long.MIN_VALUE;
@@ -668,13 +676,18 @@ public class DefaultMessageStore implements MessageStore {
}
if (GetMessageStatus.FOUND == status) {
- this.storeStatsService.getGetMessageTimesTotalFound().incrementAndGet();
+ this.storeStatsService.getGetMessageTimesTotalFound().add(1);
} else {
- this.storeStatsService.getGetMessageTimesTotalMiss().incrementAndGet();
+ this.storeStatsService.getGetMessageTimesTotalMiss().add(1);
}
long elapsedTime = this.getSystemClock().now() - beginTime;
this.storeStatsService.setGetMessageEntireTimeMax(elapsedTime);
+ // lazy init no data found.
+ if (getResult == null) {
+ getResult = new GetMessageResult(0);
+ }
+
getResult.setStatus(status);
getResult.setNextBeginOffset(nextBeginOffset);
getResult.setMaxOffset(maxOffset);
@@ -768,8 +781,8 @@ public class DefaultMessageStore implements MessageStore {
return this.storeStatsService.toString();
}
- private String getStorePathPhysic() {
- String storePathPhysic = "";
+ public String getStorePathPhysic() {
+ String storePathPhysic;
if (DefaultMessageStore.this.getMessageStoreConfig().isEnableDLegerCommitLog()) {
storePathPhysic = ((DLedgerCommitLog)DefaultMessageStore.this.getCommitLog()).getdLedgerServer().getdLedgerConfig().getDataStorePath();
} else {
@@ -778,20 +791,29 @@ public class DefaultMessageStore implements MessageStore {
return storePathPhysic;
}
+ public String getStorePathLogic() {
+ return StorePathConfigHelper.getStorePathConsumeQueue(this.messageStoreConfig.getStorePathRootDir());
+ }
+
@Override
public HashMap getRuntimeInfo() {
HashMap result = this.storeStatsService.getRuntimeInfo();
{
- double physicRatio = UtilAll.getDiskPartitionSpaceUsedPercent(getStorePathPhysic());
- result.put(RunningStats.commitLogDiskRatio.name(), String.valueOf(physicRatio));
-
+ double minPhysicsUsedRatio = Double.MAX_VALUE;
+ String commitLogStorePath = getStorePathPhysic();
+ String[] paths = commitLogStorePath.trim().split(MessageStoreConfig.MULTI_PATH_SPLITTER);
+ for (String clPath : paths) {
+ double physicRatio = UtilAll.isPathExists(clPath) ?
+ UtilAll.getDiskPartitionSpaceUsedPercent(clPath) : -1;
+ result.put(RunningStats.commitLogDiskRatio.name() + "_" + clPath, String.valueOf(physicRatio));
+ minPhysicsUsedRatio = Math.min(minPhysicsUsedRatio, physicRatio);
+ }
+ result.put(RunningStats.commitLogDiskRatio.name(), String.valueOf(minPhysicsUsedRatio));
}
{
-
- String storePathLogics = StorePathConfigHelper.getStorePathConsumeQueue(this.messageStoreConfig.getStorePathRootDir());
- double logicsRatio = UtilAll.getDiskPartitionSpaceUsedPercent(storePathLogics);
+ double logicsRatio = UtilAll.getDiskPartitionSpaceUsedPercent(getStorePathLogic());
result.put(RunningStats.consumeQueueDiskRatio.name(), String.valueOf(logicsRatio));
}
@@ -1650,25 +1672,43 @@ public class DefaultMessageStore implements MessageStore {
cleanImmediately = false;
{
- double physicRatio = UtilAll.getDiskPartitionSpaceUsedPercent(getStorePathPhysic());
- if (physicRatio > diskSpaceWarningLevelRatio) {
+ String commitLogStorePath = DefaultMessageStore.this.getMessageStoreConfig().getStorePathCommitLog();
+ String[] storePaths = commitLogStorePath.trim().split(MessageStoreConfig.MULTI_PATH_SPLITTER);
+ Set fullStorePath = new HashSet<>();
+ double minPhysicRatio = 100;
+ String minStorePath = null;
+ for (String storePathPhysic : storePaths) {
+ double physicRatio = UtilAll.getDiskPartitionSpaceUsedPercent(storePathPhysic);
+ if (minPhysicRatio > physicRatio) {
+ minPhysicRatio = physicRatio;
+ minStorePath = storePathPhysic;
+ }
+ if (physicRatio > diskSpaceCleanForciblyRatio) {
+ fullStorePath.add(storePathPhysic);
+ }
+ }
+ DefaultMessageStore.this.commitLog.setFullStorePaths(fullStorePath);
+ if (minPhysicRatio > diskSpaceWarningLevelRatio) {
boolean diskok = DefaultMessageStore.this.runningFlags.getAndMakeDiskFull();
if (diskok) {
- DefaultMessageStore.log.error("physic disk maybe full soon " + physicRatio + ", so mark disk full");
+ DefaultMessageStore.log.error("physic disk maybe full soon " + minPhysicRatio +
+ ", so mark disk full, storePathPhysic=" + minStorePath);
}
cleanImmediately = true;
- } else if (physicRatio > diskSpaceCleanForciblyRatio) {
+ } else if (minPhysicRatio > diskSpaceCleanForciblyRatio) {
cleanImmediately = true;
} else {
boolean diskok = DefaultMessageStore.this.runningFlags.getAndMakeDiskOK();
if (!diskok) {
- DefaultMessageStore.log.info("physic disk space OK " + physicRatio + ", so mark disk ok");
+ DefaultMessageStore.log.info("physic disk space OK " + minPhysicRatio +
+ ", so mark disk ok, storePathPhysic=" + minStorePath);
}
}
- if (physicRatio < 0 || physicRatio > ratio) {
- DefaultMessageStore.log.info("physic disk maybe full soon, so reclaim space, " + physicRatio);
+ if (minPhysicRatio < 0 || minPhysicRatio > ratio) {
+ DefaultMessageStore.log.info("physic disk maybe full soon, so reclaim space, "
+ + minPhysicRatio + ", storePathPhysic=" + minStorePath);
return true;
}
}
@@ -1709,8 +1749,27 @@ public class DefaultMessageStore implements MessageStore {
public void setManualDeleteFileSeveralTimes(int manualDeleteFileSeveralTimes) {
this.manualDeleteFileSeveralTimes = manualDeleteFileSeveralTimes;
}
+
+ public double calcStorePathPhysicRatio() {
+ Set fullStorePath = new HashSet<>();
+ String storePath = getStorePathPhysic();
+ String[] paths = storePath.trim().split(MessageStoreConfig.MULTI_PATH_SPLITTER);
+ double minPhysicRatio = 100;
+ for (String path : paths) {
+ double physicRatio = UtilAll.isPathExists(path) ?
+ UtilAll.getDiskPartitionSpaceUsedPercent(path) : -1;
+ minPhysicRatio = Math.min(minPhysicRatio, physicRatio);
+ if (physicRatio > diskSpaceCleanForciblyRatio) {
+ fullStorePath.add(path);
+ }
+ }
+ DefaultMessageStore.this.commitLog.setFullStorePaths(fullStorePath);
+ return minPhysicRatio;
+
+ }
+
public boolean isSpaceFull() {
- double physicRatio = UtilAll.getDiskPartitionSpaceUsedPercent(getStorePathPhysic());
+ double physicRatio = calcStorePathPhysicRatio();
double ratio = DefaultMessageStore.this.getMessageStoreConfig().getDiskMaxUsedSpaceRatio() / 100.0;
if (physicRatio > ratio) {
DefaultMessageStore.log.info("physic disk of commitLog used: " + physicRatio);
@@ -1922,10 +1981,10 @@ public class DefaultMessageStore implements MessageStore {
readSize += size;
if (DefaultMessageStore.this.getMessageStoreConfig().getBrokerRole() == BrokerRole.SLAVE) {
DefaultMessageStore.this.storeStatsService
- .getSinglePutMessageTopicTimesTotal(dispatchRequest.getTopic()).incrementAndGet();
+ .getSinglePutMessageTopicTimesTotal(dispatchRequest.getTopic()).add(1);
DefaultMessageStore.this.storeStatsService
.getSinglePutMessageTopicSizeTotal(dispatchRequest.getTopic())
- .addAndGet(dispatchRequest.getMsgSize());
+ .add(dispatchRequest.getMsgSize());
}
} else if (size == 0) {
this.reputFromOffset = DefaultMessageStore.this.commitLog.rollNextFile(this.reputFromOffset);
diff --git a/store/src/main/java/org/apache/rocketmq/store/GetMessageResult.java b/store/src/main/java/org/apache/rocketmq/store/GetMessageResult.java
index 996e24d8058cf9b88ec18c2c456e4af11e755fcd..4e6eccbfbf0b8bd2d7694e94f10db62fd109688a 100644
--- a/store/src/main/java/org/apache/rocketmq/store/GetMessageResult.java
+++ b/store/src/main/java/org/apache/rocketmq/store/GetMessageResult.java
@@ -23,10 +23,8 @@ import org.apache.rocketmq.store.stats.BrokerStatsManager;
public class GetMessageResult {
- private final List messageMapedList =
- new ArrayList(100);
-
- private final List messageBufferList = new ArrayList(100);
+ private final List messageMapedList;
+ private final List messageBufferList;
private GetMessageStatus status;
private long nextBeginOffset;
@@ -40,6 +38,13 @@ public class GetMessageResult {
private int msgCount4Commercial = 0;
public GetMessageResult() {
+ messageMapedList = new ArrayList<>(100);
+ messageBufferList = new ArrayList<>(100);
+ }
+
+ public GetMessageResult(int resultSize) {
+ messageMapedList = new ArrayList<>(resultSize);
+ messageBufferList = new ArrayList<>(resultSize);
}
public GetMessageStatus getStatus() {
diff --git a/store/src/main/java/org/apache/rocketmq/store/MappedFileQueue.java b/store/src/main/java/org/apache/rocketmq/store/MappedFileQueue.java
index cc145921cef90239ca13dc5ff9b3714e2f4a27c2..1f25e61225aa5efcd1c377ebefe36b2b821ac83c 100644
--- a/store/src/main/java/org/apache/rocketmq/store/MappedFileQueue.java
+++ b/store/src/main/java/org/apache/rocketmq/store/MappedFileQueue.java
@@ -20,6 +20,7 @@ import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
@@ -37,13 +38,13 @@ public class MappedFileQueue {
private final String storePath;
- private final int mappedFileSize;
+ protected final int mappedFileSize;
- private final CopyOnWriteArrayList mappedFiles = new CopyOnWriteArrayList();
+ protected final CopyOnWriteArrayList mappedFiles = new CopyOnWriteArrayList();
private final AllocateMappedFileService allocateMappedFileService;
- private long flushedWhere = 0;
+ protected long flushedWhere = 0;
private long committedWhere = 0;
private volatile long storeTimestamp = 0;
@@ -144,35 +145,40 @@ public class MappedFileQueue {
}
}
+
public boolean load() {
File dir = new File(this.storePath);
- File[] files = dir.listFiles();
- if (files != null) {
- // ascending order
- Arrays.sort(files);
- for (File file : files) {
-
- if (file.length() != this.mappedFileSize) {
- log.warn(file + "\t" + file.length()
- + " length not matched message store config value, please check it manually");
- return false;
- }
+ File[] ls = dir.listFiles();
+ if (ls != null) {
+ return doLoad(Arrays.asList(ls));
+ }
+ return true;
+ }
- try {
- MappedFile mappedFile = new MappedFile(file.getPath(), mappedFileSize);
-
- mappedFile.setWrotePosition(this.mappedFileSize);
- mappedFile.setFlushedPosition(this.mappedFileSize);
- mappedFile.setCommittedPosition(this.mappedFileSize);
- this.mappedFiles.add(mappedFile);
- log.info("load " + file.getPath() + " OK");
- } catch (IOException e) {
- log.error("load file " + file + " error", e);
- return false;
- }
+ public boolean doLoad(List files) {
+ // ascending order
+ files.sort(Comparator.comparing(File::getName));
+
+ for (File file : files) {
+ if (file.length() != this.mappedFileSize) {
+ log.warn(file + "\t" + file.length()
+ + " length not matched message store config value, ignore it");
+ return true;
}
- }
+ try {
+ MappedFile mappedFile = new MappedFile(file.getPath(), mappedFileSize);
+
+ mappedFile.setWrotePosition(this.mappedFileSize);
+ mappedFile.setFlushedPosition(this.mappedFileSize);
+ mappedFile.setCommittedPosition(this.mappedFileSize);
+ this.mappedFiles.add(mappedFile);
+ log.info("load " + file.getPath() + " OK");
+ } catch (IOException e) {
+ log.error("load file " + file + " error", e);
+ return false;
+ }
+ }
return true;
}
@@ -204,33 +210,41 @@ public class MappedFileQueue {
}
if (createOffset != -1 && needCreate) {
- String nextFilePath = this.storePath + File.separator + UtilAll.offset2FileName(createOffset);
- String nextNextFilePath = this.storePath + File.separator
- + UtilAll.offset2FileName(createOffset + this.mappedFileSize);
- MappedFile mappedFile = null;
+ return tryCreateMappedFile(createOffset);
+ }
- if (this.allocateMappedFileService != null) {
- mappedFile = this.allocateMappedFileService.putRequestAndReturnMappedFile(nextFilePath,
+ return mappedFileLast;
+ }
+
+ protected MappedFile tryCreateMappedFile(long createOffset) {
+ String nextFilePath = this.storePath + File.separator + UtilAll.offset2FileName(createOffset);
+ String nextNextFilePath = this.storePath + File.separator + UtilAll.offset2FileName(createOffset
+ + this.mappedFileSize);
+ return doCreateMappedFile(nextFilePath, nextNextFilePath);
+ }
+
+ protected MappedFile doCreateMappedFile(String nextFilePath, String nextNextFilePath) {
+ MappedFile mappedFile = null;
+
+ if (this.allocateMappedFileService != null) {
+ mappedFile = this.allocateMappedFileService.putRequestAndReturnMappedFile(nextFilePath,
nextNextFilePath, this.mappedFileSize);
- } else {
- try {
- mappedFile = new MappedFile(nextFilePath, this.mappedFileSize);
- } catch (IOException e) {
- log.error("create mappedFile exception", e);
- }
+ } else {
+ try {
+ mappedFile = new MappedFile(nextFilePath, this.mappedFileSize);
+ } catch (IOException e) {
+ log.error("create mappedFile exception", e);
}
+ }
- if (mappedFile != null) {
- if (this.mappedFiles.isEmpty()) {
- mappedFile.setFirstCreateInQueue(true);
- }
- this.mappedFiles.add(mappedFile);
+ if (mappedFile != null) {
+ if (this.mappedFiles.isEmpty()) {
+ mappedFile.setFirstCreateInQueue(true);
}
-
- return mappedFile;
+ this.mappedFiles.add(mappedFile);
}
- return mappedFileLast;
+ return mappedFile;
}
public MappedFile getLastMappedFile(final long startOffset) {
diff --git a/store/src/main/java/org/apache/rocketmq/store/MultiPathMappedFileQueue.java b/store/src/main/java/org/apache/rocketmq/store/MultiPathMappedFileQueue.java
new file mode 100644
index 0000000000000000000000000000000000000000..669698ff4e99c5e1e5b43a4baefa3ac70213407a
--- /dev/null
+++ b/store/src/main/java/org/apache/rocketmq/store/MultiPathMappedFileQueue.java
@@ -0,0 +1,127 @@
+/*
+ * 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.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.function.Supplier;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.rocketmq.common.UtilAll;
+import org.apache.rocketmq.store.config.MessageStoreConfig;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+public class MultiPathMappedFileQueue extends MappedFileQueue {
+
+ private final MessageStoreConfig config;
+ private final Supplier> fullStorePathsSupplier;
+
+ public MultiPathMappedFileQueue(MessageStoreConfig messageStoreConfig, int mappedFileSize,
+ AllocateMappedFileService allocateMappedFileService,
+ Supplier> fullStorePathsSupplier) {
+ super(messageStoreConfig.getStorePathCommitLog(), mappedFileSize, allocateMappedFileService);
+ this.config = messageStoreConfig;
+ this.fullStorePathsSupplier = fullStorePathsSupplier;
+ }
+
+ private Set getPaths() {
+ String[] paths = config.getStorePathCommitLog().trim().split(MessageStoreConfig.MULTI_PATH_SPLITTER);
+ return new HashSet<>(Arrays.asList(paths));
+ }
+
+ private Set getReadonlyPaths() {
+ String pathStr = config.getReadOnlyCommitLogStorePaths();
+ if (StringUtils.isBlank(pathStr)) {
+ return Collections.emptySet();
+ }
+ String[] paths = pathStr.trim().split(MessageStoreConfig.MULTI_PATH_SPLITTER);
+ return new HashSet<>(Arrays.asList(paths));
+ }
+
+ @Override
+ public boolean load() {
+ Set storePathSet = getPaths();
+ storePathSet.addAll(getReadonlyPaths());
+
+ List files = new ArrayList<>();
+ for (String path : storePathSet) {
+ File dir = new File(path);
+ File[] ls = dir.listFiles();
+ if (ls != null) {
+ Collections.addAll(files, ls);
+ }
+ }
+
+ return doLoad(files);
+ }
+
+ @Override
+ protected MappedFile tryCreateMappedFile(long createOffset) {
+ long fileIdx = createOffset / this.mappedFileSize;
+ Set storePath = getPaths();
+ Set readonlyPathSet = getReadonlyPaths();
+ Set fullStorePaths =
+ fullStorePathsSupplier == null ? Collections.emptySet() : fullStorePathsSupplier.get();
+
+
+ HashSet availableStorePath = new HashSet<>(storePath);
+ //do not create file in readonly store path.
+ availableStorePath.removeAll(readonlyPathSet);
+
+ //do not create file is space is nearly full.
+ availableStorePath.removeAll(fullStorePaths);
+
+ //if no store path left, fall back to writable store path.
+ if (availableStorePath.isEmpty()) {
+ availableStorePath = new HashSet<>(storePath);
+ availableStorePath.removeAll(readonlyPathSet);
+ }
+
+ String[] paths = availableStorePath.toArray(new String[]{});
+ Arrays.sort(paths);
+ String nextFilePath = paths[(int) (fileIdx % paths.length)] + File.separator
+ + UtilAll.offset2FileName(createOffset);
+ String nextNextFilePath = paths[(int) ((fileIdx + 1) % paths.length)] + File.separator
+ + UtilAll.offset2FileName(createOffset + this.mappedFileSize);
+ return doCreateMappedFile(nextFilePath, nextNextFilePath);
+ }
+
+ @Override
+ public void destroy() {
+ for (MappedFile mf : this.mappedFiles) {
+ mf.destroy(1000 * 3);
+ }
+ this.mappedFiles.clear();
+ this.flushedWhere = 0;
+
+
+ Set storePathSet = getPaths();
+ storePathSet.addAll(getReadonlyPaths());
+
+ for (String path : storePathSet) {
+ File file = new File(path);
+ if (file.isDirectory()) {
+ file.delete();
+ }
+ }
+ }
+}
diff --git a/store/src/main/java/org/apache/rocketmq/store/StoreStatsService.java b/store/src/main/java/org/apache/rocketmq/store/StoreStatsService.java
index 8372845e7fed8ed68b274bff18a5bb8de82d0925..395f5e30057940387623897838d2941f1ca1eb10 100644
--- a/store/src/main/java/org/apache/rocketmq/store/StoreStatsService.java
+++ b/store/src/main/java/org/apache/rocketmq/store/StoreStatsService.java
@@ -22,7 +22,7 @@ import java.util.LinkedList;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
-import java.util.concurrent.atomic.AtomicLong;
+import java.util.concurrent.atomic.LongAdder;
import java.util.concurrent.locks.ReentrantLock;
import org.apache.rocketmq.common.ServiceThread;
import org.apache.rocketmq.common.constant.LoggerName;
@@ -41,23 +41,23 @@ public class StoreStatsService extends ServiceThread {
private static int printTPSInterval = 60 * 1;
- private final AtomicLong putMessageFailedTimes = new AtomicLong(0);
+ private final LongAdder putMessageFailedTimes = new LongAdder();
- private final ConcurrentMap putMessageTopicTimesTotal =
- new ConcurrentHashMap(128);
- private final ConcurrentMap putMessageTopicSizeTotal =
- new ConcurrentHashMap(128);
+ private final ConcurrentMap putMessageTopicTimesTotal =
+ new ConcurrentHashMap<>(128);
+ private final ConcurrentMap putMessageTopicSizeTotal =
+ new ConcurrentHashMap<>(128);
- private final AtomicLong getMessageTimesTotalFound = new AtomicLong(0);
- private final AtomicLong getMessageTransferedMsgCount = new AtomicLong(0);
- private final AtomicLong getMessageTimesTotalMiss = new AtomicLong(0);
+ private final LongAdder getMessageTimesTotalFound = new LongAdder();
+ private final LongAdder getMessageTransferedMsgCount = new LongAdder();
+ private final LongAdder getMessageTimesTotalMiss = new LongAdder();
private final LinkedList putTimesList = new LinkedList();
private final LinkedList getTimesFoundList = new LinkedList();
private final LinkedList getTimesMissList = new LinkedList();
private final LinkedList transferedMsgCountList = new LinkedList();
- private volatile AtomicLong[] putMessageDistributeTime;
- private volatile AtomicLong[] lastPutMessageDistributeTime;
+ private volatile LongAdder[] putMessageDistributeTime;
+ private volatile LongAdder[] lastPutMessageDistributeTime;
private long messageStoreBootTimestamp = System.currentTimeMillis();
private volatile long putMessageEntireTimeMax = 0;
private volatile long getMessageEntireTimeMax = 0;
@@ -75,10 +75,10 @@ public class StoreStatsService extends ServiceThread {
this.initPutMessageDistributeTime();
}
- private AtomicLong[] initPutMessageDistributeTime() {
- AtomicLong[] next = new AtomicLong[13];
+ private LongAdder[] initPutMessageDistributeTime() {
+ LongAdder[] next = new LongAdder[13];
for (int i = 0; i < next.length; i++) {
- next[i] = new AtomicLong(0);
+ next[i] = new LongAdder();
}
this.lastPutMessageDistributeTime = this.putMessageDistributeTime;
@@ -93,48 +93,48 @@ public class StoreStatsService extends ServiceThread {
}
public void setPutMessageEntireTimeMax(long value) {
- final AtomicLong[] times = this.putMessageDistributeTime;
+ final LongAdder[] times = this.putMessageDistributeTime;
if (null == times)
return;
// us
if (value <= 0) {
- times[0].incrementAndGet();
+ times[0].add(1);
} else if (value < 10) {
- times[1].incrementAndGet();
+ times[1].add(1);
} else if (value < 50) {
- times[2].incrementAndGet();
+ times[2].add(1);
} else if (value < 100) {
- times[3].incrementAndGet();
+ times[3].add(1);
} else if (value < 200) {
- times[4].incrementAndGet();
+ times[4].add(1);
} else if (value < 500) {
- times[5].incrementAndGet();
+ times[5].add(1);
} else if (value < 1000) {
- times[6].incrementAndGet();
+ times[6].add(1);
}
// 2s
else if (value < 2000) {
- times[7].incrementAndGet();
+ times[7].add(1);
}
// 3s
else if (value < 3000) {
- times[8].incrementAndGet();
+ times[8].add(1);
}
// 4s
else if (value < 4000) {
- times[9].incrementAndGet();
+ times[9].add(1);
}
// 5s
else if (value < 5000) {
- times[10].incrementAndGet();
+ times[10].add(1);
}
// 10s
else if (value < 10000) {
- times[11].incrementAndGet();
+ times[11].add(1);
} else {
- times[12].incrementAndGet();
+ times[12].add(1);
}
if (value > this.putMessageEntireTimeMax) {
@@ -194,8 +194,8 @@ public class StoreStatsService extends ServiceThread {
public long getPutMessageTimesTotal() {
long rs = 0;
- for (AtomicLong data : putMessageTopicTimesTotal.values()) {
- rs += data.get();
+ for (LongAdder data : putMessageTopicTimesTotal.values()) {
+ rs += data.longValue();
}
return rs;
}
@@ -218,8 +218,8 @@ public class StoreStatsService extends ServiceThread {
public long getPutMessageSizeTotal() {
long rs = 0;
- for (AtomicLong data : putMessageTopicSizeTotal.values()) {
- rs += data.get();
+ for (LongAdder data : putMessageTopicSizeTotal.values()) {
+ rs += data.longValue();
}
return rs;
}
@@ -299,13 +299,13 @@ public class StoreStatsService extends ServiceThread {
}
private String putMessageDistributeTimeToString() {
- final AtomicLong[] times = this.lastPutMessageDistributeTime;
+ final LongAdder[] times = this.lastPutMessageDistributeTime;
if (null == times)
return null;
final StringBuilder sb = new StringBuilder();
for (int i = 0; i < times.length; i++) {
- long value = times[i].get();
+ long value = times[i].longValue();
sb.append(String.format("%s:%d", PUT_MESSAGE_ENTIRE_TIME_MAX_DESC[i], value));
sb.append(" ");
}
@@ -477,19 +477,19 @@ public class StoreStatsService extends ServiceThread {
}
this.getTimesFoundList.add(new CallSnapshot(System.currentTimeMillis(),
- this.getMessageTimesTotalFound.get()));
+ this.getMessageTimesTotalFound.longValue()));
if (this.getTimesFoundList.size() > (MAX_RECORDS_OF_SAMPLING + 1)) {
this.getTimesFoundList.removeFirst();
}
this.getTimesMissList.add(new CallSnapshot(System.currentTimeMillis(),
- this.getMessageTimesTotalMiss.get()));
+ this.getMessageTimesTotalMiss.longValue()));
if (this.getTimesMissList.size() > (MAX_RECORDS_OF_SAMPLING + 1)) {
this.getTimesMissList.removeFirst();
}
this.transferedMsgCountList.add(new CallSnapshot(System.currentTimeMillis(),
- this.getMessageTransferedMsgCount.get()));
+ this.getMessageTransferedMsgCount.longValue()));
if (this.transferedMsgCountList.size() > (MAX_RECORDS_OF_SAMPLING + 1)) {
this.transferedMsgCountList.removeFirst();
}
@@ -510,14 +510,14 @@ public class StoreStatsService extends ServiceThread {
this.getGetTransferedTps(printTPSInterval)
);
- final AtomicLong[] times = this.initPutMessageDistributeTime();
+ final LongAdder[] times = this.initPutMessageDistributeTime();
if (null == times)
return;
final StringBuilder sb = new StringBuilder();
long totalPut = 0;
for (int i = 0; i < times.length; i++) {
- long value = times[i].get();
+ long value = times[i].longValue();
totalPut += value;
sb.append(String.format("%s:%d", PUT_MESSAGE_ENTIRE_TIME_MAX_DESC[i], value));
sb.append(" ");
@@ -527,27 +527,27 @@ public class StoreStatsService extends ServiceThread {
}
}
- public AtomicLong getGetMessageTimesTotalFound() {
+ public LongAdder getGetMessageTimesTotalFound() {
return getMessageTimesTotalFound;
}
- public AtomicLong getGetMessageTimesTotalMiss() {
+ public LongAdder getGetMessageTimesTotalMiss() {
return getMessageTimesTotalMiss;
}
- public AtomicLong getGetMessageTransferedMsgCount() {
+ public LongAdder getGetMessageTransferedMsgCount() {
return getMessageTransferedMsgCount;
}
- public AtomicLong getPutMessageFailedTimes() {
+ public LongAdder getPutMessageFailedTimes() {
return putMessageFailedTimes;
}
- public AtomicLong getSinglePutMessageTopicSizeTotal(String topic) {
- AtomicLong rs = putMessageTopicSizeTotal.get(topic);
+ public LongAdder getSinglePutMessageTopicSizeTotal(String topic) {
+ LongAdder rs = putMessageTopicSizeTotal.get(topic);
if (null == rs) {
- rs = new AtomicLong(0);
- AtomicLong previous = putMessageTopicSizeTotal.putIfAbsent(topic, rs);
+ rs = new LongAdder();
+ LongAdder previous = putMessageTopicSizeTotal.putIfAbsent(topic, rs);
if (previous != null) {
rs = previous;
}
@@ -555,11 +555,11 @@ public class StoreStatsService extends ServiceThread {
return rs;
}
- public AtomicLong getSinglePutMessageTopicTimesTotal(String topic) {
- AtomicLong rs = putMessageTopicTimesTotal.get(topic);
+ public LongAdder getSinglePutMessageTopicTimesTotal(String topic) {
+ LongAdder rs = putMessageTopicTimesTotal.get(topic);
if (null == rs) {
- rs = new AtomicLong(0);
- AtomicLong previous = putMessageTopicTimesTotal.putIfAbsent(topic, rs);
+ rs = new LongAdder();
+ LongAdder previous = putMessageTopicTimesTotal.putIfAbsent(topic, rs);
if (previous != null) {
rs = previous;
}
@@ -567,11 +567,11 @@ public class StoreStatsService extends ServiceThread {
return rs;
}
- public Map getPutMessageTopicTimesTotal() {
+ public Map getPutMessageTopicTimesTotal() {
return putMessageTopicTimesTotal;
}
- public Map getPutMessageTopicSizeTotal() {
+ public Map getPutMessageTopicSizeTotal() {
return putMessageTopicSizeTotal;
}
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 848fe22decdb211064003ae1e7c6b7cf832da55d..e1439a0c9d8260be9c7e9fe949b364726d9f84b2 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
@@ -17,10 +17,14 @@
package org.apache.rocketmq.store.config;
import java.io.File;
+
import org.apache.rocketmq.common.annotation.ImportantField;
import org.apache.rocketmq.store.ConsumeQueue;
public class MessageStoreConfig {
+
+ public static final String MULTI_PATH_SPLITTER = System.getProperty("rocketmq.broker.multiPathSplitter", ",");
+
//The root directory in which the log data is kept
@ImportantField
private String storePathRootDir = System.getProperty("user.home") + File.separator + "store";
@@ -30,6 +34,8 @@ public class MessageStoreConfig {
private String storePathCommitLog = System.getProperty("user.home") + File.separator + "store"
+ File.separator + "commitlog";
+ private String readOnlyCommitLogStorePaths = null;
+
// CommitLog file size,default is 1G
private int mappedFileSizeCommitLog = 1024 * 1024 * 1024;
// ConsumeQueue file size,default is 30W
@@ -676,6 +682,13 @@ public class MessageStoreConfig {
this.commitCommitLogThoroughInterval = commitCommitLogThoroughInterval;
}
+ public String getReadOnlyCommitLogStorePaths() {
+ return readOnlyCommitLogStorePaths;
+ }
+
+ public void setReadOnlyCommitLogStorePaths(String readOnlyCommitLogStorePaths) {
+ this.readOnlyCommitLogStorePaths = readOnlyCommitLogStorePaths;
+ }
public String getdLegerGroup() {
return dLegerGroup;
}
diff --git a/store/src/main/java/org/apache/rocketmq/store/dledger/DLedgerCommitLog.java b/store/src/main/java/org/apache/rocketmq/store/dledger/DLedgerCommitLog.java
index 011cbe169cf7da33c095f5d4b977dc8abffdc1e9..493917587ac7a70738a718745bd6a9d6612a6168 100644
--- a/store/src/main/java/org/apache/rocketmq/store/dledger/DLedgerCommitLog.java
+++ b/store/src/main/java/org/apache/rocketmq/store/dledger/DLedgerCommitLog.java
@@ -502,8 +502,8 @@ public class DLedgerCommitLog extends CommitLog {
PutMessageResult putMessageResult = new PutMessageResult(putMessageStatus, appendResult);
if (putMessageStatus == PutMessageStatus.PUT_OK) {
// Statistics
- storeStatsService.getSinglePutMessageTopicTimesTotal(finalTopic).incrementAndGet();
- storeStatsService.getSinglePutMessageTopicSizeTotal(msg.getTopic()).addAndGet(appendResult.getWroteBytes());
+ storeStatsService.getSinglePutMessageTopicTimesTotal(finalTopic).add(1);
+ storeStatsService.getSinglePutMessageTopicSizeTotal(msg.getTopic()).add(appendResult.getWroteBytes());
}
return putMessageResult;
});
@@ -629,8 +629,8 @@ public class DLedgerCommitLog extends CommitLog {
PutMessageResult putMessageResult = new PutMessageResult(putMessageStatus, appendResult);
if (putMessageStatus == PutMessageStatus.PUT_OK) {
// Statistics
- storeStatsService.getSinglePutMessageTopicTimesTotal(messageExtBatch.getTopic()).incrementAndGet();
- storeStatsService.getSinglePutMessageTopicSizeTotal(messageExtBatch.getTopic()).addAndGet(appendResult.getWroteBytes());
+ storeStatsService.getSinglePutMessageTopicTimesTotal(messageExtBatch.getTopic()).add(1);
+ storeStatsService.getSinglePutMessageTopicSizeTotal(messageExtBatch.getTopic()).add(appendResult.getWroteBytes());
}
return putMessageResult;
});
diff --git a/store/src/main/java/org/apache/rocketmq/store/schedule/ScheduleMessageService.java b/store/src/main/java/org/apache/rocketmq/store/schedule/ScheduleMessageService.java
index bacae1e80bcfb6d7455a88ed493efb270cd595d1..e0e7b9565b6e587820988153ecdaeff2a90473d5 100644
--- a/store/src/main/java/org/apache/rocketmq/store/schedule/ScheduleMessageService.java
+++ b/store/src/main/java/org/apache/rocketmq/store/schedule/ScheduleMessageService.java
@@ -25,6 +25,7 @@ import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.atomic.AtomicBoolean;
import org.apache.rocketmq.common.ConfigManager;
+import org.apache.rocketmq.common.MixAll;
import org.apache.rocketmq.common.TopicFilterType;
import org.apache.rocketmq.common.constant.LoggerName;
import org.apache.rocketmq.common.topic.TopicValidator;
@@ -77,8 +78,7 @@ public class ScheduleMessageService extends ConfigManager {
}
/**
- * @param writeMessageStore
- * the writeMessageStore to set
+ * @param writeMessageStore the writeMessageStore to set
*/
public void setWriteMessageStore(MessageStore writeMessageStore) {
this.writeMessageStore = writeMessageStore;
@@ -132,7 +132,9 @@ public class ScheduleMessageService extends ConfigManager {
@Override
public void run() {
try {
- if (started.get()) ScheduleMessageService.this.persist();
+ if (started.get()) {
+ ScheduleMessageService.this.persist();
+ }
} catch (Throwable e) {
log.error("scheduleAtFixedRate flush exception", e);
}
@@ -164,9 +166,46 @@ public class ScheduleMessageService extends ConfigManager {
public boolean load() {
boolean result = super.load();
result = result && this.parseDelayLevel();
+ result = result && this.correctDelayOffset();
return result;
}
+ public boolean correctDelayOffset() {
+ try {
+ for (int delayLevel : delayLevelTable.keySet()) {
+ ConsumeQueue cq =
+ ScheduleMessageService.this.defaultMessageStore.findConsumeQueue(TopicValidator.RMQ_SYS_SCHEDULE_TOPIC,
+ delayLevel2QueueId(delayLevel));
+ Long currentDelayOffset = offsetTable.get(delayLevel);
+ if (currentDelayOffset == null || cq == null) {
+ continue;
+ }
+ long correctDelayOffset = currentDelayOffset;
+ long cqMinOffset = cq.getMinOffsetInQueue();
+ long cqMaxOffset = cq.getMaxOffsetInQueue();
+ if (currentDelayOffset < cqMinOffset) {
+ correctDelayOffset = cqMinOffset;
+ log.error("schedule CQ offset invalid. offset={}, cqMinOffset={}, cqMaxOffset={}, queueId={}",
+ currentDelayOffset, cqMinOffset, cqMaxOffset, cq.getQueueId());
+ }
+
+ if (currentDelayOffset > cqMaxOffset) {
+ correctDelayOffset = cqMaxOffset;
+ log.error("schedule CQ offset invalid. offset={}, cqMinOffset={}, cqMaxOffset={}, queueId={}",
+ currentDelayOffset, cqMinOffset, cqMaxOffset, cq.getQueueId());
+ }
+ if (correctDelayOffset != currentDelayOffset) {
+ log.error("correct delay offset [ delayLevel {} ] from {} to {}", delayLevel, currentDelayOffset, correctDelayOffset);
+ offsetTable.put(delayLevel, correctDelayOffset);
+ }
+ }
+ } catch (Exception e) {
+ log.error("correctDelayOffset exception", e);
+ return false;
+ }
+ return true;
+ }
+
@Override
public String configFilePath() {
return StorePathConfigHelper.getDelayOffsetStorePath(this.defaultMessageStore.getMessageStoreConfig()
@@ -308,7 +347,7 @@ public class ScheduleMessageService extends ConfigManager {
MessageExtBrokerInner msgInner = this.messageTimeup(msgExt);
if (TopicValidator.RMQ_SYS_TRANS_HALF_TOPIC.equals(msgInner.getTopic())) {
log.error("[BUG] the real topic of schedule msg is {}, discard the msg. msg={}",
- msgInner.getTopic(), msgInner);
+ msgInner.getTopic(), msgInner);
continue;
}
PutMessageResult putMessageResult =
@@ -318,6 +357,10 @@ public class ScheduleMessageService extends ConfigManager {
if (putMessageResult != null
&& putMessageResult.getPutMessageStatus() == PutMessageStatus.PUT_OK) {
if (ScheduleMessageService.this.defaultMessageStore.getMessageStoreConfig().isEnableScheduleMessageStats()) {
+ ScheduleMessageService.this.defaultMessageStore.getBrokerStatsManager().incQueueGetNums(MixAll.SCHEDULE_CONSUMER_GROUP, TopicValidator.RMQ_SYS_SCHEDULE_TOPIC, delayLevel - 1, putMessageResult.getAppendMessageResult().getMsgNum());
+ ScheduleMessageService.this.defaultMessageStore.getBrokerStatsManager().incQueueGetSize(MixAll.SCHEDULE_CONSUMER_GROUP, TopicValidator.RMQ_SYS_SCHEDULE_TOPIC, delayLevel - 1, putMessageResult.getAppendMessageResult().getWroteBytes());
+ ScheduleMessageService.this.defaultMessageStore.getBrokerStatsManager().incGroupGetNums(MixAll.SCHEDULE_CONSUMER_GROUP, TopicValidator.RMQ_SYS_SCHEDULE_TOPIC, putMessageResult.getAppendMessageResult().getMsgNum());
+ ScheduleMessageService.this.defaultMessageStore.getBrokerStatsManager().incGroupGetSize(MixAll.SCHEDULE_CONSUMER_GROUP, TopicValidator.RMQ_SYS_SCHEDULE_TOPIC, putMessageResult.getAppendMessageResult().getWroteBytes());
ScheduleMessageService.this.defaultMessageStore.getBrokerStatsManager().incTopicPutNums(msgInner.getTopic(), putMessageResult.getAppendMessageResult().getMsgNum(), 1);
ScheduleMessageService.this.defaultMessageStore.getBrokerStatsManager().incTopicPutSize(msgInner.getTopic(),
putMessageResult.getAppendMessageResult().getWroteBytes());
@@ -339,14 +382,9 @@ public class ScheduleMessageService extends ConfigManager {
} catch (Exception e) {
/*
* XXX: warn and notify me
-
-
-
*/
log.error(
- "ScheduleMessageService, messageTimeup execute error, drop it. msgExt="
- + msgExt + ", nextOffset=" + nextOffset + ",offsetPy="
- + offsetPy + ",sizePy=" + sizePy, e);
+ "ScheduleMessageService, messageTimeup execute error, drop it. msgExt={}, nextOffset={}, offsetPy={}, sizePy={}", msgExt, nextOffset, offsetPy, sizePy, e);
}
}
} else {
@@ -371,10 +409,17 @@ public class ScheduleMessageService extends ConfigManager {
else {
long cqMinOffset = cq.getMinOffsetInQueue();
+ long cqMaxOffset = cq.getMaxOffsetInQueue();
if (offset < cqMinOffset) {
failScheduleOffset = cqMinOffset;
- log.error("schedule CQ offset invalid. offset=" + offset + ", cqMinOffset="
- + cqMinOffset + ", queueId=" + cq.getQueueId());
+ log.error("schedule CQ offset invalid. offset={}, cqMinOffset={}, cqMaxOffset={}, queueId={}",
+ offset, cqMinOffset, cqMaxOffset, cq.getQueueId());
+ }
+
+ if (offset > cqMaxOffset) {
+ failScheduleOffset = cqMaxOffset;
+ log.error("schedule CQ offset invalid. offset={}, cqMinOffset={}, cqMaxOffset={}, queueId={}",
+ offset, cqMinOffset, cqMaxOffset, cq.getQueueId());
}
}
} // end of if (cq != null)
diff --git a/store/src/main/java/org/apache/rocketmq/store/stats/BrokerStats.java b/store/src/main/java/org/apache/rocketmq/store/stats/BrokerStats.java
index 38ace7d3814ad503a0e0f9a55007329f3fe03642..a7cbdd36aa54be83eddfe85c3ee99a1fca445403 100644
--- a/store/src/main/java/org/apache/rocketmq/store/stats/BrokerStats.java
+++ b/store/src/main/java/org/apache/rocketmq/store/stats/BrokerStats.java
@@ -45,7 +45,7 @@ public class BrokerStats {
this.msgPutTotalTodayMorning =
this.defaultMessageStore.getStoreStatsService().getPutMessageTimesTotal();
this.msgGetTotalTodayMorning =
- this.defaultMessageStore.getStoreStatsService().getGetMessageTransferedMsgCount().get();
+ this.defaultMessageStore.getStoreStatsService().getGetMessageTransferedMsgCount().longValue();
log.info("yesterday put message total: {}", msgPutTotalTodayMorning - msgPutTotalYesterdayMorning);
log.info("yesterday get message total: {}", msgGetTotalTodayMorning - msgGetTotalYesterdayMorning);
@@ -88,6 +88,6 @@ public class BrokerStats {
}
public long getMsgGetTotalTodayNow() {
- return this.defaultMessageStore.getStoreStatsService().getGetMessageTransferedMsgCount().get();
+ return this.defaultMessageStore.getStoreStatsService().getGetMessageTransferedMsgCount().longValue();
}
}
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 e151844706601bad8a19a1e8784bc95ffa0a314e..b9e11fd5929b8980a7dab83816e1f621cfc35dc5 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
@@ -29,6 +29,10 @@ import org.apache.rocketmq.common.stats.StatsItemSet;
public class BrokerStatsManager {
+ public static final String QUEUE_PUT_NUMS = "QUEUE_PUT_NUMS";
+ public static final String QUEUE_PUT_SIZE = "QUEUE_PUT_SIZE";
+ public static final String QUEUE_GET_NUMS = "QUEUE_GET_NUMS";
+ public static final String QUEUE_GET_SIZE = "QUEUE_GET_SIZE";
public static final String TOPIC_PUT_NUMS = "TOPIC_PUT_NUMS";
public static final String TOPIC_PUT_SIZE = "TOPIC_PUT_SIZE";
public static final String GROUP_GET_NUMS = "GROUP_GET_NUMS";
@@ -74,6 +78,10 @@ public class BrokerStatsManager {
public BrokerStatsManager(String clusterName) {
this.clusterName = clusterName;
+ this.statsTable.put(QUEUE_PUT_NUMS, new StatsItemSet(QUEUE_PUT_NUMS, this.scheduledExecutorService, log));
+ this.statsTable.put(QUEUE_PUT_SIZE, new StatsItemSet(QUEUE_PUT_SIZE, this.scheduledExecutorService, log));
+ this.statsTable.put(QUEUE_GET_NUMS, new StatsItemSet(QUEUE_GET_NUMS, this.scheduledExecutorService, log));
+ this.statsTable.put(QUEUE_GET_SIZE, new StatsItemSet(QUEUE_GET_SIZE, this.scheduledExecutorService, log));
this.statsTable.put(TOPIC_PUT_NUMS, new StatsItemSet(TOPIC_PUT_NUMS, this.scheduledExecutorService, log));
this.statsTable.put(TOPIC_PUT_SIZE, new StatsItemSet(TOPIC_PUT_SIZE, this.scheduledExecutorService, log));
this.statsTable.put(GROUP_GET_NUMS, new StatsItemSet(GROUP_GET_NUMS, this.scheduledExecutorService, log));
@@ -124,8 +132,12 @@ public class BrokerStatsManager {
public void onTopicDeleted(final String topic) {
this.statsTable.get(TOPIC_PUT_NUMS).delValue(topic);
this.statsTable.get(TOPIC_PUT_SIZE).delValue(topic);
+ this.statsTable.get(QUEUE_PUT_NUMS).delValueByPrefixKey(topic, "@");
+ this.statsTable.get(QUEUE_PUT_SIZE).delValueByPrefixKey(topic, "@");
this.statsTable.get(GROUP_GET_NUMS).delValueByPrefixKey(topic, "@");
this.statsTable.get(GROUP_GET_SIZE).delValueByPrefixKey(topic, "@");
+ this.statsTable.get(QUEUE_GET_NUMS).delValueByPrefixKey(topic, "@");
+ this.statsTable.get(QUEUE_GET_SIZE).delValueByPrefixKey(topic, "@");
this.statsTable.get(SNDBCK_PUT_NUMS).delValueByPrefixKey(topic, "@");
this.statsTable.get(GROUP_GET_LATENCY).delValueByInfixKey(topic, "@");
this.momentStatsItemSetFallSize.delValueByInfixKey(topic, "@");
@@ -135,12 +147,36 @@ public class BrokerStatsManager {
public void onGroupDeleted(final String group) {
this.statsTable.get(GROUP_GET_NUMS).delValueBySuffixKey(group, "@");
this.statsTable.get(GROUP_GET_SIZE).delValueBySuffixKey(group, "@");
+ this.statsTable.get(QUEUE_GET_NUMS).delValueBySuffixKey(group, "@");
+ this.statsTable.get(QUEUE_GET_SIZE).delValueBySuffixKey(group, "@");
this.statsTable.get(SNDBCK_PUT_NUMS).delValueBySuffixKey(group, "@");
this.statsTable.get(GROUP_GET_LATENCY).delValueBySuffixKey(group, "@");
this.momentStatsItemSetFallSize.delValueBySuffixKey(group, "@");
this.momentStatsItemSetFallTime.delValueBySuffixKey(group, "@");
}
+ public void incQueuePutNums(final String topic, final Integer queueId) {
+ this.statsTable.get(QUEUE_PUT_NUMS).addValue(buildStatsKey(topic, String.valueOf(queueId)), 1, 1);
+ }
+
+ public void incQueuePutNums(final String topic, final Integer queueId, int num, int times) {
+ this.statsTable.get(QUEUE_PUT_NUMS).addValue(buildStatsKey(topic, String.valueOf(queueId)), num, times);
+ }
+
+ public void incQueuePutSize(final String topic, final Integer queueId, final int size) {
+ this.statsTable.get(QUEUE_PUT_SIZE).addValue(buildStatsKey(topic, String.valueOf(queueId)), size, 1);
+ }
+
+ public void incQueueGetNums(final String group, final String topic, final Integer queueId, final int incValue) {
+ final String statsKey = buildStatsKey(buildStatsKey(topic, String.valueOf(queueId)), group);
+ this.statsTable.get(QUEUE_GET_NUMS).addValue(statsKey, incValue, 1);
+ }
+
+ public void incQueueGetSize(final String group, final String topic, final Integer queueId, final int incValue) {
+ final String statsKey = buildStatsKey(buildStatsKey(topic, String.valueOf(queueId)), group);
+ this.statsTable.get(QUEUE_GET_SIZE).addValue(statsKey, incValue, 1);
+ }
+
public void incTopicPutNums(final String topic) {
this.statsTable.get(TOPIC_PUT_NUMS).addValue(topic, 1, 1);
}
@@ -158,11 +194,11 @@ public class BrokerStatsManager {
this.statsTable.get(GROUP_GET_NUMS).addValue(statsKey, incValue, 1);
}
- public String buildStatsKey(String topic, String group) {
+ public String buildStatsKey(String prefix, String suffix) {
StringBuffer strBuilder = new StringBuffer();
- strBuilder.append(topic);
+ strBuilder.append(prefix);
strBuilder.append("@");
- strBuilder.append(group);
+ strBuilder.append(suffix);
return strBuilder.toString();
}
@@ -177,15 +213,15 @@ public class BrokerStatsManager {
}
public void incBrokerPutNums() {
- this.statsTable.get(BROKER_PUT_NUMS).getAndCreateStatsItem(this.clusterName).getValue().incrementAndGet();
+ this.statsTable.get(BROKER_PUT_NUMS).getAndCreateStatsItem(this.clusterName).getValue().add(1);
}
public void incBrokerPutNums(final int incValue) {
- this.statsTable.get(BROKER_PUT_NUMS).getAndCreateStatsItem(this.clusterName).getValue().addAndGet(incValue);
+ this.statsTable.get(BROKER_PUT_NUMS).getAndCreateStatsItem(this.clusterName).getValue().add(incValue);
}
public void incBrokerGetNums(final int incValue) {
- this.statsTable.get(BROKER_GET_NUMS).getAndCreateStatsItem(this.clusterName).getValue().addAndGet(incValue);
+ this.statsTable.get(BROKER_GET_NUMS).getAndCreateStatsItem(this.clusterName).getValue().add(incValue);
}
public void incSendBackNums(final String group, final String topic) {
@@ -217,7 +253,7 @@ public class BrokerStatsManager {
}
public String buildCommercialStatsKey(String owner, String topic, String group, String type) {
- StringBuffer strBuilder = new StringBuffer();
+ StringBuilder strBuilder = new StringBuilder();
strBuilder.append(owner);
strBuilder.append("@");
strBuilder.append(topic);
diff --git a/store/src/test/java/org/apache/rocketmq/store/DefaultMessageStoreCleanFilesTest.java b/store/src/test/java/org/apache/rocketmq/store/DefaultMessageStoreCleanFilesTest.java
index 7455dfea3c811381d86a7e733aea0394479eec7e..69c1673ee48b792b7b63513297a4e851ff2a7867 100644
--- a/store/src/test/java/org/apache/rocketmq/store/DefaultMessageStoreCleanFilesTest.java
+++ b/store/src/test/java/org/apache/rocketmq/store/DefaultMessageStoreCleanFilesTest.java
@@ -94,6 +94,41 @@ public class DefaultMessageStoreCleanFilesTest {
}
+ @Test
+ public void testIsSpaceFullMultiCommitLogStorePath() throws Exception {
+ String deleteWhen = "04";
+ // the min value of diskMaxUsedSpaceRatio.
+ int diskMaxUsedSpaceRatio = 1;
+ // used to set disk-full flag
+ double diskSpaceCleanForciblyRatio = 0.01D;
+ MessageStoreConfig config = genMessageStoreConfig(deleteWhen, diskMaxUsedSpaceRatio);
+ String storePath = config.getStorePathCommitLog();
+ StringBuilder storePathBuilder = new StringBuilder();
+ for (int i = 0; i < 3; i++) {
+ storePathBuilder.append(storePath).append(i).append(MessageStoreConfig.MULTI_PATH_SPLITTER);
+ }
+ config.setStorePathCommitLog(storePathBuilder.toString());
+ String[] paths = config.getStorePathCommitLog().trim().split(MessageStoreConfig.MULTI_PATH_SPLITTER);
+ assertEquals(3, paths.length);
+ initMessageStore(config, diskSpaceCleanForciblyRatio);
+
+
+
+ // build and put 55 messages, exactly one message per CommitLog file.
+ buildAndPutMessagesToMessageStore(msgCount);
+ MappedFileQueue commitLogQueue = getMappedFileQueueCommitLog();
+ assertEquals(fileCountCommitLog, commitLogQueue.getMappedFiles().size());
+ int fileCountConsumeQueue = getFileCountConsumeQueue();
+ MappedFileQueue consumeQueue = getMappedFileQueueConsumeQueue();
+ assertEquals(fileCountConsumeQueue, consumeQueue.getMappedFiles().size());
+ cleanCommitLogService.isSpaceFull();
+
+ assertEquals(1 << 4, messageStore.getRunningFlags().getFlagBits() & (1 << 4));
+ messageStore.shutdown();
+ messageStore.destroy();
+
+ }
+
@Test
public void testIsSpaceFullFunctionFull2Empty() throws Exception {
String deleteWhen = "04";
@@ -421,6 +456,10 @@ public class DefaultMessageStoreCleanFilesTest {
}
private void initMessageStore(String deleteWhen, int diskMaxUsedSpaceRatio, double diskSpaceCleanForciblyRatio) throws Exception {
+ initMessageStore(genMessageStoreConfig(deleteWhen,diskMaxUsedSpaceRatio), diskSpaceCleanForciblyRatio);
+ }
+
+ private MessageStoreConfig genMessageStoreConfig(String deleteWhen, int diskMaxUsedSpaceRatio) {
MessageStoreConfig messageStoreConfig = new MessageStoreConfigForTest();
messageStoreConfig.setMappedFileSizeCommitLog(mappedFileSize);
messageStoreConfig.setMappedFileSizeConsumeQueue(mappedFileSize);
@@ -442,7 +481,10 @@ public class DefaultMessageStoreCleanFilesTest {
String storePathCommitLog = storePathRootDir + File.separator + "commitlog";
messageStoreConfig.setStorePathRootDir(storePathRootDir);
messageStoreConfig.setStorePathCommitLog(storePathCommitLog);
+ return messageStoreConfig;
+ }
+ private void initMessageStore(MessageStoreConfig messageStoreConfig, double diskSpaceCleanForciblyRatio) throws Exception {
messageStore = new DefaultMessageStore(messageStoreConfig,
new BrokerStatsManager("test"), new MyMessageArrivingListener(), new BrokerConfig());
diff --git a/store/src/test/java/org/apache/rocketmq/store/DefaultMessageStoreTest.java b/store/src/test/java/org/apache/rocketmq/store/DefaultMessageStoreTest.java
index 440f9146314a049a91e7096f4b382399b878f8d6..f3e619d7784595280d3a54c239b3136b7ea97199 100644
--- a/store/src/test/java/org/apache/rocketmq/store/DefaultMessageStoreTest.java
+++ b/store/src/test/java/org/apache/rocketmq/store/DefaultMessageStoreTest.java
@@ -605,6 +605,22 @@ public class DefaultMessageStoreTest {
}
}
+ @Test
+ public void testStorePathOK() {
+ if (messageStore instanceof DefaultMessageStore) {
+ assertTrue(fileExists(((DefaultMessageStore) messageStore).getStorePathPhysic()));
+ assertTrue(fileExists(((DefaultMessageStore) messageStore).getStorePathLogic()));
+ }
+ }
+
+ private boolean fileExists(String path) {
+ if (path != null) {
+ File f = new File(path);
+ return f.exists();
+ }
+ return false;
+ }
+
private void damageCommitlog(long offset) throws Exception {
MessageStoreConfig messageStoreConfig = new MessageStoreConfig();
File file = new File(messageStoreConfig.getStorePathCommitLog() + File.separator + "00000000000000000000");
diff --git a/store/src/test/java/org/apache/rocketmq/store/MultiPathMappedFileQueueTest.java b/store/src/test/java/org/apache/rocketmq/store/MultiPathMappedFileQueueTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..66b3f93b01f8db4449b427dfdeaa087523254d7c
--- /dev/null
+++ b/store/src/test/java/org/apache/rocketmq/store/MultiPathMappedFileQueueTest.java
@@ -0,0 +1,154 @@
+/*
+ * 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 static org.assertj.core.api.Assertions.assertThat;
+import java.util.HashSet;
+import java.util.Set;
+import org.apache.rocketmq.common.UtilAll;
+import org.apache.rocketmq.store.config.MessageStoreConfig;
+import org.junit.Test;
+
+
+public class MultiPathMappedFileQueueTest {
+
+ @Test
+ public void testGetLastMappedFile() {
+ final byte[] fixedMsg = new byte[1024];
+
+ MessageStoreConfig config = new MessageStoreConfig();
+ config.setStorePathCommitLog("target/unit_test_store/a/" + MessageStoreConfig.MULTI_PATH_SPLITTER
+ + "target/unit_test_store/b/" + MessageStoreConfig.MULTI_PATH_SPLITTER
+ + "target/unit_test_store/c/");
+ MappedFileQueue mappedFileQueue = new MultiPathMappedFileQueue(config, 1024, null, null);
+ String[] storePaths = config.getStorePathCommitLog().trim().split(MessageStoreConfig.MULTI_PATH_SPLITTER);
+ for (int i = 0; i < 1024; i++) {
+ MappedFile mappedFile = mappedFileQueue.getLastMappedFile(fixedMsg.length * i);
+ assertThat(mappedFile).isNotNull();
+ assertThat(mappedFile.appendMessage(fixedMsg)).isTrue();
+ int idx = i % storePaths.length;
+ assertThat(mappedFile.getFileName().startsWith(storePaths[idx])).isTrue();
+ }
+ mappedFileQueue.shutdown(1000);
+ mappedFileQueue.destroy();
+ }
+
+ @Test
+ public void testLoadReadOnlyMappedFiles() {
+ {
+ //create old mapped files
+ final byte[] fixedMsg = new byte[1024];
+ MessageStoreConfig config = new MessageStoreConfig();
+ config.setStorePathCommitLog("target/unit_test_store/a/" + MessageStoreConfig.MULTI_PATH_SPLITTER
+ + "target/unit_test_store/b/" + MessageStoreConfig.MULTI_PATH_SPLITTER
+ + "target/unit_test_store/c/");
+ MappedFileQueue mappedFileQueue = new MultiPathMappedFileQueue(config, 1024, null, null);
+ String[] storePaths = config.getStorePathCommitLog().trim().split(MessageStoreConfig.MULTI_PATH_SPLITTER);
+ for (int i = 0; i < 1024; i++) {
+ MappedFile mappedFile = mappedFileQueue.getLastMappedFile(fixedMsg.length * i);
+ assertThat(mappedFile).isNotNull();
+ assertThat(mappedFile.appendMessage(fixedMsg)).isTrue();
+ int idx = i % storePaths.length;
+ assertThat(mappedFile.getFileName().startsWith(storePaths[idx])).isTrue();
+ }
+ mappedFileQueue.shutdown(1000);
+ }
+
+ // test load and readonly
+ MessageStoreConfig config = new MessageStoreConfig();
+ config.setStorePathCommitLog("target/unit_test_store/b/");
+ config.setReadOnlyCommitLogStorePaths("target/unit_test_store/a" + MessageStoreConfig.MULTI_PATH_SPLITTER
+ + "target/unit_test_store/c");
+ MultiPathMappedFileQueue mappedFileQueue = new MultiPathMappedFileQueue(config, 1024, null, null);
+
+ mappedFileQueue.load();
+
+ assertThat(mappedFileQueue.mappedFiles.size()).isEqualTo(1024);
+ for (int i = 0; i < 1024; i++) {
+ assertThat(mappedFileQueue.mappedFiles.get(i).getFile().getName())
+ .isEqualTo(UtilAll.offset2FileName(1024 * i));
+ }
+ mappedFileQueue.destroy();
+
+ }
+
+ @Test
+ public void testUpdatePathsOnline() {
+ final byte[] fixedMsg = new byte[1024];
+
+ MessageStoreConfig config = new MessageStoreConfig();
+ config.setStorePathCommitLog("target/unit_test_store/a/" + MessageStoreConfig.MULTI_PATH_SPLITTER
+ + "target/unit_test_store/b/" + MessageStoreConfig.MULTI_PATH_SPLITTER
+ + "target/unit_test_store/c/");
+ MappedFileQueue mappedFileQueue = new MultiPathMappedFileQueue(config, 1024, null, null);
+ String[] storePaths = config.getStorePathCommitLog().trim().split(MessageStoreConfig.MULTI_PATH_SPLITTER);
+ for (int i = 0; i < 1024; i++) {
+ MappedFile mappedFile = mappedFileQueue.getLastMappedFile(fixedMsg.length * i);
+ assertThat(mappedFile).isNotNull();
+ assertThat(mappedFile.appendMessage(fixedMsg)).isTrue();
+ int idx = i % storePaths.length;
+ assertThat(mappedFile.getFileName().startsWith(storePaths[idx])).isTrue();
+
+ if (i == 500) {
+ config.setStorePathCommitLog("target/unit_test_store/a/" + MessageStoreConfig.MULTI_PATH_SPLITTER
+ + "target/unit_test_store/b/");
+ storePaths = config.getStorePathCommitLog().trim().split(MessageStoreConfig.MULTI_PATH_SPLITTER);
+ }
+ }
+ mappedFileQueue.shutdown(1000);
+ mappedFileQueue.destroy();
+ }
+
+ @Test
+ public void testFullStorePath() {
+ final byte[] fixedMsg = new byte[1024];
+
+ Set fullStorePath = new HashSet<>();
+ MessageStoreConfig config = new MessageStoreConfig();
+ config.setStorePathCommitLog("target/unit_test_store/a/" + MessageStoreConfig.MULTI_PATH_SPLITTER
+ + "target/unit_test_store/b/" + MessageStoreConfig.MULTI_PATH_SPLITTER
+ + "target/unit_test_store/c/");
+ MappedFileQueue mappedFileQueue = new MultiPathMappedFileQueue(config, 1024, null, () -> fullStorePath);
+ String[] storePaths = config.getStorePathCommitLog().trim().split(MessageStoreConfig.MULTI_PATH_SPLITTER);
+ assertThat(storePaths.length).isEqualTo(3);
+
+ MappedFile mappedFile = mappedFileQueue.getLastMappedFile(0);
+ assertThat(mappedFile).isNotNull();
+ assertThat(mappedFile.appendMessage(fixedMsg)).isTrue();
+ assertThat(mappedFile.getFileName().startsWith(storePaths[0])).isTrue();
+
+ mappedFile = mappedFileQueue.getLastMappedFile(fixedMsg.length);
+ assertThat(mappedFile.getFileName().startsWith(storePaths[1])).isTrue();
+ assertThat(mappedFile.appendMessage(fixedMsg)).isTrue();
+ mappedFile = mappedFileQueue.getLastMappedFile(fixedMsg.length * 2);
+ assertThat(mappedFile.appendMessage(fixedMsg)).isTrue();
+ assertThat(mappedFile.getFileName().startsWith(storePaths[2])).isTrue();
+
+ fullStorePath.add("target/unit_test_store/b/");
+ mappedFile = mappedFileQueue.getLastMappedFile(fixedMsg.length * 3);
+ assertThat(mappedFile.appendMessage(fixedMsg)).isTrue();
+ assertThat(mappedFile.getFileName().startsWith(storePaths[2])).isTrue();
+
+ mappedFile = mappedFileQueue.getLastMappedFile(fixedMsg.length * 4);
+ assertThat(mappedFile.appendMessage(fixedMsg)).isTrue();
+ assertThat(mappedFile.getFileName().startsWith(storePaths[0])).isTrue();
+
+ mappedFileQueue.shutdown(1000);
+ mappedFileQueue.destroy();
+ }
+}
\ No newline at end of file
diff --git a/store/src/test/java/org/apache/rocketmq/store/ScheduleMessageServiceTest.java b/store/src/test/java/org/apache/rocketmq/store/ScheduleMessageServiceTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..8502521fe8e7108240ffa07f1a3c69a66a18dbe6
--- /dev/null
+++ b/store/src/test/java/org/apache/rocketmq/store/ScheduleMessageServiceTest.java
@@ -0,0 +1,84 @@
+/*
+ * 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.util.Map;
+import java.util.Random;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import org.apache.rocketmq.common.BrokerConfig;
+import org.apache.rocketmq.store.config.FlushDiskType;
+import org.apache.rocketmq.store.config.MessageStoreConfig;
+import org.apache.rocketmq.store.schedule.ScheduleMessageService;
+import org.apache.rocketmq.store.stats.BrokerStatsManager;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+public class ScheduleMessageServiceTest {
+
+ private Random random = new Random();
+
+ @Test
+ public void testCorrectDelayOffset_whenInit() throws Exception {
+
+ ConcurrentMap offsetTable = null;
+
+ ScheduleMessageService scheduleMessageService = new ScheduleMessageService((DefaultMessageStore) buildMessageStore());
+ scheduleMessageService.parseDelayLevel();
+
+ ConcurrentMap offsetTable1 = new ConcurrentHashMap<>();
+ for (int i = 1; i <= 18; i++) {
+ offsetTable1.put(i, random.nextLong());
+ }
+
+ Field field = scheduleMessageService.getClass().getDeclaredField("offsetTable");
+ field.setAccessible(true);
+ field.set(scheduleMessageService, offsetTable1);
+
+ String jsonStr = scheduleMessageService.encode();
+ scheduleMessageService.decode(jsonStr);
+
+ offsetTable = (ConcurrentMap) field.get(scheduleMessageService);
+
+ for (Map.Entry entry : offsetTable.entrySet()) {
+ assertEquals(entry.getValue(), offsetTable1.get(entry.getKey()));
+ }
+
+ scheduleMessageService.correctDelayOffset();
+
+ offsetTable = (ConcurrentMap) field.get(scheduleMessageService);
+
+ for (long offset : offsetTable.values()) {
+ assertEquals(offset, 0);
+ }
+
+ }
+
+ private MessageStore buildMessageStore() throws Exception {
+ MessageStoreConfig messageStoreConfig = new MessageStoreConfig();
+ messageStoreConfig.setMappedFileSizeCommitLog(1024 * 1024 * 10);
+ messageStoreConfig.setMappedFileSizeConsumeQueue(1024 * 1024 * 10);
+ messageStoreConfig.setMaxHashSlotNum(10000);
+ messageStoreConfig.setMaxIndexNum(100 * 100);
+ messageStoreConfig.setFlushDiskType(FlushDiskType.SYNC_FLUSH);
+ messageStoreConfig.setFlushIntervalConsumeQueue(1);
+ return new DefaultMessageStore(messageStoreConfig, new BrokerStatsManager("simpleTest"), null, new BrokerConfig());
+ }
+}
diff --git a/store/src/test/java/org/apache/rocketmq/store/StoreStatsServiceTest.java b/store/src/test/java/org/apache/rocketmq/store/StoreStatsServiceTest.java
index b8a9970168dc9167da9f7f000f5d19f8d70c4658..6e66a4487b6def207a5d96fb617f52636d0bb28d 100644
--- a/store/src/test/java/org/apache/rocketmq/store/StoreStatsServiceTest.java
+++ b/store/src/test/java/org/apache/rocketmq/store/StoreStatsServiceTest.java
@@ -21,6 +21,8 @@ import java.util.concurrent.CountDownLatch;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.AtomicReference;
+import java.util.concurrent.atomic.LongAdder;
+
import org.junit.Test;
public class StoreStatsServiceTest {
@@ -30,7 +32,7 @@ public class StoreStatsServiceTest {
final StoreStatsService storeStatsService = new StoreStatsService();
int num = Runtime.getRuntime().availableProcessors() * 2;
for (int j = 0; j < 100; j++) {
- final AtomicReference reference = new AtomicReference<>(null);
+ final AtomicReference reference = new AtomicReference<>(null);
final CountDownLatch latch = new CountDownLatch(num);
final CyclicBarrier barrier = new CyclicBarrier(num);
for (int i = 0; i < num; i++) {
@@ -39,9 +41,9 @@ public class StoreStatsServiceTest {
public void run() {
try {
barrier.await();
- AtomicLong atomicLong = storeStatsService.getSinglePutMessageTopicSizeTotal("test");
- if (reference.compareAndSet(null, atomicLong)) {
- } else if (reference.get() != atomicLong) {
+ LongAdder longAdder = storeStatsService.getSinglePutMessageTopicSizeTotal("test");
+ if (reference.compareAndSet(null, longAdder)) {
+ } else if (reference.get() != longAdder) {
throw new RuntimeException("Reference should be same!");
}
} catch (InterruptedException | BrokenBarrierException e) {
@@ -61,7 +63,7 @@ public class StoreStatsServiceTest {
final StoreStatsService storeStatsService = new StoreStatsService();
int num = Runtime.getRuntime().availableProcessors() * 2;
for (int j = 0; j < 100; j++) {
- final AtomicReference reference = new AtomicReference<>(null);
+ final AtomicReference reference = new AtomicReference<>(null);
final CountDownLatch latch = new CountDownLatch(num);
final CyclicBarrier barrier = new CyclicBarrier(num);
for (int i = 0; i < num; i++) {
@@ -70,9 +72,9 @@ public class StoreStatsServiceTest {
public void run() {
try {
barrier.await();
- AtomicLong atomicLong = storeStatsService.getSinglePutMessageTopicTimesTotal("test");
- if (reference.compareAndSet(null, atomicLong)) {
- } else if (reference.get() != atomicLong) {
+ LongAdder longAdder = storeStatsService.getSinglePutMessageTopicTimesTotal("test");
+ if (reference.compareAndSet(null, longAdder)) {
+ } else if (reference.get() != longAdder) {
throw new RuntimeException("Reference should be same!");
}
} catch (InterruptedException | BrokenBarrierException e) {
diff --git a/store/src/test/java/org/apache/rocketmq/store/schedule/ScheduleMessageServiceTest.java b/store/src/test/java/org/apache/rocketmq/store/schedule/ScheduleMessageServiceTest.java
index fa3c6bfcd8b9fd08035d5c7c409a10337f32b8d0..d375fb0c89c084d0f74d61373ce0c75af1f7d277 100644
--- a/store/src/test/java/org/apache/rocketmq/store/schedule/ScheduleMessageServiceTest.java
+++ b/store/src/test/java/org/apache/rocketmq/store/schedule/ScheduleMessageServiceTest.java
@@ -149,9 +149,9 @@ public class ScheduleMessageServiceTest {
assertThat(messageResult.getStatus()).isEqualTo(GetMessageStatus.FOUND);
// get the stats change
- assertThat(messageStore.getBrokerStatsManager().getStatsItem(BROKER_PUT_NUMS, brokerConfig.getBrokerClusterName()).getValue().get()).isEqualTo(1);
- assertThat(messageStore.getBrokerStatsManager().getStatsItem(TOPIC_PUT_NUMS, topic).getValue().get()).isEqualTo(1L);
- assertThat(messageStore.getBrokerStatsManager().getStatsItem(TOPIC_PUT_SIZE, topic).getValue().get()).isEqualTo(messageResult.getBufferTotalSize());
+ assertThat(messageStore.getBrokerStatsManager().getStatsItem(BROKER_PUT_NUMS, brokerConfig.getBrokerClusterName()).getValue().sum()).isEqualTo(1);
+ assertThat(messageStore.getBrokerStatsManager().getStatsItem(TOPIC_PUT_NUMS, topic).getValue().sum()).isEqualTo(1L);
+ assertThat(messageStore.getBrokerStatsManager().getStatsItem(TOPIC_PUT_SIZE, topic).getValue().sum()).isEqualTo(messageResult.getBufferTotalSize());
// get the message body
ByteBuffer byteBuffer = ByteBuffer.allocate(messageResult.getBufferTotalSize());
diff --git a/store/src/test/java/stats/BrokerStatsManagerTest.java b/store/src/test/java/stats/BrokerStatsManagerTest.java
index 17020729a63f89b80656f8d92f7bcdaf7cc12fc9..2b6d0f8b68d6f31619dfe47c1f651b1c59f81b86 100644
--- a/store/src/test/java/stats/BrokerStatsManagerTest.java
+++ b/store/src/test/java/stats/BrokerStatsManagerTest.java
@@ -29,6 +29,10 @@ import static org.apache.rocketmq.store.stats.BrokerStatsManager.GROUP_GET_FALL_
import static org.apache.rocketmq.store.stats.BrokerStatsManager.GROUP_GET_LATENCY;
import static org.apache.rocketmq.store.stats.BrokerStatsManager.GROUP_GET_NUMS;
import static org.apache.rocketmq.store.stats.BrokerStatsManager.GROUP_GET_SIZE;
+import static org.apache.rocketmq.store.stats.BrokerStatsManager.QUEUE_GET_NUMS;
+import static org.apache.rocketmq.store.stats.BrokerStatsManager.QUEUE_GET_SIZE;
+import static org.apache.rocketmq.store.stats.BrokerStatsManager.QUEUE_PUT_NUMS;
+import static org.apache.rocketmq.store.stats.BrokerStatsManager.QUEUE_PUT_SIZE;
import static org.apache.rocketmq.store.stats.BrokerStatsManager.SNDBCK_PUT_NUMS;
import static org.apache.rocketmq.store.stats.BrokerStatsManager.TOPIC_PUT_NUMS;
import static org.apache.rocketmq.store.stats.BrokerStatsManager.TOPIC_PUT_SIZE;
@@ -38,6 +42,7 @@ public class BrokerStatsManagerTest {
private BrokerStatsManager brokerStatsManager;
private String TOPIC = "TOPIC_TEST";
+ private Integer QUEUE_ID = 0;
private String GROUP_NAME = "GROUP_TEST";
@Before
@@ -56,6 +61,36 @@ public class BrokerStatsManagerTest {
assertThat(brokerStatsManager.getStatsItem("TEST", "TEST")).isNull();
}
+ @Test
+ public void testIncQueuePutNums() {
+ brokerStatsManager.incQueuePutNums(TOPIC, QUEUE_ID);
+ String statsKey = brokerStatsManager.buildStatsKey(TOPIC, String.valueOf(QUEUE_ID));
+ assertThat(brokerStatsManager.getStatsItem(QUEUE_PUT_NUMS, statsKey).getTimes().doubleValue()).isEqualTo(1L);
+ brokerStatsManager.incQueuePutNums(TOPIC, QUEUE_ID, 2, 2);
+ assertThat(brokerStatsManager.getStatsItem(QUEUE_PUT_NUMS, statsKey).getValue().doubleValue()).isEqualTo(3L);
+ }
+
+ @Test
+ public void testIncQueuePutSize() {
+ brokerStatsManager.incQueuePutSize(TOPIC, QUEUE_ID, 2);
+ String statsKey = brokerStatsManager.buildStatsKey(TOPIC, String.valueOf(QUEUE_ID));
+ assertThat(brokerStatsManager.getStatsItem(QUEUE_PUT_SIZE, statsKey).getValue().doubleValue()).isEqualTo(2L);
+ }
+
+ @Test
+ public void testIncQueueGetNums() {
+ brokerStatsManager.incQueueGetNums(GROUP_NAME, TOPIC, QUEUE_ID, 1);
+ final String statsKey = brokerStatsManager.buildStatsKey(brokerStatsManager.buildStatsKey(TOPIC, String.valueOf(QUEUE_ID)), GROUP_NAME);
+ assertThat(brokerStatsManager.getStatsItem(QUEUE_GET_NUMS, statsKey).getValue().doubleValue()).isEqualTo(1L);
+ }
+
+ @Test
+ public void testIncQueueGetSize() {
+ brokerStatsManager.incQueueGetSize(GROUP_NAME, TOPIC, QUEUE_ID, 1);
+ final String statsKey = brokerStatsManager.buildStatsKey(brokerStatsManager.buildStatsKey(TOPIC, String.valueOf(QUEUE_ID)), GROUP_NAME);
+ assertThat(brokerStatsManager.getStatsItem(QUEUE_GET_SIZE, statsKey).getValue().doubleValue()).isEqualTo(1L);
+ }
+
@Test
public void testIncTopicPutNums() {
brokerStatsManager.incTopicPutNums(TOPIC);
@@ -101,8 +136,12 @@ public class BrokerStatsManagerTest {
public void testOnTopicDeleted() {
brokerStatsManager.incTopicPutNums(TOPIC);
brokerStatsManager.incTopicPutSize(TOPIC, 100);
+ brokerStatsManager.incQueuePutNums(TOPIC, QUEUE_ID);
+ brokerStatsManager.incQueuePutSize(TOPIC, QUEUE_ID, 100);
brokerStatsManager.incGroupGetNums(GROUP_NAME, TOPIC, 1);
brokerStatsManager.incGroupGetSize(GROUP_NAME, TOPIC, 100);
+ brokerStatsManager.incQueueGetNums(GROUP_NAME, TOPIC, QUEUE_ID, 1);
+ brokerStatsManager.incQueueGetSize(GROUP_NAME, TOPIC, QUEUE_ID, 100);
brokerStatsManager.incSendBackNums(GROUP_NAME, TOPIC);
brokerStatsManager.incGroupGetLatency(GROUP_NAME, TOPIC, 1, 1);
brokerStatsManager.recordDiskFallBehindTime(GROUP_NAME, TOPIC, 1, 11L);
@@ -112,8 +151,12 @@ public class BrokerStatsManagerTest {
Assert.assertNull(brokerStatsManager.getStatsItem(TOPIC_PUT_NUMS, TOPIC));
Assert.assertNull(brokerStatsManager.getStatsItem(TOPIC_PUT_SIZE, TOPIC));
+ Assert.assertNull(brokerStatsManager.getStatsItem(QUEUE_PUT_NUMS, TOPIC + "@" + QUEUE_ID));
+ Assert.assertNull(brokerStatsManager.getStatsItem(QUEUE_PUT_SIZE, TOPIC + "@" + QUEUE_ID));
Assert.assertNull(brokerStatsManager.getStatsItem(GROUP_GET_SIZE, TOPIC + "@" + GROUP_NAME));
Assert.assertNull(brokerStatsManager.getStatsItem(GROUP_GET_NUMS, TOPIC + "@" + GROUP_NAME));
+ Assert.assertNull(brokerStatsManager.getStatsItem(QUEUE_GET_SIZE, TOPIC + "@" + QUEUE_ID + "@" + GROUP_NAME));
+ Assert.assertNull(brokerStatsManager.getStatsItem(QUEUE_GET_NUMS, TOPIC + "@" + QUEUE_ID + "@" + GROUP_NAME));
Assert.assertNull(brokerStatsManager.getStatsItem(SNDBCK_PUT_NUMS, TOPIC + "@" + GROUP_NAME));
Assert.assertNull(brokerStatsManager.getStatsItem(GROUP_GET_LATENCY, "1@" + TOPIC + "@" + GROUP_NAME));
Assert.assertNull(brokerStatsManager.getStatsItem(GROUP_GET_FALL_SIZE, "1@" + TOPIC + "@" + GROUP_NAME));
@@ -124,6 +167,8 @@ public class BrokerStatsManagerTest {
public void testOnGroupDeleted(){
brokerStatsManager.incGroupGetNums(GROUP_NAME, TOPIC, 1);
brokerStatsManager.incGroupGetSize(GROUP_NAME, TOPIC, 100);
+ brokerStatsManager.incQueueGetNums(GROUP_NAME, TOPIC, QUEUE_ID, 1);
+ brokerStatsManager.incQueueGetSize(GROUP_NAME, TOPIC, QUEUE_ID, 100);
brokerStatsManager.incSendBackNums(GROUP_NAME, TOPIC);
brokerStatsManager.incGroupGetLatency(GROUP_NAME, TOPIC, 1, 1);
brokerStatsManager.recordDiskFallBehindTime(GROUP_NAME, TOPIC, 1, 11L);
@@ -133,6 +178,8 @@ public class BrokerStatsManagerTest {
Assert.assertNull(brokerStatsManager.getStatsItem(GROUP_GET_SIZE, TOPIC + "@" + GROUP_NAME));
Assert.assertNull(brokerStatsManager.getStatsItem(GROUP_GET_NUMS, TOPIC + "@" + GROUP_NAME));
+ Assert.assertNull(brokerStatsManager.getStatsItem(QUEUE_GET_SIZE, TOPIC + "@" + QUEUE_ID + "@" + GROUP_NAME));
+ Assert.assertNull(brokerStatsManager.getStatsItem(QUEUE_GET_NUMS, TOPIC + "@" + QUEUE_ID + "@" + GROUP_NAME));
Assert.assertNull(brokerStatsManager.getStatsItem(SNDBCK_PUT_NUMS, TOPIC + "@" + GROUP_NAME));
Assert.assertNull(brokerStatsManager.getStatsItem(GROUP_GET_LATENCY, "1@" + TOPIC + "@" + GROUP_NAME));
Assert.assertNull(brokerStatsManager.getStatsItem(GROUP_GET_FALL_SIZE, "1@" + TOPIC + "@" + GROUP_NAME));
diff --git a/test/pom.xml b/test/pom.xml
index 83e0e337055233763a780759bf37ebac8a3f0dc9..93ff590cb0bc4fd275cdb08704d7a27968b8ce00 100644
--- a/test/pom.xml
+++ b/test/pom.xml
@@ -20,7 +20,7 @@
rocketmq-all
org.apache.rocketmq
- 4.9.2-SNAPSHOT
+ 4.9.3-SNAPSHOT
4.0.0
diff --git a/tools/pom.xml b/tools/pom.xml
index ffab7442e50e01e6019bebfe7a5bae94b9f3fbe7..3eda8523c0c6a19560ac97635dd18bcdbfa5d98f 100644
--- a/tools/pom.xml
+++ b/tools/pom.xml
@@ -19,7 +19,7 @@
org.apache.rocketmq
rocketmq-all
- 4.9.2-SNAPSHOT
+ 4.9.3-SNAPSHOT
4.0.0
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 6592639035f922a362f7503342d34f7ff06ac11b..c3e3a30d6bf29d51e23512586a7ee72ac770aed6 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
@@ -203,12 +203,13 @@ public class DefaultMQAdminExt extends ClientConfig implements MQAdminExt {
}
@Override
- public SubscriptionGroupConfig examineSubscriptionGroupConfig(String addr, String group) {
+ public SubscriptionGroupConfig examineSubscriptionGroupConfig(String addr, String group)
+ throws InterruptedException, RemotingException, MQClientException, MQBrokerException {
return defaultMQAdminExtImpl.examineSubscriptionGroupConfig(addr, group);
}
@Override
- public TopicConfig examineTopicConfig(String addr, String topic) {
+ public TopicConfig examineTopicConfig(String addr, String topic) throws RemotingException, InterruptedException, MQBrokerException {
return defaultMQAdminExtImpl.examineTopicConfig(addr, topic);
}
@@ -288,6 +289,11 @@ public class DefaultMQAdminExt extends ClientConfig implements MQAdminExt {
return defaultMQAdminExtImpl.wipeWritePermOfBroker(namesrvAddr, brokerName);
}
+ @Override
+ public int addWritePermOfBroker(String namesrvAddr, String brokerName) throws RemotingCommandException, RemotingConnectException, RemotingSendRequestException, RemotingTimeoutException, InterruptedException, MQClientException {
+ return defaultMQAdminExtImpl.addWritePermOfBroker(namesrvAddr, brokerName);
+ }
+
@Override
public void putKVConfig(String namespace, String key, String value) {
defaultMQAdminExtImpl.putKVConfig(namespace, key, value);
@@ -495,10 +501,24 @@ public class DefaultMQAdminExt extends ClientConfig implements MQAdminExt {
}
@Override
- public TopicConfigSerializeWrapper getAllTopicGroup(final String brokerAddr,
+ public SubscriptionGroupWrapper getUserSubscriptionGroup(final String brokerAddr,
long timeoutMillis) throws InterruptedException, RemotingTimeoutException, RemotingSendRequestException,
RemotingConnectException, MQBrokerException {
- return this.defaultMQAdminExtImpl.getAllTopicGroup(brokerAddr, timeoutMillis);
+ return this.defaultMQAdminExtImpl.getUserSubscriptionGroup(brokerAddr, timeoutMillis);
+ }
+
+ @Override
+ public TopicConfigSerializeWrapper getAllTopicConfig(final String brokerAddr,
+ long timeoutMillis) throws InterruptedException, RemotingTimeoutException, RemotingSendRequestException,
+ RemotingConnectException, MQBrokerException {
+ return this.defaultMQAdminExtImpl.getAllTopicConfig(brokerAddr, timeoutMillis);
+ }
+
+ @Override
+ public TopicConfigSerializeWrapper getUserTopicConfig(final String brokerAddr, final boolean specialTopic,
+ long timeoutMillis) throws InterruptedException, RemotingException,
+ MQBrokerException, MQClientException {
+ return this.defaultMQAdminExtImpl.getUserTopicConfig(brokerAddr, specialTopic, timeoutMillis);
}
/* (non-Javadoc)
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 8930bbe49d207ab2dc361caaee6d88f75762cbea..80999c24249758a6a5c350005e5497949b8fcbaa 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
@@ -99,6 +99,24 @@ public class DefaultMQAdminExtImpl implements MQAdminExt, MQAdminExtInner {
private long timeoutMillis = 20000;
private Random random = new Random();
+ private static final Set SYSTEM_GROUP_SET = new HashSet();
+
+ static {
+ SYSTEM_GROUP_SET.add(MixAll.DEFAULT_CONSUMER_GROUP);
+ SYSTEM_GROUP_SET.add(MixAll.DEFAULT_PRODUCER_GROUP);
+ SYSTEM_GROUP_SET.add(MixAll.TOOLS_CONSUMER_GROUP);
+ SYSTEM_GROUP_SET.add(MixAll.FILTERSRV_CONSUMER_GROUP);
+ SYSTEM_GROUP_SET.add(MixAll.MONITOR_CONSUMER_GROUP);
+ SYSTEM_GROUP_SET.add(MixAll.CLIENT_INNER_PRODUCER_GROUP);
+ SYSTEM_GROUP_SET.add(MixAll.SELF_TEST_PRODUCER_GROUP);
+ SYSTEM_GROUP_SET.add(MixAll.SELF_TEST_CONSUMER_GROUP);
+ SYSTEM_GROUP_SET.add(MixAll.ONS_HTTP_PROXY_GROUP);
+ SYSTEM_GROUP_SET.add(MixAll.CID_ONSAPI_PERMISSION_GROUP);
+ SYSTEM_GROUP_SET.add(MixAll.CID_ONSAPI_OWNER_GROUP);
+ SYSTEM_GROUP_SET.add(MixAll.CID_ONSAPI_PULL_GROUP);
+ SYSTEM_GROUP_SET.add(MixAll.CID_SYS_RMQ_TRANS);
+ }
+
public DefaultMQAdminExtImpl(DefaultMQAdminExt defaultMQAdminExt, long timeoutMillis) {
this(defaultMQAdminExt, null, timeoutMillis);
}
@@ -217,13 +235,16 @@ public class DefaultMQAdminExtImpl implements MQAdminExt, MQAdminExtInner {
}
@Override
- public SubscriptionGroupConfig examineSubscriptionGroupConfig(String addr, String group) {
- return null;
+ public SubscriptionGroupConfig examineSubscriptionGroupConfig(String addr, String group)
+ throws InterruptedException, RemotingException, MQClientException, MQBrokerException {
+ SubscriptionGroupWrapper wrapper = this.mqClientInstance.getMQClientAPIImpl().getAllSubscriptionGroup(addr, timeoutMillis);
+ return wrapper.getSubscriptionGroupTable().get(group);
}
@Override
- public TopicConfig examineTopicConfig(String addr, String topic) {
- return null;
+ public TopicConfig examineTopicConfig(String addr, String topic) throws RemotingException, InterruptedException, MQBrokerException {
+ TopicConfigSerializeWrapper topicConfigSerializeWrapper = this.mqClientInstance.getMQClientAPIImpl().getAllTopicConfig(addr,timeoutMillis);
+ return topicConfigSerializeWrapper.getTopicConfigTable().get(topic);
}
@Override
@@ -382,6 +403,12 @@ public class DefaultMQAdminExtImpl implements MQAdminExt, MQAdminExtInner {
return this.mqClientInstance.getMQClientAPIImpl().wipeWritePermOfBroker(namesrvAddr, brokerName, timeoutMillis);
}
+ @Override
+ public int addWritePermOfBroker(String namesrvAddr, String brokerName) throws RemotingCommandException,
+ RemotingConnectException, RemotingSendRequestException, RemotingTimeoutException, InterruptedException, MQClientException {
+ return this.mqClientInstance.getMQClientAPIImpl().addWritePermOfBroker(namesrvAddr, brokerName, timeoutMillis);
+ }
+
@Override
public void putKVConfig(String namespace, String key, String value) {
}
@@ -880,7 +907,7 @@ public class DefaultMQAdminExtImpl implements MQAdminExt, MQAdminExtInner {
if (mq.getTopic().equals(msg.getTopic()) && mq.getQueueId() == msg.getQueueId()) {
BrokerData brokerData = ci.getBrokerAddrTable().get(mq.getBrokerName());
if (brokerData != null) {
- String addr = brokerData.getBrokerAddrs().get(MixAll.MASTER_ID);
+ String addr = RemotingUtil.convert2IpString(brokerData.getBrokerAddrs().get(MixAll.MASTER_ID));
if (RemotingUtil.socketAddress2String(msg.getStoreHost()).equals(addr)) {
if (next.getValue().getConsumerOffset() > msg.getQueueOffset()) {
return true;
@@ -955,12 +982,49 @@ public class DefaultMQAdminExtImpl implements MQAdminExt, MQAdminExtInner {
}
@Override
- public TopicConfigSerializeWrapper getAllTopicGroup(final String brokerAddr,
+ public SubscriptionGroupWrapper getUserSubscriptionGroup(final String brokerAddr,
+ long timeoutMillis) throws InterruptedException,
+ RemotingTimeoutException, RemotingSendRequestException, RemotingConnectException, MQBrokerException {
+ SubscriptionGroupWrapper subscriptionGroupWrapper = this.mqClientInstance.getMQClientAPIImpl()
+ .getAllSubscriptionGroup(brokerAddr, timeoutMillis);
+
+ Iterator> iterator = subscriptionGroupWrapper.getSubscriptionGroupTable()
+ .entrySet().iterator();
+ while (iterator.hasNext()) {
+ Map.Entry configEntry = iterator.next();
+ if (MixAll.isSysConsumerGroup(configEntry.getKey()) || SYSTEM_GROUP_SET.contains(configEntry.getKey())) {
+ iterator.remove();
+ }
+ }
+
+ return subscriptionGroupWrapper;
+ }
+
+ @Override
+ public TopicConfigSerializeWrapper getAllTopicConfig(final String brokerAddr,
long timeoutMillis) throws InterruptedException,
RemotingTimeoutException, RemotingSendRequestException, RemotingConnectException, MQBrokerException {
return this.mqClientInstance.getMQClientAPIImpl().getAllTopicConfig(brokerAddr, timeoutMillis);
}
+ @Override
+ public TopicConfigSerializeWrapper getUserTopicConfig(final String brokerAddr, final boolean specialTopic,
+ long timeoutMillis) throws InterruptedException, RemotingException,
+ MQBrokerException, MQClientException {
+ TopicConfigSerializeWrapper topicConfigSerializeWrapper = this.getAllTopicConfig(brokerAddr, timeoutMillis);
+ TopicList topicList = this.mqClientInstance.getMQClientAPIImpl().getSystemTopicListFromBroker(brokerAddr,
+ timeoutMillis);
+ Iterator> iterator = topicConfigSerializeWrapper.getTopicConfigTable().entrySet()
+ .iterator();
+ while (iterator.hasNext()) {
+ String topic = iterator.next().getKey();
+ if (topicList.getTopicList().contains(topic) || (!specialTopic && (topic.startsWith(MixAll.RETRY_GROUP_TOPIC_PREFIX) || topic.startsWith(MixAll.DLQ_GROUP_TOPIC_PREFIX)))) {
+ iterator.remove();
+ }
+ }
+ return topicConfigSerializeWrapper;
+ }
+
@Override
public void createTopic(String key, String newTopic, int queueNum) throws MQClientException {
createTopic(key, newTopic, queueNum, 0);
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 d5462cb04e5a41873690c10cf67b880e21ad6bd1..82c1cbd30d27e059839ddecae6c850fb9375e66f 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
@@ -90,9 +90,9 @@ public interface MQAdminExt extends MQAdmin {
final SubscriptionGroupConfig config) throws RemotingException,
MQBrokerException, InterruptedException, MQClientException;
- SubscriptionGroupConfig examineSubscriptionGroupConfig(final String addr, final String group);
+ SubscriptionGroupConfig examineSubscriptionGroupConfig(final String addr, final String group) throws InterruptedException, RemotingException, MQClientException, MQBrokerException;
- TopicConfig examineTopicConfig(final String addr, final String topic);
+ TopicConfig examineTopicConfig(final String addr, final String topic) throws RemotingException, InterruptedException, MQBrokerException;
TopicStatsTable examineTopicStats(
final String topic) throws RemotingException, MQClientException, InterruptedException,
@@ -134,6 +134,9 @@ public interface MQAdminExt extends MQAdmin {
int wipeWritePermOfBroker(final String namesrvAddr, String brokerName) throws RemotingCommandException,
RemotingConnectException, RemotingSendRequestException, RemotingTimeoutException, InterruptedException, MQClientException;
+ int addWritePermOfBroker(final String namesrvAddr, String brokerName) throws RemotingCommandException,
+ RemotingConnectException, RemotingSendRequestException, RemotingTimeoutException, InterruptedException, MQClientException;
+
void putKVConfig(final String namespace, final String key, final String value);
String getKVConfig(final String namespace,
@@ -235,10 +238,18 @@ public interface MQAdminExt extends MQAdmin {
long timeoutMillis) throws InterruptedException, RemotingTimeoutException, RemotingSendRequestException,
RemotingConnectException, MQBrokerException;
- TopicConfigSerializeWrapper getAllTopicGroup(final String brokerAddr,
+ SubscriptionGroupWrapper getUserSubscriptionGroup(final String brokerAddr,
long timeoutMillis) throws InterruptedException, RemotingTimeoutException, RemotingSendRequestException,
RemotingConnectException, MQBrokerException;
+ TopicConfigSerializeWrapper getAllTopicConfig(final String brokerAddr,
+ long timeoutMillis) throws InterruptedException, RemotingTimeoutException, RemotingSendRequestException,
+ RemotingConnectException, MQBrokerException;
+
+ TopicConfigSerializeWrapper getUserTopicConfig(final String brokerAddr, final boolean specialTopic,
+ long timeoutMillis) throws InterruptedException, RemotingException,
+ MQBrokerException, MQClientException;
+
void updateConsumeOffset(String brokerAddr, String consumeGroup, MessageQueue mq,
long offset) throws RemotingException, InterruptedException, MQBrokerException;
diff --git a/tools/src/main/java/org/apache/rocketmq/tools/command/CommandUtil.java b/tools/src/main/java/org/apache/rocketmq/tools/command/CommandUtil.java
index 2e65f980848a9ef553dc5ec593ad4ef68cde1b6b..8984ca67b2029350e434d0214c2f5358058a28db 100644
--- a/tools/src/main/java/org/apache/rocketmq/tools/command/CommandUtil.java
+++ b/tools/src/main/java/org/apache/rocketmq/tools/command/CommandUtil.java
@@ -146,5 +146,4 @@ public class CommandUtil {
}
throw new Exception(ERROR_MESSAGE);
}
-
}
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 f9477445bea3d895dd9f52a0c7f7a1127ee95d67..e8572bd7b168d254214b13a2db7094929694f4b4 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
@@ -49,8 +49,11 @@ import org.apache.rocketmq.tools.command.connection.ProducerConnectionSubCommand
import org.apache.rocketmq.tools.command.consumer.ConsumerProgressSubCommand;
import org.apache.rocketmq.tools.command.consumer.ConsumerStatusSubCommand;
import org.apache.rocketmq.tools.command.consumer.DeleteSubscriptionGroupCommand;
+import org.apache.rocketmq.tools.command.consumer.GetConsumerConfigSubCommand;
import org.apache.rocketmq.tools.command.consumer.StartMonitoringSubCommand;
import org.apache.rocketmq.tools.command.consumer.UpdateSubGroupSubCommand;
+import org.apache.rocketmq.tools.command.export.ExportMetricsCommand;
+import org.apache.rocketmq.tools.command.export.ExportConfigsCommand;
import org.apache.rocketmq.tools.command.message.CheckMsgSendRTCommand;
import org.apache.rocketmq.tools.command.message.ConsumeMessageCommand;
import org.apache.rocketmq.tools.command.message.PrintMessageByQueueCommand;
@@ -61,6 +64,7 @@ import org.apache.rocketmq.tools.command.message.QueryMsgByOffsetSubCommand;
import org.apache.rocketmq.tools.command.message.QueryMsgByUniqueKeySubCommand;
import org.apache.rocketmq.tools.command.message.QueryMsgTraceByIdSubCommand;
import org.apache.rocketmq.tools.command.message.SendMessageCommand;
+import org.apache.rocketmq.tools.command.namesrv.AddWritePermSubCommand;
import org.apache.rocketmq.tools.command.namesrv.DeleteKvConfigCommand;
import org.apache.rocketmq.tools.command.namesrv.GetNamesrvConfigCommand;
import org.apache.rocketmq.tools.command.namesrv.UpdateKvConfigCommand;
@@ -72,6 +76,7 @@ import org.apache.rocketmq.tools.command.queue.QueryConsumeQueueCommand;
import org.apache.rocketmq.tools.command.stats.StatsAllSubCommand;
import org.apache.rocketmq.tools.command.topic.AllocateMQSubCommand;
import org.apache.rocketmq.tools.command.topic.DeleteTopicSubCommand;
+import org.apache.rocketmq.tools.command.export.ExportMetadataCommand;
import org.apache.rocketmq.tools.command.topic.TopicClusterSubCommand;
import org.apache.rocketmq.tools.command.topic.TopicListSubCommand;
import org.apache.rocketmq.tools.command.topic.TopicRouteSubCommand;
@@ -185,6 +190,7 @@ public class MQAdminStartup {
initCommand(new DeleteKvConfigCommand());
initCommand(new WipeWritePermSubCommand());
+ initCommand(new AddWritePermSubCommand());
initCommand(new ResetOffsetByTimeCommand());
initCommand(new UpdateOrderConfCommand());
@@ -202,6 +208,7 @@ public class MQAdminStartup {
initCommand(new GetNamesrvConfigCommand());
initCommand(new UpdateNamesrvConfigCommand());
initCommand(new GetBrokerConfigCommand());
+ initCommand(new GetConsumerConfigSubCommand());
initCommand(new QueryConsumeQueueCommand());
initCommand(new SendMessageCommand());
@@ -213,6 +220,10 @@ public class MQAdminStartup {
initCommand(new ClusterAclConfigVersionListSubCommand());
initCommand(new UpdateGlobalWhiteAddrSubCommand());
initCommand(new GetAccessConfigSubCommand());
+
+ initCommand(new ExportMetadataCommand());
+ initCommand(new ExportConfigsCommand());
+ initCommand(new ExportMetricsCommand());
}
private static void initLogback() throws JoranException {
diff --git a/tools/src/main/java/org/apache/rocketmq/tools/command/acl/DeleteAccessConfigSubCommand.java b/tools/src/main/java/org/apache/rocketmq/tools/command/acl/DeleteAccessConfigSubCommand.java
index d82453dc9ff72d031dcbb2fcbc561da9b27fe9bb..4e7cd9344c8c3c44df02aba204a9e9925adcee6d 100644
--- a/tools/src/main/java/org/apache/rocketmq/tools/command/acl/DeleteAccessConfigSubCommand.java
+++ b/tools/src/main/java/org/apache/rocketmq/tools/command/acl/DeleteAccessConfigSubCommand.java
@@ -85,9 +85,9 @@ public class DeleteAccessConfigSubCommand implements SubCommand {
defaultMQAdminExt.start();
- Set masterSet =
- CommandUtil.fetchMasterAddrByClusterName(defaultMQAdminExt, clusterName);
- for (String addr : masterSet) {
+ Set brokerAddrSet =
+ CommandUtil.fetchMasterAndSlaveAddrByClusterName(defaultMQAdminExt, clusterName);
+ for (String addr : brokerAddrSet) {
defaultMQAdminExt.deletePlainAccessConfig(addr, accessKey);
System.out.printf("delete plain access config account from %s success.%n", addr);
}
diff --git a/tools/src/main/java/org/apache/rocketmq/tools/command/acl/UpdateGlobalWhiteAddrSubCommand.java b/tools/src/main/java/org/apache/rocketmq/tools/command/acl/UpdateGlobalWhiteAddrSubCommand.java
index ef9d9407ced92504947f546f4e6dd88ecf3311f8..efd39e9f2593d4c4e35909868dc4644e3e70555b 100644
--- a/tools/src/main/java/org/apache/rocketmq/tools/command/acl/UpdateGlobalWhiteAddrSubCommand.java
+++ b/tools/src/main/java/org/apache/rocketmq/tools/command/acl/UpdateGlobalWhiteAddrSubCommand.java
@@ -82,9 +82,9 @@ public class UpdateGlobalWhiteAddrSubCommand implements SubCommand {
String clusterName = commandLine.getOptionValue('c').trim();
defaultMQAdminExt.start();
- Set masterSet =
- CommandUtil.fetchMasterAddrByClusterName(defaultMQAdminExt, clusterName);
- for (String addr : masterSet) {
+ Set brokerAddrSet =
+ CommandUtil.fetchMasterAndSlaveAddrByClusterName(defaultMQAdminExt, clusterName);
+ for (String addr : brokerAddrSet) {
defaultMQAdminExt.updateGlobalWhiteAddrConfig(addr, globalWhiteRemoteAddresses);
System.out.printf("update global white remote addresses to %s success.%n", addr);
}
diff --git a/tools/src/main/java/org/apache/rocketmq/tools/command/consumer/GetConsumerConfigSubCommand.java b/tools/src/main/java/org/apache/rocketmq/tools/command/consumer/GetConsumerConfigSubCommand.java
new file mode 100644
index 0000000000000000000000000000000000000000..be2b9466881b77976f33dc7912138ce53ba15cd4
--- /dev/null
+++ b/tools/src/main/java/org/apache/rocketmq/tools/command/consumer/GetConsumerConfigSubCommand.java
@@ -0,0 +1,146 @@
+/*
+ * 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.consumer;
+
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.rocketmq.common.protocol.body.ClusterInfo;
+import org.apache.rocketmq.common.subscription.SubscriptionGroupConfig;
+import org.apache.rocketmq.remoting.RPCHook;
+import org.apache.rocketmq.tools.admin.DefaultMQAdminExt;
+import org.apache.rocketmq.tools.command.SubCommand;
+import org.apache.rocketmq.tools.command.SubCommandException;
+
+public class GetConsumerConfigSubCommand implements SubCommand {
+
+ @Override
+ public String commandName() {
+ return "getConsumerConfig";
+ }
+
+ @Override
+ public String commandDesc() {
+ return "Get consumer config by subscription group name!";
+ }
+
+ @Override
+ public Options buildCommandlineOptions(final Options options) {
+ Option opt = new Option("g", "groupName", true, "subscription group name");
+ opt.setRequired(true);
+ options.addOption(opt);
+ return options;
+ }
+
+ @Override
+ public void execute(CommandLine commandLine, Options options,
+ RPCHook rpcHook) throws SubCommandException {
+ DefaultMQAdminExt adminExt = new DefaultMQAdminExt(rpcHook);
+ adminExt.setInstanceName(Long.toString(System.currentTimeMillis()));
+ String groupName = commandLine.getOptionValue('g').trim();
+ try {
+ adminExt.start();
+ List consumerConfigInfoList = new ArrayList<>();
+ ClusterInfo clusterInfo = adminExt.examineBrokerClusterInfo();
+ Map> clusterAddrTable = clusterInfo.getClusterAddrTable();
+ for (String brokerName : clusterInfo.getBrokerAddrTable().keySet()) {
+ String clusterName = this.getClusterName(brokerName, clusterAddrTable);
+ String brokerAddress = clusterInfo.getBrokerAddrTable().get(brokerName).selectBrokerAddr();
+ SubscriptionGroupConfig subscriptionGroupConfig = adminExt.examineSubscriptionGroupConfig(brokerAddress, groupName);
+ if (subscriptionGroupConfig == null) {
+ continue;
+ }
+ consumerConfigInfoList.add(new ConsumerConfigInfo(clusterName, brokerName, subscriptionGroupConfig));
+ }
+ if (CollectionUtils.isEmpty(consumerConfigInfoList)) {
+ return;
+ }
+ for (ConsumerConfigInfo info : consumerConfigInfoList) {
+ System.out.printf("=============================%s:%s=============================\n",
+ info.getClusterName(), info.getBrokerName());
+ SubscriptionGroupConfig config = info.getSubscriptionGroupConfig();
+ Field[] fields = config.getClass().getDeclaredFields();
+ for (Field field : fields) {
+ field.setAccessible(true);
+ if (field.get(config) != null) {
+ System.out.printf("%s%-40s= %s\n", "", field.getName(), field.get(config).toString());
+ } else {
+ System.out.printf("%s%-40s= %s\n", "", field.getName(), "");
+ }
+ }
+ }
+ } catch (Exception e) {
+ throw new SubCommandException(this.getClass().getSimpleName() + " command failed", e);
+ } finally {
+ adminExt.shutdown();
+ }
+ }
+
+ private String getClusterName(String brokeName, Map> clusterAddrTable) {
+ for (Map.Entry> entry : clusterAddrTable.entrySet()) {
+ Set brokerNameSet = entry.getValue();
+ if (brokerNameSet.contains(brokeName)) {
+ return entry.getKey();
+ }
+ }
+ return null;
+ }
+}
+
+class ConsumerConfigInfo {
+ private String clusterName;
+
+ private String brokerName;
+
+ private SubscriptionGroupConfig subscriptionGroupConfig;
+
+ public ConsumerConfigInfo(String clusterName, String brokerName, SubscriptionGroupConfig subscriptionGroupConfig) {
+ this.clusterName = clusterName;
+ this.brokerName = brokerName;
+ this.subscriptionGroupConfig = subscriptionGroupConfig;
+ }
+
+ public String getClusterName() {
+ return clusterName;
+ }
+
+ public void setClusterName(String clusterName) {
+ this.clusterName = clusterName;
+ }
+
+ public String getBrokerName() {
+ return brokerName;
+ }
+
+ public void setBrokerName(String brokerNameList) {
+ this.brokerName = brokerName;
+ }
+
+ public SubscriptionGroupConfig getSubscriptionGroupConfig() {
+ return subscriptionGroupConfig;
+ }
+
+ public void setSubscriptionGroupConfig(SubscriptionGroupConfig subscriptionGroupConfig) {
+ this.subscriptionGroupConfig = subscriptionGroupConfig;
+ }
+}
diff --git a/tools/src/main/java/org/apache/rocketmq/tools/command/export/ExportConfigsCommand.java b/tools/src/main/java/org/apache/rocketmq/tools/command/export/ExportConfigsCommand.java
new file mode 100644
index 0000000000000000000000000000000000000000..c3ca9d31902c02bfdf19cc3cc1668dc0ec745096
--- /dev/null
+++ b/tools/src/main/java/org/apache/rocketmq/tools/command/export/ExportConfigsCommand.java
@@ -0,0 +1,128 @@
+/*
+ * 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.export;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
+import com.alibaba.fastjson.JSON;
+
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+import org.apache.rocketmq.common.MixAll;
+import org.apache.rocketmq.remoting.RPCHook;
+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 ExportConfigsCommand implements SubCommand {
+ @Override
+ public String commandName() {
+ return "exportConfigs";
+ }
+
+ @Override
+ public String commandDesc() {
+ return "export configs";
+ }
+
+ @Override
+ public Options buildCommandlineOptions(Options options) {
+ Option opt = new Option("c", "clusterName", true, "choose a cluster to export");
+ opt.setRequired(true);
+ options.addOption(opt);
+
+ opt = new Option("f", "filePath", true,
+ "export configs.json path | default /tmp/rocketmq/export");
+ opt.setRequired(false);
+ options.addOption(opt);
+ return options;
+ }
+
+ @Override
+ public void execute(CommandLine commandLine, Options options, RPCHook rpcHook)
+ throws SubCommandException {
+ DefaultMQAdminExt defaultMQAdminExt = new DefaultMQAdminExt(rpcHook);
+ defaultMQAdminExt.setInstanceName(Long.toString(System.currentTimeMillis()));
+
+ try {
+ String clusterName = commandLine.getOptionValue('c').trim();
+ String filePath = !commandLine.hasOption('f') ? "/tmp/rocketmq/export" : commandLine.getOptionValue('f')
+ .trim();
+
+ defaultMQAdminExt.start();
+ Map result = new HashMap<>();
+ // name servers
+ List nameServerAddressList = defaultMQAdminExt.getNameServerAddressList();
+
+ //broker
+ int masterBrokerSize = 0;
+ int slaveBrokerSize = 0;
+ Map brokerConfigs = new HashMap<>();
+ Map> masterAndSlaveMap
+ = CommandUtil.fetchMasterAndSlaveDistinguish(defaultMQAdminExt, clusterName);
+ for (String masterAddr : masterAndSlaveMap.keySet()) {
+ Properties masterProperties = defaultMQAdminExt.getBrokerConfig(masterAddr);
+ masterBrokerSize++;
+ slaveBrokerSize += masterAndSlaveMap.get(masterAddr).size();
+
+ brokerConfigs.put(masterProperties.getProperty("brokerName"), needBrokerProprties(masterProperties));
+ }
+
+ Map clusterScaleMap = new HashMap<>();
+ clusterScaleMap.put("namesrvSize", nameServerAddressList.size());
+ clusterScaleMap.put("masterBrokerSize", masterBrokerSize);
+ clusterScaleMap.put("slaveBrokerSize", slaveBrokerSize);
+
+ result.put("brokerConfigs", brokerConfigs);
+ result.put("clusterScale", clusterScaleMap);
+
+ String path = filePath + "/configs.json";
+ MixAll.string2FileNotSafe(JSON.toJSONString(result, true), path);
+ System.out.printf("export %s success", path);
+ } catch (Exception e) {
+ throw new SubCommandException(this.getClass().getSimpleName() + " command failed", e);
+ } finally {
+ defaultMQAdminExt.shutdown();
+ }
+ }
+
+ private Properties needBrokerProprties(Properties properties) {
+ Properties newProperties = new Properties();
+ newProperties.setProperty("brokerClusterName", properties.getProperty("brokerClusterName"));
+ newProperties.setProperty("brokerId", properties.getProperty("brokerId"));
+ newProperties.setProperty("brokerName", properties.getProperty("brokerName"));
+ newProperties.setProperty("brokerRole", properties.getProperty("brokerRole"));
+ newProperties.setProperty("fileReservedTime", properties.getProperty("fileReservedTime"));
+ newProperties.setProperty("filterServerNums", properties.getProperty("filterServerNums"));
+ newProperties.setProperty("flushDiskType", properties.getProperty("flushDiskType"));
+ newProperties.setProperty("maxMessageSize", properties.getProperty("maxMessageSize"));
+ newProperties.setProperty("messageDelayLevel", properties.getProperty("messageDelayLevel"));
+ newProperties.setProperty("msgTraceTopicName", properties.getProperty("msgTraceTopicName"));
+ newProperties.setProperty("slaveReadEnable", properties.getProperty("slaveReadEnable"));
+ newProperties.setProperty("traceOn", properties.getProperty("traceOn"));
+ newProperties.setProperty("traceTopicEnable", properties.getProperty("traceTopicEnable"));
+ newProperties.setProperty("useTLS", properties.getProperty("useTLS"));
+ newProperties.setProperty("autoCreateTopicEnable", properties.getProperty("autoCreateTopicEnable"));
+ newProperties.setProperty("autoCreateSubscriptionGroup", properties.getProperty("autoCreateSubscriptionGroup"));
+ return newProperties;
+ }
+}
diff --git a/tools/src/main/java/org/apache/rocketmq/tools/command/export/ExportMetadataCommand.java b/tools/src/main/java/org/apache/rocketmq/tools/command/export/ExportMetadataCommand.java
new file mode 100644
index 0000000000000000000000000000000000000000..1909436467b05655e3a474f1f675e136749b3eab
--- /dev/null
+++ b/tools/src/main/java/org/apache/rocketmq/tools/command/export/ExportMetadataCommand.java
@@ -0,0 +1,184 @@
+/*
+ * 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.export;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+import com.alibaba.fastjson.JSON;
+
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+import org.apache.rocketmq.common.MQVersion;
+import org.apache.rocketmq.common.MixAll;
+import org.apache.rocketmq.common.TopicConfig;
+import org.apache.rocketmq.common.protocol.body.SubscriptionGroupWrapper;
+import org.apache.rocketmq.common.protocol.body.TopicConfigSerializeWrapper;
+import org.apache.rocketmq.common.subscription.SubscriptionGroupConfig;
+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 ExportMetadataCommand implements SubCommand {
+
+ private static final String DEFAULT_FILE_PATH = "/tmp/rocketmq/export";
+
+ @Override
+ public String commandName() {
+ return "exportMetadata";
+ }
+
+ @Override
+ public String commandDesc() {
+ return "export metadata";
+ }
+
+ @Override
+ public Options buildCommandlineOptions(Options options) {
+ Option opt = new Option("c", "clusterName", true, "choose a cluster to export");
+ opt.setRequired(false);
+ options.addOption(opt);
+
+ opt = new Option("b", "brokerAddr", true, "choose a broker to export");
+ opt.setRequired(false);
+ options.addOption(opt);
+
+ opt = new Option("f", "filePath", true, "export metadata.json path | default /tmp/rocketmq/export");
+ opt.setRequired(false);
+ options.addOption(opt);
+
+ opt = new Option("t", "topic", false, "only export topic metadata");
+ opt.setRequired(false);
+ options.addOption(opt);
+
+ opt = new Option("g", "subscriptionGroup", false, "only export subscriptionGroup metadata");
+ opt.setRequired(false);
+ options.addOption(opt);
+
+ opt = new Option("s", "specialTopic", false, "need retryTopic and dlqTopic");
+ opt.setRequired(false);
+ options.addOption(opt);
+ return options;
+ }
+
+ @Override
+ public void execute(CommandLine commandLine, Options options, RPCHook rpcHook)
+ throws SubCommandException {
+ DefaultMQAdminExt defaultMQAdminExt = new DefaultMQAdminExt(rpcHook);
+
+ defaultMQAdminExt.setInstanceName(Long.toString(System.currentTimeMillis()));
+
+ try {
+ defaultMQAdminExt.start();
+
+ String filePath = !commandLine.hasOption('f') ? DEFAULT_FILE_PATH : commandLine.getOptionValue('f')
+ .trim();
+
+ boolean specialTopic = commandLine.hasOption('s');
+
+ if (commandLine.hasOption('b')) {
+ final String brokerAddr = commandLine.getOptionValue('b').trim();
+
+ if (commandLine.hasOption('t')) {
+ filePath = filePath + "/topic.json";
+ TopicConfigSerializeWrapper topicConfigSerializeWrapper = defaultMQAdminExt.getUserTopicConfig(
+ brokerAddr, specialTopic, 10000L);
+ MixAll.string2FileNotSafe(JSON.toJSONString(topicConfigSerializeWrapper, true), filePath);
+ System.out.printf("export %s success", filePath);
+ } else if (commandLine.hasOption('g')) {
+ filePath = filePath + "/subscriptionGroup.json";
+ SubscriptionGroupWrapper subscriptionGroupWrapper = defaultMQAdminExt.getUserSubscriptionGroup(
+ brokerAddr, 10000L);
+ MixAll.string2FileNotSafe(JSON.toJSONString(subscriptionGroupWrapper, true), filePath);
+ System.out.printf("export %s success", filePath);
+ }
+ } else if (commandLine.hasOption('c')) {
+ String clusterName = commandLine.getOptionValue('c').trim();
+
+ Set masterSet =
+ CommandUtil.fetchMasterAddrByClusterName(defaultMQAdminExt, clusterName);
+
+ Map topicConfigMap = new HashMap<>();
+ Map subGroupConfigMap = new HashMap<>();
+
+ for (String addr : masterSet) {
+ TopicConfigSerializeWrapper topicConfigSerializeWrapper = defaultMQAdminExt.getUserTopicConfig(
+ addr, specialTopic, 10000L);
+
+ SubscriptionGroupWrapper subscriptionGroupWrapper = defaultMQAdminExt.getUserSubscriptionGroup(
+ addr, 10000);
+
+ if (commandLine.hasOption('t')) {
+ filePath = filePath + "/topic.json";
+ MixAll.string2FileNotSafe(JSON.toJSONString(topicConfigSerializeWrapper, true), filePath);
+ System.out.printf("export %s success", filePath);
+ return;
+ } else if (commandLine.hasOption('g')) {
+ filePath = filePath + "/subscriptionGroup.json";
+ MixAll.string2FileNotSafe(JSON.toJSONString(subscriptionGroupWrapper, true), filePath);
+ System.out.printf("export %s success", filePath);
+ return;
+ } else {
+ for (Map.Entry entry : topicConfigSerializeWrapper.getTopicConfigTable().entrySet()) {
+ TopicConfig topicConfig = topicConfigMap.get(entry.getKey());
+ if (null != topicConfig) {
+ entry.getValue().setWriteQueueNums(
+ topicConfig.getWriteQueueNums() + entry.getValue().getWriteQueueNums());
+ entry.getValue().setReadQueueNums(
+ topicConfig.getReadQueueNums() + entry.getValue().getReadQueueNums());
+ }
+ topicConfigMap.put(entry.getKey(), entry.getValue());
+ }
+
+ for (Map.Entry entry : subscriptionGroupWrapper.getSubscriptionGroupTable().entrySet()) {
+
+ SubscriptionGroupConfig subscriptionGroupConfig = subGroupConfigMap.get(entry.getKey());
+ if (null != subscriptionGroupConfig) {
+ entry.getValue().setRetryQueueNums(
+ subscriptionGroupConfig.getRetryQueueNums() + entry.getValue().getRetryQueueNums());
+ }
+ subGroupConfigMap.put(entry.getKey(), entry.getValue());
+ }
+
+ Map result = new HashMap<>();
+ result.put("topicConfigTable", topicConfigMap);
+ result.put("subscriptionGroupTable", subGroupConfigMap);
+ result.put("rocketmqVersion", MQVersion.getVersionDesc(MQVersion.CURRENT_VERSION));
+ result.put("exportTime", System.currentTimeMillis());
+
+ filePath = filePath + "/metadata.json";
+ MixAll.string2FileNotSafe(JSON.toJSONString(result, true), filePath);
+ System.out.printf("export %s success", filePath);
+ }
+
+ }
+ } else {
+ 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/main/java/org/apache/rocketmq/tools/command/export/ExportMetricsCommand.java b/tools/src/main/java/org/apache/rocketmq/tools/command/export/ExportMetricsCommand.java
new file mode 100644
index 0000000000000000000000000000000000000000..497083f09a7333af364ae3166a54fae738a96a20
--- /dev/null
+++ b/tools/src/main/java/org/apache/rocketmq/tools/command/export/ExportMetricsCommand.java
@@ -0,0 +1,282 @@
+/*
+ * 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.export;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+
+import com.alibaba.fastjson.JSON;
+
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+import org.apache.rocketmq.client.exception.MQBrokerException;
+import org.apache.rocketmq.client.exception.MQClientException;
+import org.apache.rocketmq.common.MQVersion;
+import org.apache.rocketmq.common.MixAll;
+import org.apache.rocketmq.common.protocol.body.BrokerStatsData;
+import org.apache.rocketmq.common.protocol.body.ClusterInfo;
+import org.apache.rocketmq.common.protocol.body.Connection;
+import org.apache.rocketmq.common.protocol.body.ConsumerConnection;
+import org.apache.rocketmq.common.protocol.body.KVTable;
+import org.apache.rocketmq.common.protocol.body.SubscriptionGroupWrapper;
+import org.apache.rocketmq.common.protocol.body.TopicConfigSerializeWrapper;
+import org.apache.rocketmq.common.protocol.route.BrokerData;
+import org.apache.rocketmq.common.subscription.SubscriptionGroupConfig;
+import org.apache.rocketmq.common.topic.TopicValidator;
+import org.apache.rocketmq.remoting.RPCHook;
+import org.apache.rocketmq.remoting.exception.RemotingException;
+import org.apache.rocketmq.store.stats.BrokerStatsManager;
+import org.apache.rocketmq.tools.admin.DefaultMQAdminExt;
+import org.apache.rocketmq.tools.command.SubCommand;
+import org.apache.rocketmq.tools.command.SubCommandException;
+import org.apache.rocketmq.tools.command.stats.StatsAllSubCommand;
+
+public class ExportMetricsCommand implements SubCommand {
+
+ @Override
+ public String commandName() {
+ return "exportMetrics";
+ }
+
+ @Override
+ public String commandDesc() {
+ return "export metrics";
+ }
+
+ @Override
+ public Options buildCommandlineOptions(Options options) {
+ Option opt = new Option("c", "clusterName", true, "choose a cluster to export");
+ opt.setRequired(true);
+ options.addOption(opt);
+
+ opt = new Option("f", "filePath", true,
+ "export metrics.json path | default /tmp/rocketmq/export");
+ opt.setRequired(false);
+ options.addOption(opt);
+ return options;
+ }
+
+ @Override
+ public void execute(CommandLine commandLine, Options options, RPCHook rpcHook)
+ throws SubCommandException {
+
+ DefaultMQAdminExt defaultMQAdminExt = new DefaultMQAdminExt(rpcHook);
+ defaultMQAdminExt.setInstanceName(Long.toString(System.currentTimeMillis()));
+
+ try {
+ String clusterName = commandLine.getOptionValue('c').trim();
+ String filePath = !commandLine.hasOption('f') ? "/tmp/rocketmq/export" : commandLine.getOptionValue('f')
+ .trim();
+
+ defaultMQAdminExt.start();
+
+ Map>> evaluateReportMap = new HashMap<>();
+ Map totalTpsMap = new HashMap<>();
+ Map totalOneDayNumMap = new HashMap<>();
+ initTotalMap(totalTpsMap, totalOneDayNumMap);
+
+ ClusterInfo clusterInfoSerializeWrapper = defaultMQAdminExt.examineBrokerClusterInfo();
+ Set brokerNameSet = clusterInfoSerializeWrapper.getClusterAddrTable().get(clusterName);
+ for (String brokerName : brokerNameSet) {
+ BrokerData brokerData = clusterInfoSerializeWrapper.getBrokerAddrTable().get(brokerName);
+ if (brokerData != null) {
+ String addr = brokerData.getBrokerAddrs().get(0L);
+
+ KVTable kvTable = defaultMQAdminExt.fetchBrokerRuntimeStats(addr);
+
+ Properties properties = defaultMQAdminExt.getBrokerConfig(addr);
+
+ SubscriptionGroupWrapper subscriptionGroupWrapper = defaultMQAdminExt.getUserSubscriptionGroup(addr,
+ 10000);
+
+ Map> brokerInfo = new HashMap<>();
+
+ //broker environment,machine configuration
+ brokerInfo.put("runtimeEnv", getRuntimeEnv(kvTable, properties));
+
+ brokerInfo.put("runtimeQuota",
+ getRuntimeQuota(kvTable, defaultMQAdminExt, addr, totalTpsMap,
+ totalOneDayNumMap, subscriptionGroupWrapper));
+
+ // runtime version
+ brokerInfo.put("runtimeVersion",
+ getRuntimeVersion(defaultMQAdminExt, subscriptionGroupWrapper));
+
+ evaluateReportMap.put(brokerName, brokerInfo);
+ }
+
+ }
+
+ String path = filePath + "/metrics.json";
+
+ Map totalData = new HashMap<>();
+ totalData.put("totalTps", totalTpsMap);
+ totalData.put("totalOneDayNum", totalOneDayNumMap);
+
+ Map result = new HashMap<>();
+ result.put("evaluateReport", evaluateReportMap);
+ result.put("totalData", totalData);
+
+ MixAll.string2FileNotSafe(JSON.toJSONString(result, true), path);
+ System.out.printf("export %s success", path);
+ } catch (Exception e) {
+ throw new SubCommandException(this.getClass().getSimpleName() + " command failed", e);
+ } finally {
+ defaultMQAdminExt.shutdown();
+ }
+
+ }
+
+ private Map getRuntimeVersion(DefaultMQAdminExt defaultMQAdminExt,
+ SubscriptionGroupWrapper subscriptionGroupWrapper) {
+ Map runtimeVersionMap = new HashMap();
+
+ Set clientInfoSet = new HashSet<>();
+ for (Map.Entry entry : subscriptionGroupWrapper
+ .getSubscriptionGroupTable().entrySet()) {
+ try {
+ ConsumerConnection cc = defaultMQAdminExt.examineConsumerConnectionInfo(
+ entry.getValue().getGroupName());
+ for (Connection conn : cc.getConnectionSet()) {
+ String clientInfo = conn.getLanguage() + "%" + MQVersion.getVersionDesc(conn.getVersion());
+ clientInfoSet.add(clientInfo);
+ }
+ } catch (Exception e) {
+ continue;
+ }
+ }
+ runtimeVersionMap.put("rocketmqVersion", MQVersion.getVersionDesc(MQVersion.CURRENT_VERSION));
+ runtimeVersionMap.put("clientInfo", clientInfoSet);
+ return runtimeVersionMap;
+ }
+
+ private Map getRuntimeEnv(KVTable kvTable, Properties properties) {
+ Map runtimeEnvMap = new HashMap<>();
+ runtimeEnvMap.put("cpuNum", properties.getProperty("clientCallbackExecutorThreads"));
+ runtimeEnvMap.put("totalMemKBytes", kvTable.getTable().get("totalMemKBytes"));
+ return runtimeEnvMap;
+ }
+
+ private Map getRuntimeQuota(KVTable kvTable, DefaultMQAdminExt defaultMQAdminExt, String brokerAddr,
+ Map totalTpsMap, Map totalOneDayNumMap,
+ SubscriptionGroupWrapper subscriptionGroupWrapper)
+ throws RemotingException, MQBrokerException, InterruptedException, MQClientException {
+ TopicConfigSerializeWrapper topicConfigSerializeWrapper = defaultMQAdminExt.getUserTopicConfig(
+ brokerAddr, false, 10000);
+
+ BrokerStatsData transStatsData = null;
+
+ try {
+ transStatsData = defaultMQAdminExt.viewBrokerStatsData(brokerAddr,
+ BrokerStatsManager.TOPIC_PUT_NUMS,
+ TopicValidator.RMQ_SYS_TRANS_HALF_TOPIC);
+ } catch (MQClientException e) {
+ }
+
+ BrokerStatsData scheduleStatsData = null;
+ try {
+ scheduleStatsData = defaultMQAdminExt.viewBrokerStatsData(brokerAddr,
+ BrokerStatsManager.TOPIC_PUT_NUMS, TopicValidator.RMQ_SYS_SCHEDULE_TOPIC);
+ } catch (MQClientException e) {
+ }
+
+ Map runtimeQuotaMap = new HashMap<>();
+ //disk use ratio
+ Map diskRatioMap = new HashMap<>();
+ diskRatioMap.put("commitLogDiskRatio", kvTable.getTable().get("commitLogDiskRatio"));
+ diskRatioMap.put("consumeQueueDiskRatio", kvTable.getTable().get("consumeQueueDiskRatio"));
+ runtimeQuotaMap.put("diskRatio", diskRatioMap);
+
+ //inTps and outTps
+ Map tpsMap = new HashMap<>();
+ double normalInTps = 0;
+ double normalOutTps = 0;
+ String putTps = kvTable.getTable().get("putTps");
+ String getTransferedTps = kvTable.getTable().get("getTransferedTps");
+ String[] inTpss = putTps.split(" ");
+ if (inTpss.length > 0) {
+ normalInTps = Double.parseDouble(inTpss[0]);
+ }
+
+ String[] outTpss = getTransferedTps.split(" ");
+ if (outTpss.length > 0) {
+ normalOutTps = Double.parseDouble(outTpss[0]);
+ }
+
+ double transInTps = null != transStatsData ? transStatsData.getStatsMinute().getTps() : 0.0;
+ double scheduleInTps = null != scheduleStatsData ? scheduleStatsData.getStatsMinute().getTps() : 0.0;
+
+ long transOneDayInNum = null != transStatsData ? StatsAllSubCommand.compute24HourSum(transStatsData) : 0;
+ long scheduleOneDayInNum = null != scheduleStatsData ? StatsAllSubCommand.compute24HourSum(scheduleStatsData) : 0;
+
+ //current minute tps
+ tpsMap.put("normalInTps", normalInTps);
+ tpsMap.put("normalOutTps", normalOutTps);
+ tpsMap.put("transInTps", transInTps);
+ tpsMap.put("scheduleInTps", scheduleInTps);
+ runtimeQuotaMap.put("tps", tpsMap);
+
+ //one day num
+ Map oneDayNumMap = new HashMap<>();
+ long normalOneDayInNum = Long.parseLong(kvTable.getTable().get("msgPutTotalTodayMorning")) -
+ Long.parseLong(kvTable.getTable().get("msgPutTotalYesterdayMorning"));
+ long normalOneDayOutNum = Long.parseLong(kvTable.getTable().get("msgGetTotalTodayMorning")) -
+ Long.parseLong(kvTable.getTable().get("msgGetTotalYesterdayMorning"));
+ oneDayNumMap.put("normalOneDayInNum", normalOneDayInNum);
+ oneDayNumMap.put("normalOneDayOutNum", normalOneDayOutNum);
+ oneDayNumMap.put("transOneDayInNum", transOneDayInNum);
+ oneDayNumMap.put("scheduleOneDayInNum", scheduleOneDayInNum);
+ runtimeQuotaMap.put("oneDayNum", oneDayNumMap);
+
+ //all broker current minute tps
+ totalTpsMap.put("totalNormalInTps", totalTpsMap.get("totalNormalInTps") + normalInTps);
+ totalTpsMap.put("totalNormalOutTps", totalTpsMap.get("totalNormalOutTps") + normalOutTps);
+ totalTpsMap.put("totalTransInTps", totalTpsMap.get("totalTransInTps") + transInTps);
+ totalTpsMap.put("totalScheduleInTps", totalTpsMap.get("totalScheduleInTps") + scheduleInTps);
+
+
+ //all broker one day num
+ totalOneDayNumMap.put("normalOneDayInNum", totalOneDayNumMap.get("normalOneDayInNum") + normalOneDayInNum);
+ totalOneDayNumMap.put("normalOneDayOutNum", totalOneDayNumMap.get("normalOneDayOutNum") + normalOneDayOutNum);
+ totalOneDayNumMap.put("transOneDayInNum", totalOneDayNumMap.get("transOneDayInNum") + transOneDayInNum);
+ totalOneDayNumMap.put("scheduleOneDayInNum", totalOneDayNumMap.get("scheduleOneDayInNum") + scheduleOneDayInNum);
+
+ // putMessageAverageSize
+ runtimeQuotaMap.put("messageAverageSize", kvTable.getTable().get("putMessageAverageSize"));
+
+ //topicSize
+ runtimeQuotaMap.put("topicSize", topicConfigSerializeWrapper.getTopicConfigTable().size());
+ runtimeQuotaMap.put("groupSize", subscriptionGroupWrapper.getSubscriptionGroupTable().size());
+ return runtimeQuotaMap;
+ }
+
+ private void initTotalMap(Map totalTpsMap, Map totalOneDayNumMap) {
+ totalTpsMap.put("totalNormalInTps", 0.0);
+ totalTpsMap.put("totalNormalOutTps", 0.0);
+ totalTpsMap.put("totalTransInTps", 0.0);
+ totalTpsMap.put("totalScheduleInTps", 0.0);
+
+ totalOneDayNumMap.put("normalOneDayInNum", 0L);
+ totalOneDayNumMap.put("normalOneDayOutNum", 0L);
+ totalOneDayNumMap.put("transOneDayInNum", 0L);
+ totalOneDayNumMap.put("scheduleOneDayInNum", 0L);
+ }
+}
diff --git a/tools/src/main/java/org/apache/rocketmq/tools/command/message/QueryMsgByUniqueKeySubCommand.java b/tools/src/main/java/org/apache/rocketmq/tools/command/message/QueryMsgByUniqueKeySubCommand.java
index 8c7bec616d7068a8fab2c8c03d79cabcfb1e64cb..17abdf218cb366e6f8c902caea5d567674196c86 100644
--- a/tools/src/main/java/org/apache/rocketmq/tools/command/message/QueryMsgByUniqueKeySubCommand.java
+++ b/tools/src/main/java/org/apache/rocketmq/tools/command/message/QueryMsgByUniqueKeySubCommand.java
@@ -114,7 +114,7 @@ public class QueryMsgByUniqueKeySubCommand implements SubCommand {
private static String createBodyFile(MessageExt msg, int index) throws IOException {
DataOutputStream dos = null;
try {
- StringBuffer bodyTmpFilePath = new StringBuffer("/tmp/rocketmq/msgbodys");
+ StringBuilder bodyTmpFilePath = new StringBuilder("/tmp/rocketmq/msgbodys");
File file = new File(bodyTmpFilePath.toString());
if (!file.exists()) {
file.mkdirs();
@@ -127,8 +127,9 @@ public class QueryMsgByUniqueKeySubCommand implements SubCommand {
dos.write(msg.getBody());
return bodyTmpFilePath.toString();
} finally {
- if (dos != null)
+ if (dos != null) {
dos.close();
+ }
}
}
diff --git a/tools/src/main/java/org/apache/rocketmq/tools/command/namesrv/AddWritePermSubCommand.java b/tools/src/main/java/org/apache/rocketmq/tools/command/namesrv/AddWritePermSubCommand.java
new file mode 100644
index 0000000000000000000000000000000000000000..98542d065d5459ece5922b2af2f3260c7e350bd5
--- /dev/null
+++ b/tools/src/main/java/org/apache/rocketmq/tools/command/namesrv/AddWritePermSubCommand.java
@@ -0,0 +1,80 @@
+/*
+ * 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.namesrv;
+
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+import org.apache.rocketmq.remoting.RPCHook;
+import org.apache.rocketmq.tools.admin.DefaultMQAdminExt;
+import org.apache.rocketmq.tools.command.SubCommand;
+import org.apache.rocketmq.tools.command.SubCommandException;
+
+import java.util.List;
+
+public class AddWritePermSubCommand implements SubCommand {
+ @Override
+ public String commandName() {
+ return "addWritePerm";
+ }
+
+ @Override
+ public String commandDesc() {
+ return "Add write perm of broker in all name server you defined in the -n param";
+ }
+
+ @Override
+ public Options buildCommandlineOptions(Options options) {
+ Option opt = new Option("b", "brokerName", true, "broker name");
+ opt.setRequired(true);
+ options.addOption(opt);
+ return options;
+ }
+
+ @Override
+ public void execute(CommandLine commandLine, Options options, RPCHook rpcHook) throws SubCommandException {
+ DefaultMQAdminExt defaultMQAdminExt = new DefaultMQAdminExt(rpcHook);
+ defaultMQAdminExt.setInstanceName(Long.toString(System.currentTimeMillis()));
+ try {
+ defaultMQAdminExt.start();
+ String brokerName = commandLine.getOptionValue('b').trim();
+ List namesrvList = defaultMQAdminExt.getNameServerAddressList();
+ if (namesrvList != null) {
+ for (String namesrvAddr : namesrvList) {
+ try {
+ int addTopicCount = defaultMQAdminExt.addWritePermOfBroker(namesrvAddr, brokerName);
+ System.out.printf("add write perm of broker[%s] in name server[%s] OK, %d%n",
+ brokerName,
+ namesrvAddr,
+ addTopicCount
+ );
+ } catch (Exception e) {
+ System.out.printf("add write perm of broker[%s] in name server[%s] Failed%n",
+ brokerName,
+ namesrvAddr
+ );
+ e.printStackTrace();
+ }
+ }
+ }
+ } catch (Exception e) {
+ throw new SubCommandException(this.getClass().getSimpleName() + "command failed", e);
+ } finally {
+ defaultMQAdminExt.shutdown();
+ }
+ }
+}
diff --git a/tools/src/main/java/org/apache/rocketmq/tools/command/namesrv/WipeWritePermSubCommand.java b/tools/src/main/java/org/apache/rocketmq/tools/command/namesrv/WipeWritePermSubCommand.java
index f8868335a18fd68acdd5c1eb2406930d4300149a..213931ed86e16beb3df37dc1a0161c56a5c9572c 100644
--- a/tools/src/main/java/org/apache/rocketmq/tools/command/namesrv/WipeWritePermSubCommand.java
+++ b/tools/src/main/java/org/apache/rocketmq/tools/command/namesrv/WipeWritePermSubCommand.java
@@ -34,7 +34,7 @@ public class WipeWritePermSubCommand implements SubCommand {
@Override
public String commandDesc() {
- return "Wipe write perm of broker in all name server";
+ return "Wipe write perm of broker in all name server you defined in the -n param";
}
@Override
diff --git a/tools/src/test/java/org/apache/rocketmq/tools/admin/DefaultMQAdminExtTest.java b/tools/src/test/java/org/apache/rocketmq/tools/admin/DefaultMQAdminExtTest.java
index 3146b1781154792a2d7928e0306e9cf172b5ddac..5c69774c11c2329a5edb31c1a73c1fe768d1a300 100644
--- a/tools/src/test/java/org/apache/rocketmq/tools/admin/DefaultMQAdminExtTest.java
+++ b/tools/src/test/java/org/apache/rocketmq/tools/admin/DefaultMQAdminExtTest.java
@@ -34,6 +34,7 @@ import org.apache.rocketmq.client.exception.MQClientException;
import org.apache.rocketmq.client.impl.MQClientAPIImpl;
import org.apache.rocketmq.client.impl.MQClientManager;
import org.apache.rocketmq.client.impl.factory.MQClientInstance;
+import org.apache.rocketmq.common.TopicConfig;
import org.apache.rocketmq.common.admin.ConsumeStats;
import org.apache.rocketmq.common.admin.OffsetWrapper;
import org.apache.rocketmq.common.admin.TopicOffset;
@@ -54,6 +55,7 @@ import org.apache.rocketmq.common.protocol.body.ProcessQueueInfo;
import org.apache.rocketmq.common.protocol.body.ProducerConnection;
import org.apache.rocketmq.common.protocol.body.QueueTimeSpan;
import org.apache.rocketmq.common.protocol.body.SubscriptionGroupWrapper;
+import org.apache.rocketmq.common.protocol.body.TopicConfigSerializeWrapper;
import org.apache.rocketmq.common.protocol.body.TopicList;
import org.apache.rocketmq.common.protocol.heartbeat.ConsumeType;
import org.apache.rocketmq.common.protocol.heartbeat.MessageModel;
@@ -209,6 +211,7 @@ public class DefaultMQAdminExtTest {
when(mQClientAPIImpl.getProducerConnectionList(anyString(), anyString(), anyLong())).thenReturn(producerConnection);
when(mQClientAPIImpl.wipeWritePermOfBroker(anyString(), anyString(), anyLong())).thenReturn(6);
+ when(mQClientAPIImpl.addWritePermOfBroker(anyString(), anyString(), anyLong())).thenReturn(7);
TopicStatsTable topicStatsTable = new TopicStatsTable();
topicStatsTable.setOffsetTable(new HashMap());
@@ -225,6 +228,14 @@ public class DefaultMQAdminExtTest {
consumerRunningInfo.setStatusTable(new TreeMap());
consumerRunningInfo.setSubscriptionSet(new TreeSet());
when(mQClientAPIImpl.getConsumerRunningInfo(anyString(), anyString(), anyString(), anyBoolean(), anyLong())).thenReturn(consumerRunningInfo);
+
+ TopicConfigSerializeWrapper topicConfigSerializeWrapper = new TopicConfigSerializeWrapper();
+ topicConfigSerializeWrapper.setTopicConfigTable(new ConcurrentHashMap() {
+ {
+ put("topic_test_examine_topicConfig", new TopicConfig("topic_test_examine_topicConfig"));
+ }
+ });
+ when(mQClientAPIImpl.getAllTopicConfig(anyString(),anyLong())).thenReturn(topicConfigSerializeWrapper);
}
@AfterClass
@@ -299,6 +310,12 @@ public class DefaultMQAdminExtTest {
assertThat(result).isEqualTo(6);
}
+ @Test
+ public void testAddWritePermOfBroker() throws InterruptedException, RemotingCommandException, RemotingSendRequestException, RemotingTimeoutException, MQClientException, RemotingConnectException {
+ int result = defaultMQAdminExt.addWritePermOfBroker("127.0.0.1:9876", "default-broker");
+ assertThat(result).isEqualTo(7);
+ }
+
@Test
public void testExamineTopicRouteInfo() throws RemotingException, MQClientException, InterruptedException {
TopicRouteData topicRouteData = defaultMQAdminExt.examineTopicRouteInfo("UnitTest");
@@ -406,4 +423,10 @@ public class DefaultMQAdminExtTest {
assertThat(subscriptionGroupWrapper.getSubscriptionGroupTable().get("Consumer-group-one").getGroupName()).isEqualTo("Consumer-group-one");
assertThat(subscriptionGroupWrapper.getSubscriptionGroupTable().get("Consumer-group-one").isConsumeBroadcastEnable()).isTrue();
}
+
+ @Test
+ public void testExamineTopicConfig() throws MQBrokerException, RemotingException, InterruptedException {
+ TopicConfig topicConfig = defaultMQAdminExt.examineTopicConfig("127.0.0.1:10911", "topic_test_examine_topicConfig");
+ assertThat(topicConfig.getTopicName().equals("topic_test_examine_topicConfig"));
+ }
}
\ No newline at end of file
diff --git a/tools/src/test/java/org/apache/rocketmq/tools/command/consumer/GetConsumerConfigSubCommandTest.java b/tools/src/test/java/org/apache/rocketmq/tools/command/consumer/GetConsumerConfigSubCommandTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..1ec68ff02ba380e5ff2357fb4dd379d9a158214c
--- /dev/null
+++ b/tools/src/test/java/org/apache/rocketmq/tools/command/consumer/GetConsumerConfigSubCommandTest.java
@@ -0,0 +1,83 @@
+/*
+ * 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.consumer;
+
+import java.io.UnsupportedEncodingException;
+import java.lang.reflect.Field;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Options;
+import org.apache.commons.cli.PosixParser;
+import org.apache.rocketmq.client.ClientConfig;
+import org.apache.rocketmq.client.exception.MQBrokerException;
+import org.apache.rocketmq.client.exception.MQClientException;
+import org.apache.rocketmq.client.impl.MQClientAPIImpl;
+import org.apache.rocketmq.client.impl.MQClientManager;
+import org.apache.rocketmq.client.impl.factory.MQClientInstance;
+import org.apache.rocketmq.remoting.exception.RemotingConnectException;
+import org.apache.rocketmq.remoting.exception.RemotingSendRequestException;
+import org.apache.rocketmq.remoting.exception.RemotingTimeoutException;
+import org.apache.rocketmq.srvutil.ServerUtil;
+import org.apache.rocketmq.tools.admin.DefaultMQAdminExt;
+import org.apache.rocketmq.tools.admin.DefaultMQAdminExtImpl;
+import org.apache.rocketmq.tools.command.SubCommandException;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Ignore;
+import org.junit.Test;
+
+import static org.mockito.Mockito.mock;
+
+public class GetConsumerConfigSubCommandTest {
+ private static DefaultMQAdminExt defaultMQAdminExt;
+ private static DefaultMQAdminExtImpl defaultMQAdminExtImpl;
+ private static MQClientInstance mqClientInstance = MQClientManager.getInstance().getOrCreateMQClientInstance(new ClientConfig());
+ private static MQClientAPIImpl mQClientAPIImpl;
+
+ @BeforeClass
+ public static void init() throws NoSuchFieldException, IllegalAccessException, InterruptedException, RemotingTimeoutException, MQClientException, RemotingSendRequestException, RemotingConnectException, MQBrokerException, UnsupportedEncodingException {
+ mQClientAPIImpl = mock(MQClientAPIImpl.class);
+ defaultMQAdminExt = new DefaultMQAdminExt();
+ defaultMQAdminExtImpl = new DefaultMQAdminExtImpl(defaultMQAdminExt, 1000);
+
+ Field field = DefaultMQAdminExtImpl.class.getDeclaredField("mqClientInstance");
+ field.setAccessible(true);
+ field.set(defaultMQAdminExtImpl, mqClientInstance);
+ field = MQClientInstance.class.getDeclaredField("mQClientAPIImpl");
+ field.setAccessible(true);
+ field.set(mqClientInstance, mQClientAPIImpl);
+ field = DefaultMQAdminExt.class.getDeclaredField("defaultMQAdminExtImpl");
+ field.setAccessible(true);
+ field.set(defaultMQAdminExt, defaultMQAdminExtImpl);
+ }
+
+ @AfterClass
+ public static void terminate() {
+ defaultMQAdminExt.shutdown();
+ }
+
+ @Ignore
+ @Test
+ public void testExecute() throws SubCommandException {
+ System.setProperty("rocketmq.namesrv.addr", "127.0.0.1:9876");
+ GetConsumerConfigSubCommand cmd = new GetConsumerConfigSubCommand();
+ Options options = ServerUtil.buildCommandlineOptions(new Options());
+ String[] subargs = new String[] {"-g group_test"};
+ final CommandLine commandLine =
+ ServerUtil.parseCmdLine("mqadmin " + cmd.commandName(), subargs, cmd.buildCommandlineOptions(options), new PosixParser());
+ cmd.execute(commandLine, options, null);
+ }
+}
\ No newline at end of file
diff --git a/tools/src/test/java/org/apache/rocketmq/tools/command/namesrv/AddWritePermSubCommandTest.java b/tools/src/test/java/org/apache/rocketmq/tools/command/namesrv/AddWritePermSubCommandTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..901b8bbd3be25783554d251b98b1db26bf806f76
--- /dev/null
+++ b/tools/src/test/java/org/apache/rocketmq/tools/command/namesrv/AddWritePermSubCommandTest.java
@@ -0,0 +1,37 @@
+/*
+ * 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.namesrv;
+
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Options;
+import org.apache.commons.cli.PosixParser;
+import org.apache.rocketmq.srvutil.ServerUtil;
+import org.apache.rocketmq.tools.command.SubCommandException;
+import org.junit.Test;
+
+public class AddWritePermSubCommandTest {
+
+ @Test
+ public void testExecute() throws SubCommandException {
+ AddWritePermSubCommand cmd = new AddWritePermSubCommand();
+ Options options = ServerUtil.buildCommandlineOptions(new Options());
+ String[] subargs = new String[]{"-b default-broker"};
+ final CommandLine commandLine =
+ ServerUtil.parseCmdLine("mqadmin " + cmd.commandName(), subargs, cmd.buildCommandlineOptions(options), new PosixParser());
+ cmd.execute(commandLine, options, null);
+ }
+}