xuxueli / xxl-rpc

A high performance, distributed RPC framework.(分布式服务框架XXL-RPC)
http://www.xuxueli.com/xxl-rpc/
Apache License 2.0
620 stars 404 forks source link

NioEvenLoopGroup应该使用全局共享单例,它不能完全关闭,频繁new和closeGracefully会造成内存耗尽! #35

Closed canuran closed 4 years ago

canuran commented 4 years ago

因网络不通而频繁创建NioEvenLoopGroup导致内存耗尽,是我在项目中真实遇到的问题。 另外如果连接目标(包括失效的)过多也会导致内存耗尽,该问题在docker/k8s随机网络分配的环境下更明显 。 NioEvenLoopGroup应该使用单例模式,以下是我的解决方案:

定义自动检查的单例:

// 须使用getEventLoopGroup方法获取,勿直接使用
private static EventLoopGroup group = new NioEventLoopGroup();
private static ReentrantLock reentrantLock = new ReentrantLock();

public static EventLoopGroup getEventLoopGroup() {
    try {
        // 共享NioEventLoopGroup,因为是频繁要用的所以不要关闭group
        if (reentrantLock.tryLock(5, TimeUnit.SECONDS)) {
            // 如果关闭了则重新创建NioEventLoopGroup
            if (group == null || group.isShutdown() || group.isShuttingDown()) {
                group = new NioEventLoopGroup();
            }
            return group;
        } else {
            throw new IllegalStateException("Get the EventLoopGroup fail");
        }
    } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
        throw new IllegalStateException("Get the EventLoopGroup fail");
    } finally {
        reentrantLock.unlock();
    }
}

使用时调用 getEventLoopGroup() 方法。

xuxueli commented 4 years ago

你好,问题已修复并推送master分支,可以pull master体验下。将会跟随下个版本发布。

geercode commented 4 years ago
xxl线程泄漏

雪里兄好,我在使用过程中发现有线程泄漏的问题,跟这位老兄的情况比较相似,但是我还没有看到很多的代码。我使用的xxl-job版本为2.0.2,xxl-rpc是1.4.0。由于开发环境没有xxl-admin,所以在发布时间一两天后,发现了有内存溢出,full gc过于频繁的问题,一开始发现byte[] object[] char[]过多,只定位到是netty出的问题,后用jprofiler查看内存,发现有线程数过多的情况,最终定位到是xxl造成的nettygroup线程过多造成的,截图如下:

xxl线程泄漏2

后沿着注册的Exception定位到是NettyHttpConnectClient#init方法中this.channel = bootstrap.connect(host, port).sync().channel();中sync()方法失败则造成nettyGroup的channel线程失去管理。由于我没有对netty深入研究过,这个地方是否应该在更高层级对资源进行限定,channel是否也应该避免用很多线程的粗放模式。原来提这个issue的老兄跟我说的比较像,是同一个问题吗,以及现在是否已经解决?