返回

Netty源码解析-启动服务

后端

服务启动,特别是NIO服务,其本质是启动NIO通讯服务端,等待来自外部的连接,然后处理来自这些连接的数据和网络事件。

通常,进行NIO通讯服务,需要两个组件:

  1. Selector:selector的作用是等待来自通道的数据和网络事件,当这些事件发生时,它会通知应用程序,并返回发生了事件的通道。
  2. EventLoop:EventLoop的基本功能是轮询监听事件、调用IO线程或者将任务分发到业务线程,用来处理IO事件,提供IO线程与非IO线程通信、调度器等工具。

一个简单的NIO通讯服务启动过程:

  1. 创建Selector。
  2. 创建ServerSocketChannel并绑定端口。
  3. 将ServerSocketChannel注册到Selector。
  4. 启动Selector轮询线程。
  5. 等待客户端连接。
  6. 接受客户端连接,并为客户端创建一个新的SocketChannel。
  7. 将SocketChannel注册到Selector。
  8. 轮询Selector,处理来自客户端的数据和网络事件。
  9. 处理来自客户端的数据和网络事件。

在Netty中,这些步骤被抽象成了更加通用的方法,在类Channel的API中,Selector被抽象成EventLoop,ServerSocketChannel被抽象成ServerChannel,SocketChannel被抽象成Channel,不同之处在于,这些对象都对应了Netty自己的实现。

将这些组件抽象成Netty专有的实现,可以在一定程度上降低用户的操作难度,同时也可以让用户免受Selector、SocketChannel等复杂实现的困扰,可以专注于业务逻辑的开发,而不必担心底层实现的细节。


启动服务

在Netty中,启动服务的过程相对简单,只需要以下几个步骤:

  1. 创建一个EventLoopGroup。
  2. 创建一个ServerBootstrap。
  3. 设置ServerBootstrap的各种属性。
  4. 绑定端口并启动服务。

以下代码展示了如何启动一个简单的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端口,等待客户端的连接请求。

扩展阅读