Netty是什么
Netty是Java的一种能提供异步事件驱动网络编程框架,Netty提供了简洁强大的API,能极大提高开发稳定可靠网络服务器和客户端程序的效率。
如何使用
以创建一个服务端举例说明
public class TimeServer {
public void bind(int port) throws Exception {
// 1.配置服务端的NIO线程组
EventLoopGroup bossGroup = new NioEventLoopGroup();
EventLoopGroup workerGroup = new NioEventLoopGroup();
try {
ServerBootstrap b = new ServerBootstrap();
//2.配置参数
b.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.option(ChannelOption.SO_BACKLOG, 1024)
.childHandler(new ChildChannelHandler());
// 3.绑定端口,同步等待成功
ChannelFuture f = b.bind(port).sync();
//4. 等待服务端关闭
f.channel().closeFuture().sync();
} finally {
//5.优雅退出,释放线程池资源
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
}
private class ChildChannelHandler extends ChannelInitializer<SocketChannel> {
@Override
protected void initChannel(SocketChannel arg0) throws Exception {
arg0.pipeline().addLast(new TimeServerHandler());
}
}
/**
* @param args
* @throws Exception
*/
public static void main(String[] args) throws Exception {
int port = 8080;
if (args != null && args.length > 0) {
try {
port = Integer.valueOf(args[0]);
} catch (NumberFormatException e) {
// 采用默认值
}
}
new TimeServer().bind(port);
}
}
从上面的代码例子来看启动服务端有5个步骤
- 1.配置服务端的NIO线程组,这里配置2个线程组,bossGroup线程组接收客户端的连接,workerGroup线程组处理连接上的的客户端的读写等处理。
- 2.配置参数,这里配置了NioServerSocketChannel渠道处理io事件,配置Accept队列大小为1024(这里的大小是somaxconn和配置BACKLOG取最小值)。
- 3.绑定端口。
- 4.阻塞等待服务端关闭。
- 5.优雅退出,释放线程池资源。
为什么不使用Java原生NIO编程
Netty网络框架目前广泛的应用在各个领域中,那么为什么不用Java原生的NIO来开发呢。具体原因如下:
- 1.Java原生NIO的API复杂,使用麻烦。
- 2.对开发人员的要求高,列如需要熟悉Java多线程知识,网络协议知识等。
- 3.使用Java原生NIO需要开发人员自己解决半包问题,网络中断问题,网络拥塞问题及Java NIO中的epoll bug导致的Selector空轮询问题,还要自己编写常用的协议编码解码(和谐)器。
Netty线程模型
Netty的客户端就是单线程的NIO模型这里就不讨论,Netty的服务端的线程模型如下
如上图AcceptorSelector线程的职责就是轮询客户端连接事件,如果轮询到客户端连接,将连接后的IO操作委托给IOSelector线程池操作。
Netty同时支持Reactor的单线程、多线程和主从多线程模型可通过配置线程个数和是否共享线程来实现。
Netty官方demo推荐使用主从多线程模型,试想如果IOSelector和AcceptorSelector使用同一个Selector来轮询,如果单个Selector处理大量的客户端的Acceptor和IO事件,出现某个操作非常损耗性能,将直接拖垮整个系统的Acceptor和IO事件处理能力。