热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Netty源代码分析服务器端启动ServerBootstrap初始化

本文主要分析了Netty源代码中服务器端启动的过程,包括ServerBootstrap的初始化和相关参数的设置。通过分析NioEventLoopGroup、NioServerSocketChannel、ChannelOption.SO_BACKLOG等关键组件和选项的作用,深入理解Netty服务器端的启动过程。同时,还介绍了LoggingHandler的作用和使用方法,帮助读者更好地理解Netty源代码。


一. 开始

1.1 上一篇


接上一篇NioEventLoopGroup的实例化分析继续
https://blog.51cto.com/483181/2118817


这篇博客要分析的是 “2. ServerBootstrap初始化”,如下:


EventLoopGroup bossGroup = new NioEventLoopGroup();
EventLoopGroup workerGroup = new NioEventLoopGroup();
try {
ServerBootstrap b = new ServerBootstrap(); //2. ServerBootstrap初始化
b.group(bossGroup, workerGroup) // 2. ServerBootstrap初始化
.channel(NioServerSocketChannel.class)
.option(ChannelOption.SO_BACKLOG, 100)
.handler(new LoggingHandler(LogLevel.INFO))
.childHandler(new ChannelInitializer() {
@Override
protected void initChannel(SocketChannel ch) throws Exception {
}
});
ChannelFuture f = b.bind(port).sync(); //3. bind
f.channel().closeFuture().sync();
} catch (Exception e) {
e.printStackTrace();
} finally {
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}

二. ServerBootstrap

2.1 ServerBootstrap继承关系图


57. Netty源代码分析-服务器端启动ServerBootstrap初始化


2.2 ServerBootstrap构造函数


public ServerBootstrap() { }

ServerBootstrap提供了一个无参构造函数,其实有点奇怪,因为像这种网络服务肯定要适应不同的场景,所以肯定得有很多参数的构造函数。
对于这一点,正是因为要适配的参数太多了,所以ServerBootstrap提供了一个无参构造函数,然后使用构造者模式来解决这个问题。
如下:


public ServerBootstrap childHandler(ChannelHandler childHandler) {
if (childHandler == null) {
throw new NullPointerException("childHandler");
}
this.childHandler = childHandler;
return this;
}

2.3 ServerBootstrap.group


public ServerBootstrap group(EventLoopGroup parentGroup, EventLoopGroup childGroup) {
super.group(parentGroup);
if (childGroup == null) {
throw new NullPointerException("childGroup");
}
if (this.childGroup != null) {
throw new IllegalStateException("childGroup set already");
}
this.childGroup = childGroup;
return this;
}
父类的group(xx)
public B group(EventLoopGroup group) {
this.group = group;
return self();
}

传入了两个EventLoopGroup,也就是上一篇文章说的NioEventLoopGroup,一个是bossGroup,一个workerGroup.
其中bossGroup存在它的父类group属性
workerGroup存在ServerBootstrap的childGroup属性里面,不过暂时不知道它们之间的区别。


继续看b.channel(NioServerSocketChannel.class)


2.4 设置channel


代码在ServerBootstrap的父类AbstractBootstrap里面,如下:


public B channel(Class channelClass) {
return channelFactory(new ReflectiveChannelFactory(channelClass));
}
public B channelFactory(ChannelFactory channelFactory) {
this.channelFactory = channelFactory;
return self();
}
public class ReflectiveChannelFactory implements ChannelFactory {
private final Class clazz;
public ReflectiveChannelFactory(Class clazz) {
this.clazz = clazz;
}
@Override
public T newChannel() {
try {
return clazz.getConstructor().newInstance();
} catch (Throwable t) {
}
}
}

上面这段代码可以看出:


  1. 初始化了一个ReflectiveChannelFactory工程类,它是一个工厂类,调用newChannel的时候负责初始化一个指定Channel。也就是我们传入进来的NioServerSocketChannel对象。
  2. 这个工厂对象保存在AbstractBootstrap的channelFactory属性里面,以便于后面调用生成channel对象,目前只是保存工厂对象。

继续看b.option()方法


2.5 设置option


Map, Object> options;
public B option(ChannelOption option, T value) {
if (option == null) {
throw new NullPointerException("option");
}
if (value == null) {
synchronized (options) {
options.remove(option);
}
} else {
synchronized (options) {
options.put(option, value);
}
}
return self();
}

从上面这代码可以看出几点:
1.option方法带有remove和put两个操作,根据value是否null来判断。这种写法自己以前用的比较少,一般的话会提供两个方法出来。
2.如果是put的话,那么把值存在options这个Map集合里面。


继续回头看b.handler()方法


2.6 handler方法


handler方法位于ServerBootstrap的父类AbstractBootstrap里面,如下:


private volatile ChannelHandler handler;
public B handler(ChannelHandler handler) {
if (handler == null) {
throw new NullPointerException("handler");
}
this.handler = handler;
return self();
}

很是简单,就是把传入的ChannelHandler对象保存起来,放在属性handler里面。
另外,注意到handler对象是volatile类型的,volatile具有挥发性,如果一个线程修改了数据,那么另外一个线程可以马上看到这个修改。具体大家可以百度下。


继续回去看b.childHandler(xx)方法


2.7 childHandler


childHandler方法位于ServerBootstrap里面


