netty - Netty 4.1 - 检测拒绝连接导致完全连接
问题描述
我已经实现 Netty 4.1 作为 TCP Server 来处理数千个客户端,但不知道如何检测服务器是否无法接收客户端导致连接已满,因此应用程序通知管理员服务器已满,在传统的 ServerSocket 中我们可以检测到异常连接太多/打开的文件太多:
public class TCPServer {
private int port;
public TCPServer (int port) {
this.port = port;
}
public void run() throws Exception {
EventLoopGroup bossGroup = new NioEventLoopGroup();
EventLoopGroup workerGroup = new NioEventLoopGroup();
try {
ServerBootstrap b = new ServerBootstrap();
b.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
public void initChannel(SocketChannel ch) throws Exception {
ch.pipeline().addLast(new FrameDecoder());
ch.pipeline().addLast(new ProcessingData());
}
})
.option(ChannelOption.SO_BACKLOG, 128)
.childOption(ChannelOption.SO_KEEPALIVE, true);
ChannelFuture f = b.bind(port).sync();
f.channel().closeFuture().sync();
} finally {
workerGroup.shutdownGracefully();
bossGroup.shutdownGracefully();
}
}
public static void main(String[] args) throws Exception {
int port = 9812;
if (args.length > 0) {
port = Integer.parseInt(args[0]);
}
new TCPServer
(port).run();
}
}
帧解码器也作为检测连接已满
public class FrameDecoder extends ByteToMessageDecoder {
public FrameDecoder() {
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
try {
ctx.fireExceptionCaught(cause);
// i never get exception like too many open files here....
//
} catch (Exception ex) {
}
}
@Override
protected void decode(ChannelHandlerContext ctx, ByteBuf buf, List<Object> out) throws Exception {
if (buf.readableBytes() < 5) {
return;
}
int length = 2 + 2; // head and tail
if (buf.getByte(buf.readerIndex()) == 0x78 && buf.getByte(buf.readerIndex() + 1) == 0x78) {
length += 1 + buf.getUnsignedByte(buf.readerIndex() + 2);
} else{
length += 2 + buf.getUnsignedShort(buf.readerIndex() + 2);
}
if (buf.readableBytes() >= length && buf.getUnsignedShort(buf.readerIndex() + length - 2) == 0x0d0a) {
out.add(buf.readRetainedSlice(length));
return;
}
int endIndex = buf.readerIndex() - 1;
do {
endIndex = buf.indexOf(endIndex + 1, buf.writerIndex(), (byte) 0x0d);
if (endIndex > 0 && buf.writerIndex() > endIndex + 1 && buf.getByte(endIndex + 1) == 0x0a) {
out.add(buf.readRetainedSlice(endIndex + 2 - buf.readerIndex()));
}
} while (endIndex > 0);
}
}
解决方案
您应该能够ChannelInboundHandler
为ServerChannel
via添加一个b.handler(...)
。childHandler(...)
为“接受”的Channel
shandler(...)
添加处理程序,同时为ServerChannel
接受s 的添加处理程序Channel
。由于抛出异常,ServerChannel
您将需要在那里而不是在子处理程序上处理它。
推荐阅读
- r - 用于 R Shiny 发布的 RHEL Bash 脚本
- ios - iOS 自定义框架未在 Storyboard 上显示模块选项
- android - Android 从arraylist中的字符串中提取
- javascript - 如何使用 JavaScript Webdriver 访问 Selenium 的日志以查看网络请求
- sql - 将一列的值复制到不同行的另一列
- javascript - 在Javascript中的特定时间绘制正方形然后移动
- stream - 在 Beam 中流式传输
- kubernetes - Kubernetes 无法运行容器
- sql - SQL ORA-02063 - 如何解决这个问题?
- c# - 如何将sharepoint2010列表绑定到aspnet中继器控件