Netty源码分析之服务端启动

博文小编

2023-01-18

Netty在服务端启动过程中是如何绑定端口、启动服务的呢?

在启动服务的过程中,我们可以顺势了解到Netty各大核心组件。

本文暂时不会详细描述这些组件,先简单介绍一下各大组件是如何协同工作、一起构建Netty核心的。

01 服务端启动示例

我们写了一个比较完整的服务端启动例子,绑定在8888端口,使用NIO模式。


下面来回顾一下每个方法的作用。

1.EventLoopGroup:服务端的线程模型外观类。从字面意思可以了解到,Netty的线程模型是事件驱动型的,也就是说,这个线程要做的事情就是不停地检测IO事件、处理IO事件、执行任务,不断重复这三个步骤。

2.ServerBootstrap:服务端的一个启动辅助类。通过给它设置一系列参数来绑定端口启动服务。

3..group(bossGroup, workerGroup):设置服务端的线程模型。读者可以先想象一下:在一个工厂里,我们需要两种类型的人干活,一种是老板,一种是工人。老板负责从外面接活,把接到的活分配给工人。放到这里,bossGroup的作用就是不断地接收新的连接,将新连接交给workerGroup来处理。

4..channel(NioServerSocketChannel.class):设置服务员的IO类型为NIO。Netty通过指定Channel的类型来指定IO类型。Channel在Netty里是一大核心概念,可以理解为,一个Channel就是一个连接或者一个服务端bind动作,后面会细讲。

