This is an automated email from the ASF dual-hosted git repository. huangli pushed a commit to branch 4.9.2_dev_community in repository https://gitbox.apache.org/repos/asf/rocketmq.git
commit c7fe273c5f3ff6b60d138badebedec51fa4dbcfd Author: huangli <[email protected]> AuthorDate: Tue Nov 16 00:16:21 2021 +0800 优化createUniqID使其在生产者(client)火焰图中的占比从2.41%下降到0.42% --- .../java/org/apache/rocketmq/common/UtilAll.java | 14 +++++++++++ .../common/message/MessageClientIDSetter.java | 27 +++++++++++----------- .../common/message/MessageClientIDSetterTest.java | 22 ++++++++++++++++++ 3 files changed, 50 insertions(+), 13 deletions(-) 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 ea22aa7..a15b4fa 100644 --- a/common/src/main/java/org/apache/rocketmq/common/UtilAll.java +++ b/common/src/main/java/org/apache/rocketmq/common/UtilAll.java @@ -262,6 +262,20 @@ public class UtilAll { return new String(hexChars); } + public static void writeInt(char[] buffer, int pos, int value) { + char[] hexArray = HEX_ARRAY; + for (int moveBits = 28; moveBits >= 0; moveBits -= 4) { + buffer[pos++] = hexArray[(value >>> moveBits) & 0x0F]; + } + } + + public static void writeShort(char[] buffer, int pos, int value) { + char[] hexArray = HEX_ARRAY; + for (int moveBits = 12; moveBits >= 0; moveBits -= 4) { + buffer[pos++] = hexArray[(value >>> moveBits) & 0x0F]; + } + } + public static byte[] string2bytes(String hexString) { if (hexString == null || hexString.equals("")) { return null; diff --git a/common/src/main/java/org/apache/rocketmq/common/message/MessageClientIDSetter.java b/common/src/main/java/org/apache/rocketmq/common/message/MessageClientIDSetter.java index 041bf6b..57090c1 100644 --- a/common/src/main/java/org/apache/rocketmq/common/message/MessageClientIDSetter.java +++ b/common/src/main/java/org/apache/rocketmq/common/message/MessageClientIDSetter.java @@ -25,7 +25,7 @@ import org.apache.rocketmq.common.UtilAll; public class MessageClientIDSetter { private static final String TOPIC_KEY_SPLITTER = "#"; private static final int LEN; - private static final String FIX_STRING; + private static final char[] FIX_STRING; private static final AtomicInteger COUNTER; private static long startTime; private static long nextStartTime; @@ -42,7 +42,7 @@ public class MessageClientIDSetter { tempBuffer.put(ip); tempBuffer.putShort((short) UtilAll.getPid()); tempBuffer.putInt(MessageClientIDSetter.class.getClassLoader().hashCode()); - FIX_STRING = UtilAll.bytes2string(tempBuffer.array()); + FIX_STRING = UtilAll.bytes2string(tempBuffer.array()).toCharArray(); setStartTime(System.currentTimeMillis()); COUNTER = new AtomicInteger(0); } @@ -112,21 +112,22 @@ public class MessageClientIDSetter { } public static String createUniqID() { - StringBuilder sb = new StringBuilder(LEN * 2); - sb.append(FIX_STRING); - sb.append(UtilAll.bytes2string(createUniqIDBuffer())); - return sb.toString(); - } - - private static byte[] createUniqIDBuffer() { - ByteBuffer buffer = ByteBuffer.allocate(4 + 2); + char[] sb = new char[LEN * 2]; + System.arraycopy(FIX_STRING, 0, sb, 0, FIX_STRING.length); long current = System.currentTimeMillis(); if (current >= nextStartTime) { setStartTime(current); } - buffer.putInt((int) (System.currentTimeMillis() - startTime)); - buffer.putShort((short) COUNTER.getAndIncrement()); - return buffer.array(); + int diff = (int)(current - startTime); + if (diff < 0 && diff > -1000_000) { + // may cause by NTP + diff = 0; + } + int pos = FIX_STRING.length; + UtilAll.writeInt(sb, pos, diff); + pos += 8; + UtilAll.writeShort(sb, pos, COUNTER.getAndIncrement()); + return new String(sb); } public static void setUniqID(final Message msg) { diff --git a/common/src/test/java/org/apache/rocketmq/common/message/MessageClientIDSetterTest.java b/common/src/test/java/org/apache/rocketmq/common/message/MessageClientIDSetterTest.java index 0a17c36..1734cbd 100644 --- a/common/src/test/java/org/apache/rocketmq/common/message/MessageClientIDSetterTest.java +++ b/common/src/test/java/org/apache/rocketmq/common/message/MessageClientIDSetterTest.java @@ -22,9 +22,31 @@ import org.junit.Test; import static org.assertj.core.api.Assertions.assertThat; +import java.nio.charset.StandardCharsets; + public class MessageClientIDSetterTest { @Test + public void testGetTimeFromID() { + long t = System.currentTimeMillis(); + String uniqID = MessageClientIDSetter.createUniqID(); + long t2 = MessageClientIDSetter.getNearlyTimeFromID(uniqID).getTime(); + assertThat(t2 - t < 20); + } + + @Test + public void testGetCountFromID() { + String uniqID = MessageClientIDSetter.createUniqID(); + String uniqID2 = MessageClientIDSetter.createUniqID(); + String idHex = uniqID.substring(uniqID.length() - 4); + String idHex2 = uniqID2.substring(uniqID2.length() - 4); + int s1 = Integer.parseInt(idHex, 16); + int s2 = Integer.parseInt(idHex2, 16); + assertThat(s1 == s2 - 1); + } + + + @Test public void testGetIPStrFromID() { byte[] ip = UtilAll.getIP(); String ipStr = (4 == ip.length) ? UtilAll.ipToIPv4Str(ip) : UtilAll.ipToIPv6Str(ip);
