阅读笔记:Netty在行动

想更多地了解Java网络

推荐这本书在几个地方,Netty看起来像是一个不错的Java项目,可以更多地了解Java网络。 据我了解,Netty应该类似于Apple网络层,甚至类似于iOS应用程序。 网络层基本上是一个事件驱动的应用程序,用于轮询事件并从用户代码执行注册的回调。 读完本书的目的是构建自己的HTTP / RPC服务器并在Raspberry Pis中进行部署🙂

第1章:Netty简介

本章非常基础,涵盖了Netty,非阻塞IO和事件驱动。

第2章:您的首次入网申请

本章就像一个开胃菜,用于构建netty应用程序(服务器/客户端组合)以激发您阅读整本书。

第三章:网络组件和设计

频道,事件循环和频道未来

渠道

Netty的Channel接口提供了一个API,该API降低了直接使用Java Socket类的复杂性。 Channel是具有许多预定义实现的广泛类层次结构的根源。

事件循环

EventLoop是Netty的抽象概念,用于在连接的生存期内处理事件。

  • 一个EventLoopGroup包含一个以上的EventLoops
  • EventLoop在其生命周期内绑定到单个线程。
  • 由EventLoop处理的所有IO事件均在其专用线程上处理。
  • 使用单个EventLoop可以注册一个通道,以保证其生命周期
  • 单个EventLoop可以分配给一个或多个通道。

ChannelFuture

可以使用addListener()注册ChannelFuture。 操作员完成后,将通知注册的ChannelFutureListener。

ChannelHandler

用作所有应用逻辑的容器,这些逻辑适用于处理绑定数据和出站数据。

ChannelPipeline

提供一个ChannelHandlers链的容器,并定义API和API,以传播该链上的入站和出站事件流。

您可以通过遍历整个ChannelPipeline(与Channel对话)来开始与Netty进行交互,也可以仅与管道内部的ChannelHandler对话,以便仅调用后续的ChannelHandler。

编码器和解码器

用于编码和解码网络流量。

包扎

Bootstrap类提供了用于配置应用程序网络层的容器-将进程绑定到端口或将进程连接到另一个端口。

有两种类型的引导程序。 ServerBootstrap用于绑定到端口,因为服务器必须侦听连接。 客户端应用程序使用Bootstrap连接到远程对等方。

ServerBootstrap需要两个EventLoopGroups。 它需要两组不同的通道。 第一组将包含一个ServerChannel,代表与本地端口绑定的服务器自己的侦听套接字。 第二组将包含为处理传入的客户端连接而创建的所有通道-服务器接受的每个连接中的一个。

第四章:运输

Netty提取了NIO / OIO和从一版Java网络IO切换到另一版Java网络IO包所需的最少更改。

ChannelPipeline保存所有ChannelHandler。 ChannelHandlers的典型用法:

  • 将数据从一种格式转换为另一种格式
  • 提供例外通知
  • 提供有关频道变为活动或非活动状态的通知
  • 在EventLoop中注册频道或从中注销频道时提供通知
  • 提供有关用户定义事件的通知

您可以即时修改ChannelPipeline。

包括运输

Netty捆绑了几种可供使用的传输器。 但是,并非所有协议都支持每种协议,因此您必须选择与应用程序所采用协议兼容的传输方式。

运输用例

(X表示支持)

第5章ByteBuf

ByteBuf是Netty更好的Java NIO的ByteBuffer版本。 优点

  • 可扩展到用户定义的缓冲区类型。
  • 透明的零复制是通过内置的复合缓冲区类型实现的。
  • 按需扩展容量(与JDK StringBuilder一样)
  • 在读取器和写入器模式之间切换不需要flip()方法。
  • 阅读和写作采用不同的索引。
  • 支持方法链接。
  • 支持引用计数。
  • 支持池化。

ByteBuf有两种使用模式

  • 堆缓冲区。 数据存储在JVM的堆空间中,称为后备阵列。
  • 直接缓冲区。 数据存储在堆外空间中。
  • 复合缓冲区。 多个ByteBuf的聚合视图。

字节级操作

  • 随机访问索引
  buffer.getByte(i) 
  • 顺序访问索引
  • 丢弃字节,可读字节,可写字节

ByteBuf分配

  • 按需:ByteBufAllocator

Netty使用ByteBufAllocator实现池化,以减少分配和取消分配内存的开销。 您可以通过Channel或ChannelHandlerContext获得对ByteBufAllocator的引用。

  • 未缓冲的缓冲区

