Netty与Java NIO APIs
本章包括
- Netty的体系结构
- 为什么我们需要非阻塞IO(NIO)
- 阻塞IO与非阻塞IO
- 基于JDK的NIO存在的问题与Netty的解决办法
本章虽然是Netty的介绍章节,但重点却是Java的NIO API,如果你是JVM网络方面的新手,本章是个不错的开始,同时对于经验丰富的Java开发人员,也是一个不错的复习机会。如果你对NIO与NIO2(AIO)比较熟悉了,在你本机运行Netty后,请自行跳过本章,从第二章开始深入到Netty的世界了。
Netty是一个NIO的CS(client-server)模式框架,使用它可以快速容易的开发网络应用,如协议服务器与客户端。Netty为你开发网络应用提供了一个新的易上手的可扩展方案。它的实现基于对复杂操作的抽象,并提供给一个对业务逻辑处理与网络处理代码的解耦的易用API。由于Netty是为NIO而设计,故其所有的API都是异步的。
通常,不管是基于Netty还是基于其他NIO API的网络应用都存在扩展性的问题。Netty的关键组成部分是它的异步性,这一章节主要讨论同步(阻塞blocking)与异步(非阻塞non-blocking)IO,以此来解释我们为何以及如何通过异步代码解决可扩展性的问题。
对于以上这些网络中新的部分,本章将给出一个关于网络应用的一般性理解以及Netty如何提升网络应用的性能的,本章将解释如何使用基本的Java networking APIs构建应用程式,以及讨论它的优缺点,另外,本章也展示了Netty是如何解决Java的这些问题(如Epoll模型的BUG或内存泄露问题)的。
在本章结尾处,你将会理解Netty是什么以及它能帮我们干什么,同时结合本书的其他章节你也将会再次对你工作中用到的Java的NIO以及异步程式获得足够深入的理解。
为何选择Netty
用David Wheeler的话来说"计算机科学中的所有问题都可以在另一个级别间接求解(all problems in computer science can be solved by anotherlevel of indirection)",作为一个NIO CS框架,Netty提供了一个类似的另一级别间接解决方案。Netty简化了TCP或UDP服务端的网络编程,但你依然可以通过较低级别的APIs访问,因为Netty提供了较高层次的抽象。
不是所有的网络框架都相似
Netty,"快且容易"并不意味着以牺牲应用的可维护性或性能为代价。来自于协议的实现经验(如FTP、SMTP、HTTP、WebSocket,SPDY以及各种二进制与基于文本的传统协议)引导了Netty的创作者们对Netty的设计非常小心,这也为Netty成功的提供了在可用性、性能、稳定性、灵活性上的兼顾。
比较著名的公司以及开源组织包括RedHat、Twitter、Infinispan、HornetQ、Vert.x、Finagle、Akka、Apache Cassandra、Elasticsearch等在使用Netty并为之做贡献。也可以公平的说Netty的一些特性正是这些项目所需的。过去的几年里,Netty变得越来越广为人之,同时它也是在一些盛行的开源非开源项目中应用最广泛的JVM网络框架之一。事实上,Netty在2011年荣获了"the Duke_s Choice Award"奖。
同样在2011年,Netty的作者Trustin Lee离开了RedHat加入了Twitter。基于这一点,Netty项目变成了一个独立的、任何公司都在努力为其做贡献的项目。RedHat与Twitter都在用Netty,所以,这两家公司理所当然的成为了Netty的最大贡献者,个人使用并贡献与Netty的数量还在增长。Netty的用户群体很活跃,Netty项目本身也是充满活力的。
Netty丰富的功能集
如果你按照本书的各章节操作练习时,你将会学到和用到很多Netty的功能。在下图的高亮部分(一些Netty支持的传输协议)给出了一个Netty架构的简要概述。
Figure 1.1 Overview of the model, transports, and protocols
除了它宽泛的传输协议,Netty也提供了在不同领域的优势(见下表1.1)
Table 1.1 Netty gives developers a full set of tools.
Development Area | Netty Features |
Design |
|
Ease of Use |
|
Performance |
|
Robustness |
|
Security |
|
|
|
Community |
|
除了上述列举出来的功能,Netty也附带解决了在Java NIO中已知的BUG或限制,因此,你无需在为此花费精力讨论。
在你对Netty的功能有了一个概览后,是时候仔细研究下异步处理的机制了,NIO与Netty都是严重依赖异步编码的,如果不了解与此相关的选择方案,就很难超越它。在下一部分,我们会研究下为何我们需要异步API。
异步的设计
所有的Netty API都是异步的,异步式处理实际并不是新的东西;虽然这个方案的提出已经有一段时间了,但是在这段时间里,IO始终都是一个瓶颈,异步式处理一天比一天变得更重要。但它是如何工作的呢,又有哪些不同的模式可用呢?
异步式处理鼓励你去更加有效的利用你的资源,首先你去开始一项任务,当任务结束的时候再去唤醒它继续执行,在这项任务的执行期间,你无须一直等待,你可以去做其他的事情。
这部分将解释在利用异步API工作的时候的两个最常用的方法,也将讨论着两种技术的不同。
回调
回调是在异步处理中常用到的一项技术。回调就是传到方法B中一个方法A,在B执行完以后,执行A方法,你可能在javascript中认出了此种模式,没错,回调函数是这门语言的核心,下面的例子向我们展示了如何利用该项技术来获取数据。
(未完)