Netty的核心组件

Netty的主要组成模块:
  • Channels
  • Callbacks
  • Futures
  • Events 和 handlers
这些模块代表了不同类型的概念:资源,逻辑和通知。你的应用将会利用这些模块来获取网络和网络上的数据。
对每个组件,我们会给出一个基本的定义,并且在合适的情况下,用一个简单的代码实例说明它的用法。
 
1. Channels 通道
一个Channel是Java NIO的一个基本抽象。它代表了:一个连接到比如硬件设备,文件,网络socket等实体的开放连接,或者是一个能够完成一种或多种譬如读或写等不同I/O操作的程序。
目前,可以把一个Channel想象成一个输入和输出数据的媒介。同样地,它可以被打开或者关闭,连接或者断开。
 
2. Callbacks 回调
一个callback就是一个方法,一个提供给另一个的方法的引用。这让另一个方法可以在适当的时候回过头来调用这个callback方法。Callbacks在很多编程情形中被广泛使用,是用于通知相关方某个操作已经完成最常用的方法之一。
Netty在处理事件时内部使用了callback;当一个callback被触发,事件可以被ChannelHandler的接口实现处理。下面的代码清单是这样一个例子:当一个新的连接建立后,ChannelHandler的callback方法channelActive()会被调用,然后打印一条消息。
代码清单 1.1 ChannelHandler被一个callback触发
 
 
 
3. Future
一个Future提供了当另一个操作完成时如何通知应用的方法。Future对象充当了一个存放异步操作结果的占位符(placeholder)角色;它会在将来某个时间完成并且提供对操作结果的访问。
JDK搭载了接口java.util.concurrent.Future, 但是提供的接口实现只允许你手动检查操作是否已经完成,或者就一直阻塞到操作完成。这非常麻烦,所以Netty提供了它自己的ChannelFuture实现,用于执行异步操作。
ChannelFuture提供了额外的方法让我们可以注册一个或者多个ChannelFutureListener实例。监听者的callback方法operationComplete()在操作完成时被调用。然后监听者可以查看这个操作是否成功完成,还是出错了。如果出错了,我们可以从future获取Throwable。简单来说,ChannelFutureListener提供的通知机制免去了手动检查操作完成情况的麻烦。
每个Netty输出的I/O操作都会返回一个ChannelFuture;就是说,没有一个操作是阻塞的。就像我们之前所说的,Netty由下至上都是异步和事件驱动的。
代码清单1.2中,一个ChannelFuture做为一个I/O操作的一部分被返回。这里,connect()会无阻塞地直接返回,调用会在后台完成。什么时候会完成取决于多个因素,但是这个担心已经从代码里被抽离(abstract away)出来了。因为这个线程没有阻塞在等待这个操作完成,它可以同时做其他事情,因此更有效率地利用资源。
代码清单1.2  异步连接
 
代码清单1.3展示了如何利用ChannelFutureListener。首先你连接到一个远端。然后用connect()返回的ChannelFuture注册一个新的ChannelFutureListener。当监听器被通知连接建立时,检查状态(1)。如果这个操作成功,你写数据到这个Channel。否则你从ChannelFuture中读取Throwable。
代码清单1.3 运作中的Callback
 
注意错误处理完全取决于你,取决于某个具体错误施加的限制。比如说,连接错误发生时,你可以试着重连或者和另一个远端建立连接。
如果你认为一个ChannelFutureListener是一个callback的复杂版本,那你想对了。事实上,callbacks和Futures是互补的机制;两者结合起来构成了Netty的关键模块之一。
 
4. Events 和 handlers
Netty用细分的events来通知我们状态的变化或者操作的状况。这让我们可以基于发生的events来触发适当的行为。这类行为可能包括
  • 日志记录
  • 数据传送
  • 流控制
  • 应用逻辑
Netty是一个网络编程框架,所以events按它们和输入或者输出数据流的关系来分类。
可能被输入数据或者相关状态改变触发的events包括:
  • 活跃或者停用的连接
  • 读数据
  • 用户events
  • 错误events
而输出event则是会触发将来行为的操作的结果,可能会是:
  • 打开或者关闭到远端的连接
  • 写或者刷数据到一个socket
每一个event都可以被分派到一个用户实现的handler对象的方法。这是一个事件驱动的模型如何直接转变为应用模块的好例子。图1.3展示了一个event如何被一串这样的event handler处理。
图1-3 经过一串ChannelHandler的输入输出事件
 
Netty的ChannelHandler提供了如图1.3中展示的handler的基本抽象。我们在适当的时候会更多地谈论到ChannelHandler,但是现在你可以认为每个handler实例就是一种响应某个具体event的callback。
Netty提供了大量你可以马上拿来用的预定义handler,包括HTTP和SSL/TLS等协议的handler。在内部,ChannelHandler自己也用events和futures,和你的应用是同样抽象的消费者。
 
5. 汇总
在这一章,初次接触了Netty针对高性能网络编程的方案,以及Netty实现的一些主要模块。让我们把讨论过的东西总结下。
FUTURES,CALLBACKS和HANDLERS
Netty的异步编程模型是建立在Futures和callbacks概念之上的,在更深一层分派事件到handler方法。这些元素结合起来提供了一个处理环境,让你的应用逻辑可以逐步发展而不用关心网络操作。这一个Netty设计方案的一个关键目标。
快速地拦截操作和传送输入输出数据只要求你提供callbacks或者用操作返回的Futures。这让链式操作变得容易和有效,同时促进了可重用和通用代码的编写。
SELECTORS, EVENTS, AND EVENT LOOPS
Netty通过引发事件把Selector从应用中抽象出来,省掉了所有原本需要手写得调度代码。在内部,一个EventLoop被分配到每个Channel来处理所有的events,包括
  • 注册感兴趣的events
  • 分派events到ChannelHandlers
  • 安排将来的行为
EventLoop自己仅由一个线程驱动,这个线程处理一个Channel所有的I/O事件,这个关系在Eventloop的生命周期内不会改变。这个简单强大的设计消除了任何你可能对ChannelHandler同步的顾虑,因此你能够专注于在数据被处理时,提供正确的执行逻辑。在我们详细探讨Netty的线程模型时将会看到的,这个API简洁并且紧凑。
原文地址:https://www.cnblogs.com/barrywxx/p/8515217.html