关于netty服务端使用SocketChannel报Failed to submit a listener notification task. Event loop shut down?问题

Failed to submit a listener notification task. Event loop shut down?
java.util.concurrent.RejectedExecutionException: event executor terminated
这是博主在开发过程中发现的报错。

关于这个问题,关键在于服务端在每次连客户端是都会新一个SocketChannel通道来区分多个客户端,因为博主之前是每生成一个Channel就存到了socketChannelMaps中,代码如下:

  @Override
                    protected void initChannel(SocketChannel ch) throws Exception {
                        if (!socketChannelMaps.containsKey(String.valueOf(ch.remoteAddress().getAddress()).replace("/",""))) {
                            socketChannelMaps.put(String.valueOf(ch.remoteAddress().getAddress()).replace("/",""), ch);
                        }
                        initHandler(ch.pipeline());
//                        channelHandlers.forEach(ch.pipeline()::addLast);
                    }

因为连接的channel一直都是同一个没有改变,所以不管是服务端向客户端发命令还是客户端给服务端发命令都没问题,但是当关闭了采集通道后,重新打开,这个时候要命了,因为重新生成了一个channel,而本人又是用客户端的ip做map的key,所以逻辑就会跳过。
而当自己想让服务端向客户端发命令时,识别到这个通道(channel)后,用它发命令,因为通道重新生成的channel并不是这个socketChannelMaps中存的channel,所以导致报错。
我的解决办法是:
每当发现map中存在相同远程ip一样的channel,就把旧的删除,换上新的。
代码如下:

 protected void initChannel(SocketChannel ch) throws Exception {
                        String remoteAddress = String.valueOf(ch.remoteAddress().getAddress()).replace("/","");
                        if (!socketChannelMaps.containsKey(remoteAddress)) {
                            socketChannelMaps.put(remoteAddress, ch);
                        } else {
                            socketChannelMaps.remove(remoteAddress);
                            socketChannelMaps.put(remoteAddress, ch);
                        }
                        initHandler(ch.pipeline());
                    }

本人还在思考一个问题,因为本人socketChannelMaps结构的问题,该netty连接只能做到一对一(一个服务端端口接一个客户端ip)和一对多(一个服务端端口接多个客户端ip),或者去实现多对多呢?把服务端端口和客户端ip结合起来行不行,后面慢慢去修改把。

io.netty.util.internal.outofdirectmemoryerror: failed to allocate 16777216 b 是一个错误提示,意味着在使用 io.netty 这个库时,尝试分配 16,777,216 字节的直接内存时出现了错误。 出现这个错误通常是由于系统中的直接内存不足导致的。直接内存是一种通过 Native Memory 来直接分配内存的方式,与 Java 堆内存不同。由于直接内存不受 JVM 垃圾回收的控制,因此需要手动释放。 解决这个问题的方法有以下几种: 1. 增加直接内存的容量:可以通过修改 JVM 的启动参数,增加直接内存的最大容量。可以使用 -XX:MaxDirectMemorySize 参数指定最大直接内存大小。例如,可以设置为 -XX:MaxDirectMemorySize=1g 来将最大直接内存大小设置为 1GB。 2. 检查代码中的资源是否正确释放:如果在代码中使用了 io.netty 这个库,需要确保在使用完毕后正确释放资源。可以通过调用相关的 close() 或者 release() 方法来释放所占用的直接内存。 3. 调整程序的设计:如果程序中的网络请求或者数据处理量非常大,考虑对程序进行优化,减少对直接内存的依赖。可以通过合理缓存、分批处理等方式来减少直接内存的使用。 总之,当出现 io.netty.util.internal.outofdirectmemoryerror: failed to allocate 16777216 b 错误时,需要检查直接内存的容量是否足够,释放资源是否正确,以及是否需要对程序进行优化,减少对直接内存的依赖。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值