Netty服务端初始化详解

简介: Netty服务端初始化详解

前言

这是源码共读活动的第二篇文章, 在上一章节中我们分析了  backlog 的作用, 接下来我们看一看张师傅为我们准备的Netty启动类都进行了哪些配置吧

没有拉取代码的小伙伴可以通过git输入以下命令拉一下代码, 让我们保持代码的同步

git clone https://github.com/arthur-zhang/netty-study.git
复制代码

配置分析

首先, 我们可以看到这个项目的目录结构很简单, 只有三个类, 通过名称可以知道, 分别是两个 Headler 类和一个 启动类 MyServer, 本篇文章也是主要针对MyServer来进行讲解的

网络异常,图片无法展示
|

MyServer详解

下图是MyServer类的全部代码, 可以看到实际上没有多少,一图装得下, 接下来我们一起逐行代码去学习

网络异常,图片无法展示
|

ServerBootstrap serverBootstrap = new ServerBootstrap();

Bootstrap的意思是引导, 在Netty应用中, 通常也是由Bootstrap开始的, 他的作用就是对Netty进行配置

网络异常,图片无法展示
|

翻译工具为`uTools`插件 词典

本次主要对Netty中的ServerBootstrap进行讲解, ServerBootstrap是服务端引导类, 他的继承关系如下所示

网络异常,图片无法展示
|

Netty中, AbstractBootstrap的实现类主要有两种, 分别是服务端ServeBootstrap和客户端Bootstrap, 对Bootstrap感兴趣的小伙伴可以评论区留言

网络异常,图片无法展示
|

serverBootstrap.channel() 方法;

serverBootstrap.channel()方法是用来设置Netty对应的通道的

在执行该方法的时候可以看到, 他实际上是调用了ServeBootstrap类的抽象父类AbstractBootstrap

channel方法中实际上是初始化了一个ReflectiveChannelFactory工厂类, 同时将该工厂对象保存在AbstractBootstrap抽象类的channelFactory属性中, 后续可以调用生成channel对象, 目前只是保存

网络异常,图片无法展示
|

下面我们看一下在ReflectiveChannelFactory工厂类的初始化和后续调用生成channel对象的方法

网络异常,图片无法展示
|

NioServerSocketChannel.class

NioServerSocketChannelNetty官方封装的, 用来代替或包装 JDK 原生的SocketChannel对象, 他的继承关系图如下所示

网络异常,图片无法展示
|

过多的就不讲了, 在讲下去就该这个类的源码分析, 感兴趣的小伙伴可以评论区说出来

option()和 childOption() 方法

Nettyoption()方法主要是设置ServerChannel的一些选项, 而childOption()方法是用来设置ServerChannel子Channel的选项

注: 如果是客户端, 因为是Bootstrap, 只会有option(), 没有childOption(), 所以设置的是客户端Channel的选项

网络异常,图片无法展示
|

所以, childOption()方法是写在ServerBootstrap类中, 而不是继承于AbstractBootstrap抽象类的

网络异常,图片无法展示
|

option()方法是写在了AbstractBootstrap抽象类中, 记住他, 后面我们分析Netty启动的时候还会看到

网络异常,图片无法展示
|

NioChannelOption

NioChannelOption类是继承于ChannelOption同时新增了几个方法, 那么我们主要讲一下ChannelOption里面的常量信息

网络异常,图片无法展示
|

@SuppressJava6Requirement 注解的作用: 清除 java6 的警告, 现在我们大多使用的都是 java8 以上了, 这个注解可以无视掉

1、ChannelOption.SO_BACKLOG

SO_BACKLOG参数用来初始化服务端可连接队列。

服务端处理客户端连接请求是顺序处理的,所以同一时间只能处理一个客户端连接,多个客户端来的时候,服务端将不能处理的客户端连接请求放在队列中等待处理,backlog 参数指定了队列的大小。

同时在设置backlog参数的时候, 也要根据需求来设置, 避免因为队列设置的太小导致消息溢出

在推一手上一篇文章 Netty源码分析(一) backlog 参数

2、ChannelOption.SO_REUSEADDR

SO_REUSEADDR参数表示允许重复使用本地地址和端口。

比如,某个服务器进程占用了TCP的80端口进行监听,此时再次监听该端口就会返回错误,使用该参数就可以解决问题,该参数允许共用该端口,这个在服务器程序中比较常使用。

3、ChannelOption.SO_KEEPALIVE

SO_KEEPALIVE 默认为 false, 启用该功能时, TCP 会主动探测空闲连接的有效性, 可以将此功能视为TCP的心跳机制,需要注意的是:默认的心跳间隔是7200s即2小时。Netty默认关闭该功能

4、ChannelOption.SO_SNDBUF和ChannelOption.SO_RCVBUF

SO_SNDBUFSO_RCVBUF这两个参数用于操作发送缓冲区大小和接受缓冲区大小。

接收缓冲区用于保存网络协议站内收到的数据,直到应用程序读取成功,发送缓冲区用于保存发送数据,直到发送成功。

5、ChannelOption.SO_LINGER

Linux内核默认的处理方式是当用户调用close()方法的时候,函数返回,在可能的情况下,尽量发送数据,不一定保证会发送剩余的数据,造成了数据的不确定性,使用SO_LINGER可以阻塞close()的调用时间,直到数据完全发送.

6、ChannelOption.TCP_NODELAY

TCP_NODELAY参数的使用与Nagle算法有关。

该参数的作用就是禁止使用Nagle算法,使用于小数据即时传输。和TCP_NODELAY相对应的是TCP_CORK,该选项是需要等到发送的数据量最大的时候,一次性发送数据,适用于文件传输。

