Netty In Action 读书笔记 - 第三章 分解Netty

Netty中重要的组件:
-Bootstrap或ServerBootstrap
-EventLoop
-EventLoopGroup
-ChannelPipeline
-Channel
-Future或ChannelFuture
-ChannelInitializer
-ChannelHandler

Netty速成
Netty应用开始于一个Bootstrap类,Bootstrap类是Netty提供的构造器,用来配置Netty应用,或引导启动Netty应用程序。

为了兼容不同的传输协议,以及处理数据的不同方式,Netty引入了Handler,正如其名所示,它们被设计用来处理Netty中一个,或一组具体的“事件”,如处理字节到对象的转换、或在异常发生时被通知。
我们以后经常需要用到的是接口 ChannelInboundHandler的实现, ChannelInboundHandler接受数据,由我们获取并决定如何对数据进行处理。在应用程序需要提供响应时,我们也可以在 ChannelInboundHandler内部写数据,并将数据flush到远端。换句话说,应用程序的业务逻辑通常是存在于 ChannelInboundHandler中的。

当Netty连接客户端或绑定服务器时,它需要知道如何处理发送或接收到的消息。这也是通过不同的Handler来完成的。
为了配置这些Handler,Netty提供了ChannelInitializer类,它的作用是将ChannelHandler实现添加到ChannelPipeline中。
ChannelInitializer本身也是一个ChannelHandler,在它添加完其它handlers之后,会自动将自己从ChannelPipeline中移除。

所有Netty应用都以ChannelPipeline为基础,ChannelPipeline与EventLoop、EventLoopGroup关系密切,它们都与事件或事件处理相关。
应用中EventLoop的目的是为Channel处理IO操作。一个单独的EventLoop通常会为多个Channel处理事件,而EventLoopGroup可能包含一个或多个EventLoop,并可以用来获取EventLoop。

Channel是套接字连接或其它可以执行IO操作的组件的抽象,这就是为什么它被EventLoop所管理,后者的任务正是IO处理。

Netty中所有的IO操作都是异步的。假设我们连接到服务器,这个操作默认是异步完成的。当我们读/写数据时也是一样。这表示操作可能不会直接被执行,而是在之后的某个时刻执行。因此在操作执行返回后,我们无法知道这个操作是成功还是失败,但我们需要有能力在之后校验操作是否成功,或通过某种方式注册监听器。Netty使用Future和ChannelFuture,Future可以用来注册监听器,在操作执行成功或失败时都会被通知。
*ChannelFuture基本上是一个容器,用来存放一个在未来某个时刻被执行的操作的结果。

Channels,Events and Input/Output(IO)
Netty是非阻塞、事件驱动、网络框架。这意味着Netty使用线程来处理IO。了解多线程编程的童鞋可能会想到要对代码进行同步处理。但Netty使用了如下设计来保证处理Netty事件是,我们的代码不需要进行同步处理:


可以把EventLoop看作是为一个Channel处理实际IO事件的线程。
*EventLoop总是绑定到一个单独的线程,并且在它的生命周期中都不会改变。

当一个Channel被注册时,在其整个生命周期中,Netty都将其绑定到一个单独的EventLoop(也即是一个单独的线程)。这就是为什么应用程序不需要对Netty的IO操作做同步处理,因为对于给定的channel,所有的IO操作都是在相同的线程内被执行。



Bootstrapping:What and Why
Bootstrap和ServerBootstrap的主要区别:
客户端应用程序使用单独的EventLoopGroup,而ServerBootstrap使用两个EventLoopGroup(实际上可以是同一个实例)。
ServerBootstrap可以被认为有两个Channel集合,第一个集合包含单独的ServerChannel,代表着已经被绑定到本地端口的服务器自身的socket。而第二个集合包含所有的Channel,代表着服务器接收的所有连接。


如图所示,EventLoopGroup A的唯一职责就是接收连接请求,并将其传递给EventLoopGroup B。Netty之所以这样设计的原因是,在发生请求高峰时,单一的EventLoopGroup很快会成为瓶颈,因为它正忙于处理已经接收到的连接,而无法在合理的时间内处理新的连接请求,最终导致部分连接超时。

*EventLoopGroup可能包含多个EventLoop,这取决于配置。每个Channel在创建时,都有一个EventLoop与之绑定并且不再改变。一般情况下EventLoopGroup包含的EventLoop都比Channels的数量少,许多Channels都将共享相同的EventLoop,这意味着让EventLoop忙于处理某个Channel,将导致绑定到该EventLoop的其他Channels无法被处理,因此在任何情况下都不能阻塞EventLoop。


Channel Handlers and Data Flow
ChannelHandlers需要依赖ChannelPipeline来描述它们执行的顺序,它们互相依赖,缺一不可。
ChannelHandler很重要,它们很抽象,但可以看作是处理ChannelPipeline上来来往往的数据的任何代码片段。


ChannelPipeline可以看作是对一系列ChannelHandler的布置。每个ChannelHandler对它能够处理的数据执行操作,然后将转换后的数据传递给ChannelPipeline中的下一个ChannelHandler,直到不再有ChannelHandler为止。
*类似Servlet。


在这个ChannelPipeline中,如果读取到信息或任何其它到达事件发生时,它将会从ChannelPipeline的头部开始,被传递给第一个ChannelInboundHandler。ChannelHandler处理或传递数据给下一个ChannelHandler,直到没有更多的 ChannelInboundHandler,此时它将到达ChannelPipeline的尾部。反过来也是一样,任何出站事件将开始于ChannelPipeline的尾部,并被传递给其中最后一个ChannelOutboundHandler。区别在于,下一个  ChannelOutboundHandler事实上是“前一个”,因为出站事件是从ChannelPipeline的尾部流向头部的。

Encoders,Decoders and Domain Logic:A Closer Look at Handlers
Netty提供了很多“Adapter”类,帮助我们更加方便的实现功能:
-ChannelHandlerAdapter
-ChannelInboundHandlerAdapter
-ChannelOutboundHandlerAdapter
-ChannelDuplexHandlerAdapter


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值