You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@rocketmq.apache.org by hu...@apache.org on 2021/12/01 10:37:58 UTC

[rocketmq] 07/11: 优化createUniqID使其在生产者(client)火焰图中的占比从2.41%下降到0.42%

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 <ar...@gmail.com>
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);