publicfinalclassChannelRegistry{privatestaticfinalChannelRegistryINSTANCE=newChannelRegistry();// TODO :wangkai do not use cache, should use map, and add unregister feature
publicfinalCache<String,Integer>connectionIds=CacheBuilder.newBuilder().build();/**
* Get instance of channel registry.
*
* @return instance of channel registry
*/publicstaticChannelRegistrygetInstance(){returnINSTANCE;}/**
* Put connection id by channel ID.
*
* @param channelId netty channel ID
* @param connectionId database connection ID
*/publicvoidputConnectionId(finalStringchannelId,finalintconnectionId){connectionIds.put(channelId,connectionId);// 自己加的日志
log.info("put channel cache, key: {}, value: {}",channelId,connectionId);}/**
* Get connection id by channel ID.
*
* @param channelId netty channel ID
* @return connectionId database connection ID
*/publicintgetConnectionId(finalStringchannelId){Integerresult=connectionIds.getIfPresent(channelId);Preconditions.checkNotNull(result,String.format("Can not get connection id via channel id: %s",channelId));returnresult;}}
默认构造器创建了一个强引用缓存,里面缓存了netty连接和对应的数据库连接。只有 put 方法,没有释放方法。
每次有新的netty连接,都会创建一个缓存元素,造成这个缓存越来越大,而且不会释放。
为了确定是这个问题,我在 putConnectionId 方法里加了日志部署测试
部署后,发现日志里频繁的 put cache,可以确定就是这个原因导致内存无法释放。连接创建这么频繁是因为运维在前面挂了一层 Aliyun SLB 负载,SLB 会频繁的创建探活连接。