由于工作中用到了Netty,而且用起来也比较简单,程序跑起来问题不大,觉得挺好用。写一段代码就可以实现:
@Override
public void start(){
boolean useEpoll = Epoll.isAvailable();
if(useEpoll) {
bossGroup = new EpollEventLoopGroup(1);
workerGroup = new EpollEventLoopGroup(Runtime.getRuntime().availableProcessors() * 2);
}else {
bossGroup = new NioEventLoopGroup(1);
workerGroup = new NioEventLoopGroup(Runtime.getRuntime().availableProcessors() * 2);
}
ServerBootstrap bootstrap = new ServerBootstrap();
bootstrap.group(bossGroup,workerGroup)
.channel(useEpoll ? EpollServerSocketChannel.class : NioServerSocketChannel.class)
.option(ChannelOption.SO_BACKLOG, 1024)
.childOption(ChannelOption.TCP_NODELAY, true)
.childOption(ChannelOption.SO_KEEPALIVE, true)
.childOption(ChannelOption.WRITE_BUFFER_WATER_MARK,
new WriteBufferWaterMark(low,high))
.childHandler(new NettyChannelInitializer());
try {
serverChannel = bootstrap.bind(port).sync().channel();
running = true;
log.info("Netty server started on port: " + port);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
@Override
public void stop() {
if (serverChannel != null) {
serverChannel.close();
}
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
当业务量大,连接多的时候怎么办呢,一万,十万,甚至百万连接,你的程序还可靠吗? 了解底层原理,知道优秀在哪里就很必要了
Netty 是一个高性能、异步事件驱动的网络应用框架,用于快速开发可维护的高性能协议服务器和客户端,有以下几个特点:
- 异步非阻塞IO : 核心是IO多路复用 一个线程可以同时监控多个 Channel 的 IO 事件(如可读、可写、连接完成),只有当事件发生时才触发处理逻辑,避免线程阻塞在单个连接上。那IO多路复用又如何实现的呢?操作系统层面,Linux 使用epoll ,Windows使用IOCP
- 事件驱动模型(Reactor 模式):Boss Group 仅处理 ACCEPT 事件 Worker Group 处理 READ/WRITE 事件(IO 操作)
- 池化技术和零拷贝 :池化技术:PooledByteBufAllocator 复用内存,减少 GC ,Netty 通过 CompositeByteBuf、FileRegion 等类实现零拷贝,核心是 减少数据在用户态和内核态之间的拷贝次数
- 高效编码解码 :内置的 ByteBuf 比 JDK 的 ByteBuffer 更灵活,配合自定义 Codec 减少冗余处理