wittyResry / myIssue

My issue mark down^_^ 欢迎吐槽,讨论~~
https://github.com/wittyResry/myIssue/issues
The Unlicense
5 stars 1 forks source link

错误总结 #91

Open wittyResry opened 5 years ago

wittyResry commented 5 years ago

ConcurrentMap源码不允许key或者value为null

HashTable的key和value不允许未null

    public synchronized V get(Object key) {
        Entry<?,?> tab[] = table;
        int hash = key.hashCode();
        int index = (hash & 0x7FFFFFFF) % tab.length;
        for (Entry<?,?> e = tab[index] ; e != null ; e = e.next) {
            if ((e.hash == hash) && e.key.equals(key)) {
                return (V)e.value;
            }
        }
        return null;
    }
    public synchronized V put(K key, V value) {
        // Make sure the value is not null
        if (value == null) {
            throw new NullPointerException();
        }

        // Makes sure the key is not already in the hashtable.
        Entry<?,?> tab[] = table;
        int hash = key.hashCode();
        int index = (hash & 0x7FFFFFFF) % tab.length;
        @SuppressWarnings("unchecked")
        Entry<K,V> entry = (Entry<K,V>)tab[index];
        for(; entry != null ; entry = entry.next) {
            if ((entry.hash == hash) && entry.key.equals(key)) {
                V old = entry.value;
                entry.value = value;
                return old;
            }
        }

        addEntry(hash, key, value, index);
        return null;
    }

测试

    @Test
    public void test2() {
        Map<String, String> m = new ConcurrentHashMap<>();
        Throwable result1 = null;
        try {
            m.put("", null);
        } catch (Throwable e) {
            result1 = e;
        }
        Assert.assertEquals("test put value null", true, result1 instanceof NullPointerException);
        Throwable result2 = null;
        try {
            m.get(null);
        } catch (Throwable e) {
            result2 = e;
        }
        Assert.assertEquals("test get key null", true, result2 instanceof NullPointerException);
    }
wittyResry commented 5 years ago
Unreachable
Thread
Busy Monitor
Native Stack

加载的"com.lambdaworks.redis.protocol.CommandHandler"实例"0xbcfa49b0"占用了1,535,774,776 (85.55%)字节.其内存主要积累在由类加载"bootstrap class loader"加载的"java.lang.Object[]"实例"0xfb35f108".
关键字
com.lambdaworks.redis.protocol.CommandHandler

fixed: Synchronize access to transport buffer:

diff --git a/pom.xml b/pom.xml
index 43eb6ce3..16eb7011 100644
--- a/pom.xml
+++ b/pom.xml
@@ -8,8 +8,8 @@
     </parent>

     <groupId>biz.paluch.redis</groupId>
-    <artifactId>lettuce</artifactId>
-    <version>3.5.0.Final</version>
+    <artifactId>lettuce-fixed</artifactId>
+    <version>3.5.1.fixed</version>
     <packaging>jar</packaging>

     <name>lettuce</name>
@@ -54,7 +54,7 @@
         <!-- You need a running redis+sentinel for all tests, therefore disabled by default -->
         <skipTests>true</skipTests>
         <github.site.upload.skip>true</github.site.upload.skip>
-        <lettuce-release-version>3.5.0.Final</lettuce-release-version>
+        <lettuce-release-version>3.5.1.fixed</lettuce-release-version>
         <netty-version>4.0.37.Final</netty-version>
     </properties>

@@ -62,7 +62,7 @@
         <connection>scm:git:https://github.com/mp911de/lettuce.git</connection>
         <developerConnection>scm:git:https://github.com/mp911de/lettuce.git</developerConnection>
         <url>http://github.com/mp911de/lettuce</url>
-        <tag>3.5.0.Final</tag>
+        <tag>3.5.1.fixed</tag>
     </scm>

     <prerequisites>
diff --git a/src/main/java/com/lambdaworks/redis/protocol/CommandHandler.java b/src/main/java/com/lambdaworks/redis/protocol/CommandHandler.java
index 10fc41b0..bf4b6f5f 100644
--- a/src/main/java/com/lambdaworks/redis/protocol/CommandHandler.java
+++ b/src/main/java/com/lambdaworks/redis/protocol/CommandHandler.java
@@ -365,7 +365,7 @@ public class CommandHandler<K, V> extends ChannelDuplexHandler implements RedisC
             throws Exception {

         if (command.isCancelled()) {
-            transportBuffer.remove(command);
+            removeFromTransportBuffer(command);
             return;
         }

@@ -394,7 +394,7 @@ public class CommandHandler<K, V> extends ChannelDuplexHandler implements RedisC
             for (RedisCommand<K, V, ?> command : commands) {

                 if (command.isCancelled()) {
-                    transportBuffer.remove(command);
+                    removeFromTransportBuffer(command);
                     continue;
                 }

@@ -425,7 +425,7 @@ public class CommandHandler<K, V> extends ChannelDuplexHandler implements RedisC
                 sentTimes.put(command, new SentReceived(nanoTime()));
                 queue.add(command);
             }
-            transportBuffer.remove(command);
+            removeFromTransportBuffer(command);
         } catch (Exception e) {
             command.setException(e);
             command.cancel(true);
@@ -434,6 +434,15 @@ public class CommandHandler<K, V> extends ChannelDuplexHandler implements RedisC
         }
     }