如果没有对ByteBufAllocator的引用,请使用此选项。 Netty为此提供了一个名为Unpooled的实用程序类。

第6章:ChannelHandler和ChannelPipeline

ChannelHandler系列

 频道的生命周期:ChannelRegistered-> ChannelActive(频道已注册到EventLoop)-> ChannelInactive-> ChannelUnregistered 

几个普通的手

ChannelInboundHandler,ChannelOutboundHandler,

ChannelPipeline

为创建的每个频道分配一个新的ChannelPipelin。 一个Channel既不能附加另一个ChannelPipeline,也不能分离当前的ChannelPipeline。

  • ChannelPipeline包含与Channel关联的ChannelHandlers。
  • 通过根据需要添加和删除ChannelHandler,可以动态修改ChannelPipeline。
  • ChannelPipeline具有丰富的API,可用于响应入站和出站事件而调用操作。

ChannelHandlerContext表示ChannelHandler和ChannelPipeline之间的关联。 它使ChannelHandler能够与其ChannelPipeline和其他处理程序进行交互。

  • 与ChannelHandler关联的ChannelHandlerContext永远不会更改。

Channel,ChannelPipeline,ChannelHandler和ChannelHandlerContext之间的关系:

第7章:EventLoop和线程模型

线程模型

基本线程池模式可以描述为:

  • 从池的空闲列表中选择一个线程,并将其分配给运行提交的任务(可运行对象)
  • 任务完成后,线程将返回到列表,并可供重用。

事件循环

事件循环的基本思想:

EventLoop由永不改变的EXACTLY ONE Thread驱动。 请注意,由于Netty4, 所有 IO操作和事件均由已分配给EventLoop的线程处理

第8章:引导

Bootstraping类包含一个抽象父类和两个具体的Bootstrap子类-Bootstrap和ServerBoostrap。

引导类

Bootstrap类负责为客户端和利用无连接协议的应用程序创建通道。

ServerBootstrap类

第9章:单元测试(跳过)

第10章:编解码器框架

什么是编解码器?

编解码器由编码器和解码器组成,它们各自将字节流从一种格式转换为另一种格式。

解码器

Netty的解码器实现ChannelInBoundHandler,因为它负责将入站数据从一种格式转换为另一种格式。

编码器

Netty的编码器实现ChannelOutBoundHandler并将出站数据从一种格式转换为另一种格式。

第11章:提供的ChannelHandler和编解码器

  1. 使用TLS / SSL保护Netty应用程序的安全

Java通过软件包javax.net.ssl支持SSL / TLS。 Netty通过名为SslHandler的ChannelHandler实现来利用此API,该实现在内部使用SSLEngine进行实际工作。

在大多数情况下,SslHandler将成为ChannelPipeline中的第一个ChannelHandler。

2.构建Netty HTTP / HTTPS应用程序

您需要HttpRequest(Response)Decoder(Encoder)来解码HTTP消息。 Netty还提供了一个HttpObjectAggregator来将HTTP消息合并消息部分聚合为FullHttpRequest和FullHttpResponse。 您还可以通过HttpContentCompressor添加HTTP压缩,并通过SslHandler添加HTTPS支持。

3.空闲连接和超时通过IdleStateHandler(int,int,int,Unit)处理。

4.可以使用LineBasedFrameDecoder(Int)解码定界协议,而可以使用LengthFieldBasedFrameDecoder(int,int,int)解码基于长度的协议。

5.编写大数据

通过从FileInputStream创建FileRegion并将其写入Channel,可以使用零拷贝传输文件的内容。

6.序列化数据

尽可能使用JBoss封送处理,它比默认的JDK串行器快3倍。 通过ProtobufEncoder(Decoder)也支持协议缓冲区。

第十二章:WebSocket

  1. WebSocket协议是从头开始设计的,旨在为Web上的双向数据传输问题提供实用的解决方案,从而允许客户端和服务器随时传输消息,并要求它们异步处理消息接收。 Netty很好地支持WebSocket!
  2. 升级握手用于从标准HTTP / HTTPS切换到WebSocket,并且使用WebSocket的应用程序将始终以HTTP / S开头,然后执行升级。

WebSocket升级之前,您的ChannelPipeline如下所示:

升级后:

您还可以附加一个SslHandler以使其安全。

第12章:使用UDP广播事件

Netty提供了许多类来支持UDP应用程序。 主要的是在这里:

第14和15章案例研究

一些案例研究,有趣的读🙂