在上一篇博客中,我们给出了java高性能网络编程的技术基础,也简单的介绍了netty的核心构件,在这一篇博客中,我们将更加详细的研究netty的各个组件,并且密切关注它们是如何通过协作来支撑这些体系结构上的最佳实践的。

首先,我们会对Channel,EventLoop和ChannelFuture类进行讨论,这些类结合在一起,可以被认为是netty网络抽象的代表:

(1)Channel - Socket

表示基本的I/O操作,在基于java的网络编程中,基本构造是class socket。netty的channel接口提供的api,大大降低了直接使用socket类的复杂性,此外,channel也是拥有许多预定义的专门化实现的广泛类层次的根如:LocalServerChannel,NioDatagramChannel,NioSocketChannel,NioSctpChannel。

(2)EventLoop-控制流,多线程处理,并发

EventLoop定义了netty的核心抽象,用于处理的连接的生命周期中所发生的事件。下图展示了几个重要的实体之间的关系:

注:一个eventLoop在在它的生命周期只与一个thread绑定;

所有由eventLoop处理的I/O事件都将在它专有的thread上被处理;

一个channel在它的生命周期内只注册于一个eventLoop;

一个eventLoop可能会被分配给一个或者多个channel;

在此基础上,一个channel的所有的I/O操作都是由同一个线程(同一个eventLoop)去处理的,消除了对于同步的需要。

(3)ChannelFuture - 异步通知

正如我们之前所说的,netty的所有的I/O操作都是异步的,所以我们需要提供一种用于在之后的某个时间点确定其结果的方法;因此,netty提供了ChannelFuture接口,其addListener()方法注册了一个ChannelFutureListener,以便在某个操作完成时得到通知。(其实可以将其看成是将来要执行的操作的结果的占位符,它究竟在什么时候执行可能取决于若干因素,但是它肯定会被执行。)

(4)ChannelHandler和ChannelPipeline

从开发人员的角度来看,netty的主要组件是channelHandler  ,因为其方法是由网络事件触发的,channelHandler几乎可以处理任何类型的动作,甚至包括异常。例如,channelInboundHandler是我们经常需要实现的子接口,其用来接收入站事件和数据,当要给连接的客户端发送响应时,也可以通过channelInboundHandler冲刷数据。

channelPipeline提供了channelHandler 链的容器,使得事件流经channelPipeline是channelHandler的工作,他们是在应用程序的初始化或者引导阶段被安装的,这些对象接收事件,执行他们所实现的处理逻辑,并将数据传递给链中的下一个channelHandler,他们的执行顺序是他们被添加的顺序决定的。当然入站和出站的channelHandler可以被安装到同一个channelPipeline中。

这里多说一句,实际上当channelHandler被注册到channelPipeline时,它将会被分配一个channelHandlerContext,其代表了channelHandler和channelPipeline之间的绑定,这个对象主要被用来写出站数据,其上的每一个方法,都提供了简单的将事件传递给下一个channelHandler方法的实现。在netty中,有两种发消息的方式,直接写到channel中或者写到和channelHandler相关联的channelHandlerContext对象中,前一种方式导致消息从channelPipeline的尾端开始流动,后一种方式导致消息从channelPipeline的下一个channelHandler开始流动。

netty以适配器的形式提供了大量的默认的channelHandler的实现,这些是适配器的子类将自动的把事件转发到链中的下一个channelHandler,因此我们只需要重写我们需要处理的方法和事件。

(5)编码器和解码器

当netty接收或者发送一个消息时,就会发生一次数据转换,入站消息被解码,出站消息将会被编码,netty也为编码器和解码器提供了不同类型的抽象类,并且所有的编码器和解码器都实现了channelOutboundHandler或channelInboundHandler接口。

(6)引导

netty的引导类,为应用程序的网络层配置提供了容器,这涉及将一个进程绑定到某个指定的端口,或将一个进程连接到另一个运行在某个指定主机的指定端口上的进程。

有两种类型的引导:一种用于客户端(Bootstrap)用于连接到远程主机和端口,一种用于服务端(ServerBootstrap)绑定到本地的端口。ServerBootstrap需要两个EventLoopGroup而Bootstrap只需要一个,我们来看一下为什么:

因为服务器需要两组不同的channel,第一组将只包含一个ServerChannel代表绑定到服务器自身本地端口正在监听的套接字,而第二组将包含创建的用来处理传入客户端连接的channel。与serverChannel 相关联的EventLoopGroup将分配一个负责为传入连接请求创建channel的EventLoop,一旦连接被接受,第二个EventLoopGroup就会给他的channel分配一个EventLoop。如下图所示:

(7)总结

这一章我们从技术和体系结构两个角度分析讨论了netty的组件,下面我们将深入研究这些组件。

