Netty学习(一)——Netty简介与模块
一、Netty简介
1.1 简介
Netty是一款异步的、事件驱动的网络应用程序框架,支持快速的开发可维护的高性能的面向协议的服务器和客户端。它是异步又是事件驱动的——它可以以任意顺序响应在任意的时间点产生的事件。
在网络编号领域,Netty是Java的卓越框架,它驾驭了Java高级API的能力,并将其隐藏在一个易于使用的API之后。
1.2 Netty特性
Netty的特性总结,如下表格。
分 类 | Netty的特性 |
---|---|
设计 | 统一的API,支持多种传输类型,阻塞的和非阻塞的简单而强大的线程模型真正的无连接数据报套接字支持链接逻辑组件以支持复用 |
易于使用 | 详实的Javadoc和大量的示例集不需要超过JDK 1.6+[7]的依赖。(一些可选的特性可能需要Java 1.7+和/或额外的依赖) |
性能 | 拥有比Java的核心API更高的吞吐量以及更低的延迟得益于池化和复用,拥有更低的资源消耗最少的内存复制 |
健壮性 | 不会因为慢速、快速或者超载的连接而导致OutOfMemoryError消除在高速网络中NIO应用程序常见的不公平读/写比率 |
安全性 | 完整的SSL/TLS以及StartTLS支持可用于受限环境下,如Applet和OSGI |
社区驱动 | 发布快速而且频繁 |
Netty的用户社区非常活跃,且在不断壮大中。也有不少大公司如Apple、Twitter、Facebook、Google等在使用Netty,还有一些流行的开源项目如Apache Cassandra、Elasticsearch等也使用了Netty。它们所有的核心代码都利用了Netty强大的网络抽象。
基于Netty异步、事件驱动的特性,与使用阻塞I/O来处理大量事件相比,使用非阻塞I/O来处理更快速、更经济。选择器的使用能够通过较少的线程便可监视许多连接上的事件。
1.3 Netty结构图
Netty结构如下图:
二、主要模块
2.1 Channel
Channel是Java NIO的一个基本构造。它代表一个到实体(如一台硬件设备)的开放连接,如读操作和写操作。可以把它看作是传入或传出数据的一个载体。可以被打开或被关闭,连接或断开连接。
2.2 回调
一个回调其实就是一个方法,一个指向已经被提供给另一个方法的方法的引用。这使得后者可以在适当的时候调用前者。
Netty内部使用了回调来处理事件,当一个回调被触发时,相关的事件可以被一个interface-ChannelHandler的实现处理。
2.3 Future
Future提供了另一种在操作完成后通知应用程序的方式。这个对象可以看作是一个异步操作的结果的点位符;它将在未来的某个时刻完成,并提供对其结果的访问。
Java预置了interface java.util.concurrent.Future,但其所提供的实现,只允许手动检查对应的操作是否已经完成,或一直阻塞直到完成。这是非常繁琐的,所以Netty提供了自己的实现——ChannelFuture,用于在执行异步操作的时候使用。
ChannelFuture提供了几种额外方法,这些方法使得能在注册一个或多个ChannelFutureListener实例。监听器的回调方法operationComplete(),将会在对应操作完成时被调用。然后监听器可以判断操作是成功还是出错了。如果出错了,可以检索产生Throwable。简而言之,由ChannelFutureListener提供的通知机制消除了手动检查对应的操作是否完成的必要。
每个Netty的出站I/O操作都将返回一个ChannelFuture,也就是说,它们都不会阻塞。正如前面说的,Netty完全是异步和事件驱动的。
2.4 事件和ChannelHandler
Netty使用不同的事件来通知我们状态的改变或是操作的状态。所以能够基于已经发生的事件来触发适当的动作,这些动作可以是:
- 记录日志;
- 数据转换:
- 流控制;
应用程序逻辑。
Netty中的事件是按照它们与入站或出站数据流的相关性进行分类的。可能由入站数据或相关的状态更改而触发的事件包括:
连接已被激活或连接失活;
- 数据读取;
- 用户事件;
错误事件。
出站事件是未来将会触发的某个动作的操作结果,这些动作包括:
打开或关闭到远程节点的连接;
将数据写到或冲刷到套接字。
每个事件都可被分发给ChannelHandler类中的某个用户实现的方法。这一个很好的将事件驱动范式直接转换为应用程序构件块的例子。
Netty的ChannelHandler为处理器提供了基本的抽象,可以认为每个ChannelHandler的实例都类似于一种为了响应特定事件而被执行的回调。Netty提供了大量预定义的可以开箱即用的ChannelHandler实现,包括用于各种协议(如HTTP和SSL/TLS)的ChannelHandler。在内部,ChannelHandler自己也使用了事件和Future,使得它们也成为了你的应用程序将使用的相同抽象的消费者。
Netty通过触发事件将Selector从应用程序中抽象出来,消除了所有本来将需要手动编写的派发代码。在内部,将会为每个Channel分配一个EventLoop,用以处理所有事件,包括:
- 注册感兴趣的事件;
- 将事件派发给ChannelHandler;
安排进一步的动作。
EventLoop本身只由一个线程驱动,其处理了一个Channel的所有I/O事件,并在该EventLoop的整个生命周期都不会改变。这个简单而强大的设计消除了可能的的在ChannelHandler实现中需要进行同步的任何顾虑。
注:本篇参考《Netty实战》。
还没有评论,来说两句吧...