diff --git a/neutrino-proxy-client/src/main/java/org/dromara/neutrinoproxy/client/core/CmdChannelHandler.java b/neutrino-proxy-client/src/main/java/org/dromara/neutrinoproxy/client/core/CmdChannelHandler.java index c1cb7c27..f45f6217 100644 --- a/neutrino-proxy-client/src/main/java/org/dromara/neutrinoproxy/client/core/CmdChannelHandler.java +++ b/neutrino-proxy-client/src/main/java/org/dromara/neutrinoproxy/client/core/CmdChannelHandler.java @@ -1,5 +1,6 @@ package org.dromara.neutrinoproxy.client.core; +import io.netty.handler.codec.DecoderException; import org.dromara.neutrinoproxy.client.config.ProxyConfig; import org.dromara.neutrinoproxy.client.util.ProxyUtil; import org.dromara.neutrinoproxy.core.Constants; @@ -13,6 +14,7 @@ import io.netty.handler.timeout.IdleStateEvent; import lombok.extern.slf4j.Slf4j; import org.noear.solon.Solon; +import java.io.IOException; import java.net.SocketException; /** @@ -60,11 +62,29 @@ public class CmdChannelHandler extends SimpleChannelInboundHandler @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { - if (cause instanceof SocketException && cause.getMessage().contains("Connection reset")) { - ctx.channel().close(); - return; + // 对于网络IO异常(致命异常),关闭channel以防止资源泄漏 + // 对于其他异常(可能是可恢复的业务异常),只记录日志 + if (cause instanceof IOException) { + // IOException及其子类(包括SocketException)都是致命的网络异常 + if (cause instanceof SocketException && cause.getMessage() != null && cause.getMessage().contains("Connection reset")) { + // Connection reset是常见的客户端断开,使用debug级别 + log.debug("[Cmd Channel] Client connection reset: {}", cause.getMessage()); + } else { + log.error("[Cmd Channel] IO Error", cause); + } + if (ctx.channel().isActive()) { + ctx.channel().close(); + } + } else if(cause instanceof DecoderException) { + // 协议解析错误,为防止数据污染,立即关闭 + log.debug("[Cmd Channel] decoder error: {}", cause.getMessage()); + if (ctx.channel().isActive()) { + ctx.channel().close(); + } + } else { + // 其他异常只记录日志,不关闭channel,让Netty自己处理 + log.error("[Cmd Channel] error", cause); } - log.error("[CMD Channel]Client CmdChannel Error channelId:{}", ctx.channel().id().asLongText(), cause); } @Override diff --git a/neutrino-proxy-client/src/main/java/org/dromara/neutrinoproxy/client/core/RealServerChannelHandler.java b/neutrino-proxy-client/src/main/java/org/dromara/neutrinoproxy/client/core/RealServerChannelHandler.java index ba5ee077..137393da 100644 --- a/neutrino-proxy-client/src/main/java/org/dromara/neutrinoproxy/client/core/RealServerChannelHandler.java +++ b/neutrino-proxy-client/src/main/java/org/dromara/neutrinoproxy/client/core/RealServerChannelHandler.java @@ -1,15 +1,15 @@ package org.dromara.neutrinoproxy.client.core; +import io.netty.buffer.Unpooled; +import io.netty.channel.*; +import io.netty.handler.codec.DecoderException; import lombok.extern.slf4j.Slf4j; import org.dromara.neutrinoproxy.client.util.ProxyUtil; import org.dromara.neutrinoproxy.core.Constants; import org.dromara.neutrinoproxy.core.ProxyMessage; import io.netty.buffer.ByteBuf; -import io.netty.channel.Channel; -import io.netty.channel.ChannelHandlerContext; -import io.netty.channel.ChannelOption; -import io.netty.channel.SimpleChannelInboundHandler; +import java.io.IOException; import java.net.SocketException; /** @@ -57,9 +57,10 @@ public class RealServerChannelHandler extends SimpleChannelInboundHandler