一起来读Netty In Action之netty的组件和设计(二)的更多相关文章

  1. Essential Netty in Action 《Netty 实战(精髓)》读书笔记一

    NIO 最初是为 New Input/Output 的缩写.然而,Java 的 API 已经存在足够长的时间,它不再是新的.现在普遍使用的缩写来表示Nonblocking I/O (非阻塞 I/O). ...

  2. 【推荐】《Netty in action》书籍

    最近准备开始阅读一下<Netty in action>并且准备构架设计一个分布式系统.用于新项目. 貌似压力很大啊.压力就是东西.希望自己能够调节好. Netty in action是Ne ...

  3. Netty In Action中文版 - 第五章:Buffers(缓冲)

    本章介绍 ByteBuf ByteBufHolder ByteBufAllocator 使用这些接口分配缓冲和运行操作 每当你须要数据传输时,它必须包括一个缓冲区.Java NIO API自带的缓冲区 ...

  4. 《Netty in action》 读书笔记

    声明:这篇文章是记录读书过程中的知识点,并加以归纳总结,成文.文中图片.代码出自<Netty in action>. 1. 为什么用Netty? 每个框架的流行,都一定有它出众的地方.Ne ...

  5. Netty In Action中文版 - 第七章:编解码器Codec

    http://blog.csdn.net/abc_key/article/details/38041143 本章介绍 Codec,编解码器 Decoder,解码器 Encoder,编码器 Netty提 ...

  6. Netty | 第1章 Java NIO 网络编程《Netty In Action》

    目录 前言 1. Java 网络编程 1.1 Javs NIO 基本介绍 1.2 缓冲区 Buffer 1.2 通道 Channel 1.3 选择器 Selector 1.4 NIO 非阻塞网络编程原 ...

  7. Netty In Action中国版 - 第二章:第一Netty程序

    本章介绍 获得Netty4最新的版本号 设置执行环境,以构建和执行netty程序 创建一个基于Netty的server和client 拦截和处理异常 编制和执行Nettyserver和client 本 ...

  8. Netty In Action中文版 - 第一章:Netty介绍

    本章介绍 Netty介绍 为什么要使用non-blocking IO(NIO) 堵塞IO(blocking IO)和非堵塞IO(non-blocking IO)对照 Java NIO的问题和在Nett ...

  9. [Netty] - Netty IN ACTION(导言)

    最近没什么事儿做,刚好看到有需要网络编程的知识,java中有NIO和IO两种不同的方式,但是NIO的编写比较麻烦,刚好找到一个成熟的网络框架Netty.接下来的一个月就准备将Netty IN ACTI ...

随机推荐

  1. thinkphp3.2集成极光推送

    项目中用到了给客户端的推送功能,选用了极光推送,下面演示一下在thinkphp中集成极光推送 1.下载极光推送的php类,可以从笔者的git下载 地址:https://git.oschina.net/ ...

  2. 【Java例题】2.8 解一元二次方程

    8.解一元二次方程. 输入一元二次方程的a,b,c三个系数,解一元二次方程 ax^2+bx+c=0,输出两个根 package study; import java.util.Scanner; pub ...

  3. http客户端-性能比较系列-第一篇-单线程

    系列文章: 单线程性能测试:https://www.cnblogs.com/victor2302/p/11077208.html 多线程性能测试:https://www.cnblogs.com/vic ...

  4. U盘重装MacOS-Sierra系统

    Mac系统重新安装两种方法: 1.在线远程重装. 2.制作启动U盘进行重装. 理论上第一种比较简单,但是会比较耗时,实际操作中,由于网上下载的系统版本低于我现在MacOS的版本,导致无法安装,因此只能 ...

  5. 算法与数据结构基础 - 滑动窗口(Sliding Window)

    滑动窗口基础 滑动窗口常用来解决求字符串子串问题,借助map和计数器,其能在O(n)时间复杂度求子串问题.滑动窗口和双指针(Two pointers)有些类似,可以理解为往同一个方向走的双指针.常用滑 ...

  6. 章节十五、8-配置文件File Logging

    一.如何将log输出到文件中? 1.配置xml文件 <?xml version="1.0" encoding="UTF-8"?> <Confi ...

  7. JS鼠标吸粉特效

    HTML <canvas id=canvas></canvas> CSS * { margin: 0; padding: 0; } html { overflow: hidde ...

  8. Bootstrap笔记--快速入门

    首先是Bootstrap的简介: 业余了解:下面这个网址可以查询IP地址的地理位置 下面学习:(具体可以参考Bootstrap中文网) 栅格系统 Bootstrap 提供了一套响应式.移动设备优先的流 ...

  9. 洛谷 P1196 [NOI2002]银河英雄传说

    题意简述 有30000列,每列都有一艘战舰,编号1~30000 有2种操作: 1.将一列的战舰运到另一列 2.询问两个战舰是否在同一列,如果是,求出它们之间的距离 题解思路 并查集, 维护每个点x离自 ...

  10. Mac 安装 homebrew 流程 以及 停在 Updating Homebrew等 常见错误解决方法

    懒人操作顺序:S_01>>>S_02>>>S_03 首先这是homebrew的官网 https://brew.sh/index_zh-cn 安装方法是在终端中输入 ...