Netty源码解析-启动服务
2023-11-09 23:59:15
服务启动,特别是NIO服务,其本质是启动NIO通讯服务端,等待来自外部的连接,然后处理来自这些连接的数据和网络事件。
通常,进行NIO通讯服务,需要两个组件:
- Selector:selector的作用是等待来自通道的数据和网络事件,当这些事件发生时,它会通知应用程序,并返回发生了事件的通道。
- EventLoop:EventLoop的基本功能是轮询监听事件、调用IO线程或者将任务分发到业务线程,用来处理IO事件,提供IO线程与非IO线程通信、调度器等工具。
一个简单的NIO通讯服务启动过程:
- 创建Selector。
- 创建ServerSocketChannel并绑定端口。
- 将ServerSocketChannel注册到Selector。
- 启动Selector轮询线程。
- 等待客户端连接。
- 接受客户端连接,并为客户端创建一个新的SocketChannel。
- 将SocketChannel注册到Selector。
- 轮询Selector,处理来自客户端的数据和网络事件。
- 处理来自客户端的数据和网络事件。
在Netty中,这些步骤被抽象成了更加通用的方法,在类Channel的API中,Selector被抽象成EventLoop,ServerSocketChannel被抽象成ServerChannel,SocketChannel被抽象成Channel,不同之处在于,这些对象都对应了Netty自己的实现。
将这些组件抽象成Netty专有的实现,可以在一定程度上降低用户的操作难度,同时也可以让用户免受Selector、SocketChannel等复杂实现的困扰,可以专注于业务逻辑的开发,而不必担心底层实现的细节。
启动服务
在Netty中,启动服务的过程相对简单,只需要以下几个步骤:
- 创建一个EventLoopGroup。
- 创建一个ServerBootstrap。
- 设置ServerBootstrap的各种属性。
- 绑定端口并启动服务。
以下代码展示了如何启动一个简单的Netty服务:
EventLoopGroup bossGroup = new NioEventLoopGroup();
EventLoopGroup workerGroup = new NioEventLoopGroup();
ServerBootstrap bootstrap = new ServerBootstrap();
bootstrap.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) {
ch.pipeline().addLast(new EchoServerHandler());
}
});
bootstrap.bind(8080).sync();
在代码中,首先创建了一个EventLoopGroup,然后创建了一个ServerBootstrap。ServerBootstrap是一个启动NIO服务的辅助类,它可以帮助用户设置各种启动服务的参数。
接下来,我们调用ServerBootstrap的group方法,将EventLoopGroup设置为bossGroup和workerGroup。bossGroup用于处理客户端的连接请求,workerGroup用于处理客户端的数据和网络事件。
然后,我们调用ServerBootstrap的channel方法,将Channel类型设置为NioServerSocketChannel。NioServerSocketChannel是Netty中NIO服务的服务器端通道实现。
最后,我们调用ServerBootstrap的childHandler方法,设置ChannelInitializer。ChannelInitializer是一个特殊的Handler,它会在新的Channel创建时被调用,并负责为Channel添加各种Handler。
在ChannelInitializer中,我们添加了一个EchoServerHandler,它是一个简单的Handler,当收到数据时会将数据原样返回给客户端。
调用ServerBootstrap的bind方法后,服务端就会开始监听8080端口,等待客户端的连接请求。
扩展阅读
- Netty官方文档:https://netty.io/
- Netty源码分析:https://github.com/netty/netty/tree/4.1.69.Final
- Java NIO编程指南:https://docs.oracle.com/javase/8/docs/api/java/nio/package-summary.html