+    private void removeFromTransportBuffer(RedisCommand<K, V, ?> command) {
+        try {
+            writeLock.lock();
+            transportBuffer.remove(command);
+        } finally {
+            writeLock.unlock();
+        }
+    }
+
     private long nanoTime() {
         return System.nanoTime();
     }
wittyResry commented 5 years ago

改动前端代码div样式问题,特殊账号导致的异常

wittyResry commented 5 years ago

spring配置化或者获取开关配置(实例引用问题)

Spring内存注入对象给出去后,必须要给一份BeanCopy,或者需要new一个对象给出去

     public Map<String, String> getConfigByDisplayType(String displayType) {
-            return loginTipConfigByDisplayTypeMap.get(displayType);
+            Map<String, String> map = loginTipConfigByDisplayTypeMap.get(displayType);
+            if (map != null) {
+                return Maps.newHashMap(map);
+            }
             ...
     }
wittyResry commented 4 years ago

线上遇到一种特殊的情况,请求对方没有返回失败的错误码,但是被拦截了。这种情况下,通过分析下游的调用链路,猜想运行的调用链路。

wittyResry commented 4 years ago
  1. 设ABC三个系统(服务),A->B->C,B->C超时设置默认3000,CfullGC,导致hang住导致失败,B的线程池。
  2. 升级框架后,加载配置采用bean声明即服务,导致默认refer拦截异常。
wittyResry commented 4 years ago

1.导致启动加载超时,线程hang住,查看阻塞态线程 image

public void init(String dataItemName) {
        // 缓存是否已经初始化
        if (isInit(dataItemName)) {
            return;
        }
        synchronized (this) {
            if (!isInit(dataItemName)) {
                // 调用远程加载器加载数据
                DataLoaderResult<UniformModel> result = dataLoader.completeLoadData(dataItemName,
                    null, UniformModel.class);
                List<UniformModel> masterdataVOs = result.getDataList();
                // 初始化缓存
                initCache(dataItemName, masterdataVOs);
                // 设置变更序列号
                setChangeLogSeq(dataItemName, result.getChangeLogSeq());
                // 打印缓存
                dumpCache(dataItemName, Integer.toString(getChangeLogSeq(dataItemName)));
            }
        }
    }

2.排查方法 jstack 查看线程堆栈,线程dump文件之后

waiting for monitor entry

wittyResry commented 1 year ago
1 配置VPC对等链接,协议PING用的是ICMP协议,配置TCP协议不生效
2 NET安全组只针对ADP出方向,故需要配置ECS单体的白名单
3 VPC对等连接,配置完成后还需要配置路由,确保下一跳能找到
网络相关的内容需要补充
wittyResry commented 1 year ago

Netty用了ByteBuf,要用safeRelease释放内存

        try {
            String str = ByteArrayUtil.bytes2HexStr(bytes);
            ByteBuf in = ByteBufAllocator.DEFAULT.directBuffer(str.getBytes().length);
            byte[] bt = BCD.toBcdBytes(str);
            in.writeBytes(bt);
            Sl651DataPacket msg = decode(in);
            return msg;
        } finally {
            //ReferenceCountUtil.safeRelease(buffer);
        }

2023-04-14 10:23:09.791 ERROR ResourceLeakDetector - LEAK: ByteBuf.release() was not called before it's garbage-collected. See https://netty.io/wiki/reference-counted-objects.html for more information.
Recent access records:
Created at:
        io.netty.buffer.PooledByteBufAllocator.newHeapBuffer(PooledByteBufAllocator.java:384)
        io.netty.buffer.AbstractByteBufAllocator.heapBuffer(AbstractByteBufAllocator.java:169)
        io.netty.buffer.AbstractByteBufAllocator.heapBuffer(AbstractByteBufAllocator.java:160)
wittyResry commented 12 months ago
反思
1、如何读懂上层的管理要求,再三强调的,要能做到。(比如9点半到、每周提交OKR、每周提交工时,按时提交周报,不要让老板催)多次强调的事项,要保证能完成,不要做不到位。
2、ip和端口,为什么一再强调不能自动创建的,但还会踩坑?
3、提交代码检查下核心改动点,不要引入bug。尽量不要在凌晨git push,哪个时候头脑不清晰,检查不够充分