5..handler(new SimpleServerHandler():表示在服务端启动过程中,需要经过哪些流程。这里SimpleServerHandler最终的顶层接口为ChannelHandler,是Netty的一大核心概念,表示数据流经过的处理器,可以理解为流水线上的每一道关卡。

6..childHandler(new ChannelInitializer)…:使用过Netty的读者应该知道,这里的方法体主要用于设置一系列Handler来处理每个连接的数据,也就是上面所说的,老板接到一个活之后,告诉每个工人这个活的固定步骤。

7.ChannelFuture f = b.bind(8888).sync():绑定端口同步等待。这里就是真正的启动过程了,绑定端口8888,等服务端启动完毕,才会进入下一行代码。

8.f.channel().closeFuture().sync():等待服务端关闭端口绑定,这里的作用其实是让程序不会退出。

9.bossGroup.shutdownGracefully()和workerGroup.shutdownGracefully():关闭两组事件循环,关闭之后,main方法就结束了。

上述代码可以很轻松地在本地运行,最终控制台的输出如下。

为什么控制台会按顺序输出这些字符,接下来我们就深入细节一探究竟。

02 服务端启动的核心步骤

我们通过以上示例代码来理一理服务端启动的基本流程。

在上面的示例代码中,我们是通过ServerBootstrap这个辅助类来实现服务端启动的,给这个启动类设置一些参数,然后通过它的外观接口来实现启动。重点落在下面这行代码上。

我们跟进到bind()方法。

通过端口号创建一个InetSocketAddress对象,然后继续调用重载方法bind()。

validate()验证服务启动需要的必要参数,然后调用doBind()。

在这里,笔者减掉了细枝末节,专注于核心方法,分别为initAndRegister()和doBind0()。

从方法名我们已经可以略窥一二,init代表初始化,register代表注册,bind代表绑定端口。联系NIO开发的基本流程,可能是把某个东西初始化之后注册到Selector上,最后bind像是在本地绑定端口号。

带着这些猜测,我们深入分析下去。

我们先来看一下initAndRegister()方法。

同样地,笔者略去了其他细节,专注于骨干代码。initAndRegister()中的3个主要方法与doBind0()方法一起组合成了服务端启动的4个过程。

这4个过程的详细分析写在《跟闪电侠学 Netty:Netty 即时聊天实战与底层原理》一书中,大家可以阅读这本书继续学习哦~~

本书上篇通过一个即时聊天的例子,让读者能够系统地使用一遍Netty,全面掌握Netty的知识点;下篇通过对源码的层层剖析,让读者能够掌握Netty底层原理,知其然并知其所以然,从而编写出高性能网络应用程序。

上篇 入门实战

在入门实战篇中,读者跟随笔者实践完这个即时聊天系统后,能够学会如何使用Netty完成最基本的网络通信程序,可以掌握以下知识点:

  1. 如何启动服务端?

  2. 如何启动客户端?

  3. 如何设计长连自定义协议?

  4. 拆包/粘包原理与实践。

  5. 如何实现自定义编解码。

  6. 如何使用Pipeline与ChannelHandler?

  7. 心跳与空闲检测的方法。

  8. 如何性能调优?

本篇通俗易懂,可一口气读完,让你一周内进入实战!

下篇 源码分析

在源码分析篇中,笔者从用户视角出发,环环相扣,带领读者逐个攻破Netty底层原理,掌握以下知识点:

1. 服务端启动流程:ServerBootstrap外观,创建NioServerSocketChannel,初始化,注册Selector,绑定端口,接收新连接。

2. 高并发线程模型:Netty无锁化串行设计,精心设计的Reactor线程模型榨干CPU、打满网卡、让应用程序性能爆表的底层原理。

3. 新连接接入流程:Boss Reactor线程,监测新连接,创建NioSocketChannel,IO线程分配,Selector注册事件。

4. 解码原理:解码顶层抽象,定长解码器,行解码器,分隔符解码器,基于长度域解码器全面分析。

5. 事件传播机制脉络:大动脉Pipeline,处理器ChannelHandler,Inbound和Outbound事件传播与异常传播的原理,编码原理。

6. writeAndFlush流程:深入了解使用最频繁的writeAndFlush的底层原理,避免踩坑。

适读人群

本书适合以下三类人群:

1. 如果你听说过或简单使用过Netty,想全面系统地学习Netty,并掌握一些性能调优方法,本书的入门实战篇可以帮助你达成这个目标。

2. 如果你深度使用过Netty,想深入了解Netty的底层设计,编写出更灵活高效的网络通信程序,本书的源码分析篇可以帮助你达成这个目标。

3. 如果你从未读过开源框架源码,本书将是你的第一本源码指导书,阅读优秀的开源软件源码可以助你写出更优美的程序。读源码并不难,难的是迈出这一小步,之后就能通往更广阔的空间。

本书推荐使用方式

01. 按章节顺序把入门实战篇的代码一章章敲出来,在没有掌握前一章节的知识点之前,建议不要跳跃学习。

02. 入门实战篇学完之后,合上书本,把本书即时聊天系统的代码再整体敲若干遍,敲的过程中可能会发现自己有遗忘知识点,这个时候可能需要不断翻阅书本,没有关系,翻阅就好了。

03. 确保最后一次实现本书的即时聊天系统的例子是没有翻阅书本的,是完全自行实现的,之后进入源码分析篇的学习。

04. 针对源码分析篇,建议读者按章节顺序来学习,不要跳跃,不要图快,每一步都要扎实。

05. 在源码学习的过程中,先跟随书本,对照源码,把对应章节的流程过一遍,每个章节学完之后,建议花较多的时间进行调试和阅读,确保掌握了前一章节的内容之后再进行下一章的学习。

京东限时立减50,快快扫码抢购吧!

读者评论

相关博文

  • 社区使用反馈专区

    陈晓猛 2016-10-04

    尊敬的博文视点用户您好: 欢迎您访问本站,您在本站点访问过程中遇到任何问题,均可以在本页留言,我们会根据您的意见和建议,对网站进行不断的优化和改进,给您带来更好的访问体验! 同时,您被采纳的意见和建议,管理员也会赠送您相应的积分...

    陈晓猛 2016-10-04
    5700 747 3 7
  • 迎战“双12”!《Unity3D实战核心技术详解》独家预售开启!

    陈晓猛 2016-12-05

    时隔一周,让大家时刻挂念的《Unity3D实战核心技术详解》终于开放预售啦! 这本书不仅满足了很多年轻人的学习欲望,并且与实际开发相结合,能够解决工作中真实遇到的问题。预售期间优惠多多,实在不容错过! Unity 3D实战核心技术详解 ...

    陈晓猛 2016-12-05
    3427 36 0 1
  • czk 2017-07-29
    6277 28 0 1