Nagle算法是将小的数据包组装为更大的帧然后进行发送,而不是输入一次发送一次,因此在数据包不足的时候会等待其他数据的到来,组装成大的数据包进行发送,虽然该算法有效提高了网络的有效负载,但是却造成了延时。

handler() 和 childHandler()

本来是到 serverBootstrap.heandler()方法了, 但是我一想下面还有一个serverBootstrap.childHandler()方法, 正好一起讲了, 顺便对比一下两个headler方法

网络异常,图片无法展示
|

同时大家应该看到了, 在实现childHeadler()方法的时候有创建一个类并实现了相应的方法, 他的作用就是初始化了一下Channel并把日志级别更改为 info

网络异常,图片无法展示
|

在 ServerBootstrap 中

handler()方法是针对bossGroup线程组起作用

childHandler()方法是针对workerGroup线程组起作用

在 Bootstrap 中

只有handler()方法, 因为客户端只需要一个事件线程组

NioEventLoopGroup 和 serverBootstrap.group()

NioEventLoopGroup是一个可处理I/O操作的多线程事件循环。Netty提供了多种 EventLoopGroup 的实现用于不同类型的传输。

serverBootstrap.group()方法就是分配 bossGroup 和 workGroup 两个线程组的

bossGroup 和 workGroup

bossGroup是负责处理客户端和服务端建立连接注册的 selector

workGroup是负责处理客户端读事件的 selector 逻辑

全部代码

public static void main(String[] args) throws InterruptedException {
    // 启动类
    ServerBootstrap serverBootstrap = new ServerBootstrap();
    // 设置对应的通道
    serverBootstrap.channel(NioServerSocketChannel.class);
    // 设置线程的连接个数
    serverBootstrap.option(NioChannelOption.SO_BACKLOG, 511);
    // TCP_NODELAY=true,如果TCP_NODELAY没有设置为true,那么底层的TCP为了能减少交互次数,会将网络数据积累到一定的数量后,
    // 服务器端才发送出去,会造成一定的延迟。在互联网应用中,通常希望服务是低延迟的,建议将TCP_NODELAY设置为true。
    serverBootstrap.childOption(NioChannelOption.TCP_NODELAY, true);
    // 以给定的日志级别打印出 LoggingHandler 中的日志
    serverBootstrap.handler(new LoggingHandler(LogLevel.INFO));
    // 监听
    NioEventLoopGroup bossGroup = new NioEventLoopGroup(0, new DefaultThreadFactory("boss"));
    // 处理每一条数据读写的线程组
    NioEventLoopGroup workGroup = new NioEventLoopGroup(0, new DefaultThreadFactory("worker"));
    try {
        // 设置对应的线程组
        serverBootstrap.group(bossGroup, workGroup);
        final MyEchoServerHandler serverHandler = new MyEchoServerHandler();
        serverBootstrap.childHandler(new ChannelInitializer<NioSocketChannel>() {
            @Override
            protected void initChannel(NioSocketChannel ch) {
                ChannelPipeline pipeline = ch.pipeline();
                pipeline.addLast(new ServerIdleCheckHandler());
                pipeline.addLast(new LoggingHandler(LogLevel.INFO));
                pipeline.addLast(serverHandler);
            }
        });
        // 启动 Netty
        ChannelFuture f = serverBootstrap.bind(8888).sync();
        // 资源优雅释放
        f.channel().closeFuture().sync();
    } finally {
        // 资源优雅释放
        bossGroup.shutdownGracefully();
        workGroup.shutdownGracefully();
    }
}
复制代码

idea技巧

查看类的继承关系图

双击选中想要查看的类 ==> 右键 ==> Diagrams ==> ShowDiagramPopup

网络异常,图片无法展示
|

总结

本篇文章我们对Netty的启动类进行了逐行分析, 也让我对Netty的大概配置有了更全面的了解, 每天进步一丢丢, 加油



目录
相关文章
|
6月前
|
Java Maven
【Netty 网络通信】启动通信服务端
【1月更文挑战第9天】【Netty 网络通信】启动通信服务端
|
存储 网络协议 前端开发
Netty服务端和客户端开发实例—官方原版
Netty服务端和客户端开发实例—官方原版
295 0
|
1月前
|
网络协议 前端开发
netty的TCP服务端和客户端实现
本文介绍了使用Netty框架实现TCP服务端和客户端的步骤,包括添加Netty依赖、编写服务端和客户端的代码,涉及NioEventLoopGroup、ServerBootstrap、Bootstrap、ChannelInitializer等核心组件,以及如何启动服务端监听和客户端连接。
138 4
|
2月前
|
存储 机器人 Linux
Netty(二)-服务端网络编程常见网络IO模型讲解
Netty(二)-服务端网络编程常见网络IO模型讲解
|
6月前
|
网络协议 Java 物联网
Spring Boot与Netty打造TCP服务端(解决粘包问题)
Spring Boot与Netty打造TCP服务端(解决粘包问题)
1014 2
|
6月前
|
安全 Java Go
springboot+netty化身Udp服务端,go化身客户端模拟设备实现指令联动
springboot+netty化身Udp服务端,go化身客户端模拟设备实现指令联动
159 0
|
6月前
|
测试技术
Netty4 websocket 开启服务端并设置IP和端口号
Netty4 websocket 开启服务端并设置IP和端口号
174 0
|
6月前
|
前端开发 Java Maven
【Netty 网络通信】启动客户端连接服务端实现通信
【1月更文挑战第9天】【Netty 网络通信】启动客户端连接服务端实现通信
|
网络协议 前端开发 Java
Netty异步NIO框架(一)java服务端与客户端实现聊天 websocket通道
Netty异步NIO框架(一)java服务端与客户端实现聊天 websocket通道
|
网络协议 Java
netty编程实战01-创建一个tcp服务端程序
netty编程实战01-创建一个tcp服务端程序
256 0