private volatile ChannelHandler childHandler;
public ServerBootstrap childHandler(ChannelHandler childHandler) {
private volatile ChannelHandler childHandler;
if (childHandler == null) {
throw new NullPointerException("childHandler");
}
this.childHandler = childHandler;
return this;
}

从上面代码可以看出:


  1. childHandler保存在ServerBootstrap,变量是childHandler,当然也是volatile类型的,我们传进来的类型是 ChannelInitializer,重写了它的initChannel方法。
  2. childHandler和handler都是ChannelHandler类型,不过一个在子类,一个在父类里面。

三. 总结

ServerBootstrap的初始化分析完之后,我们来总结下。


  1. ServerBootstrap提供了一个无参构造函数,为了适应各种不同的场景。 它使用了构造者模式,构造者模式大家百度即可,比如: https://www.cnblogs.com/cc11001100/p/5939220.html

  2. ServerBootstrap保存了
    EventLoopGroup childGroup,在上面例子我们的类型是NioEventLoopGroup
    ChannelHandler childHandler;

  3. 父类AbstractBootstrap保存了同一个类型的
    volatile EventLoopGroup group;
    private volatile ChannelHandler handler;

  4. 到目前为止,我们只是初始化了所有的变量,为下一步bind做准备。bind的流程我们下篇继续分析。

转载于:https://blog.51cto.com/483181/2119149



推荐阅读
  • 1:有如下一段程序:packagea.b.c;publicclassTest{privatestaticinti0;publicintgetNext(){return ... [详细]
  • 深入理解Cookie与Session会话管理
    本文详细介绍了如何通过HTTP响应和请求处理浏览器的Cookie信息,以及如何创建、设置和管理Cookie。同时探讨了会话跟踪技术中的Session机制,解释其原理及应用场景。 ... [详细]
  • UNP 第9章:主机名与地址转换
    本章探讨了用于在主机名和数值地址之间进行转换的函数,如gethostbyname和gethostbyaddr。此外,还介绍了getservbyname和getservbyport函数,用于在服务器名和端口号之间进行转换。 ... [详细]
  • 本文探讨了在不使用服务器控件的情况下,如何通过多种方法获取并修改页面中的HTML元素值。除了常见的AJAX方式,还介绍了其他可行的技术方案。 ... [详细]
  • 本文详细介绍了如何使用PHP检测AJAX请求,通过分析预定义服务器变量来判断请求是否来自XMLHttpRequest。此方法简单实用,适用于各种Web开发场景。 ... [详细]
  • 深入解析Spring Cloud Ribbon负载均衡机制
    本文详细介绍了Spring Cloud中的Ribbon组件如何实现服务调用的负载均衡。通过分析其工作原理、源码结构及配置方式,帮助读者理解Ribbon在分布式系统中的重要作用。 ... [详细]
  • 本文详细介绍了Java编程语言中的核心概念和常见面试问题,包括集合类、数据结构、线程处理、Java虚拟机(JVM)、HTTP协议以及Git操作等方面的内容。通过深入分析每个主题,帮助读者更好地理解Java的关键特性和最佳实践。 ... [详细]
  • DNN Community 和 Professional 版本的主要差异
    本文详细解析了 DotNetNuke (DNN) 的两种主要版本:Community 和 Professional。通过对比两者的功能和附加组件,帮助用户选择最适合其需求的版本。 ... [详细]
  • 本文介绍如何通过Windows批处理脚本定期检查并重启Java应用程序,确保其持续稳定运行。脚本每30分钟检查一次,并在需要时重启Java程序。同时,它会将任务结果发送到Redis。 ... [详细]
  • 本文介绍如何使用 NSTimer 实现倒计时功能,详细讲解了初始化方法、参数配置以及具体实现步骤。通过示例代码展示如何创建和管理定时器,确保在指定时间间隔内执行特定任务。 ... [详细]
  • 本文介绍了在Windows环境下使用pydoc工具的方法,并详细解释了如何通过命令行和浏览器查看Python内置函数的文档。此外,还提供了关于raw_input和open函数的具体用法和功能说明。 ... [详细]
  • 本文详细探讨了HTTP 500内部服务器错误的成因、解决方案及其在Web开发中的影响。通过对具体案例的分析,帮助读者理解并解决此类问题。 ... [详细]
  • 使用Vultr云服务器和Namesilo域名搭建个人网站
    本文详细介绍了如何通过Vultr云服务器和Namesilo域名搭建一个功能齐全的个人网站,包括购买、配置服务器以及绑定域名的具体步骤。文章还提供了详细的命令行操作指南,帮助读者顺利完成建站过程。 ... [详细]
  • 在现代网络环境中,两台计算机之间的文件传输需求日益增长。传统的FTP和SSH方式虽然有效,但其配置复杂、步骤繁琐,难以满足快速且安全的传输需求。本文将介绍一种基于Go语言开发的新一代文件传输工具——Croc,它不仅简化了操作流程,还提供了强大的加密和跨平台支持。 ... [详细]
  • 并发编程:深入理解设计原理与优化
    本文探讨了并发编程中的关键设计原则,特别是Java内存模型(JMM)的happens-before规则及其对多线程编程的影响。文章详细介绍了DCL双重检查锁定模式的问题及解决方案,并总结了不同处理器和内存模型之间的关系,旨在为程序员提供更深入的理解和最佳实践。 ... [详细]
author-avatar
皆靖所能
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有