Freewind @ Thoughtworks scala java javascript dart 工具 编程实践 月结 math python english [comments admin] [feed]

(2011-09-13) Netty初探

广告: 云梯:翻墙vpn (省10元) 土行孙:科研用户翻墙http proxy (有优惠)

本来打算这几天好好研究Netty的源代码的,真做起来发现还是缺少充足的动力。最开始还算认真的看了其buffer包,但是到了后来,就变成看javadoc了,知道有哪些类、类中有哪些方法就知足了。毕竟有500多个java文件,看起来真够累的。

好在基本理解了nio 之后,看netty也不是很难。Netty跟Mina结构上相当的相似,据说性能略优、在细节上更完善一些,但是我的直观感觉就是,Netty的文档和例子相当不错,让人很理解起来容易一些(以前学Mina时,费不了少工夫)。

这里简单的总结一下,技术含量不高(因为没有深入下去)。上一个日志中讲到,NIO有四大主要概念:Channel, Selector, SelectionKey, Buffer。Netty中同样也少不了这些,并且出于性能和设计上的考虑,对它们进行了扩充。比如netty的buffer包,重新定义了Buffer,提供了各种各样的实现,比jdk中自带的Buffer更加高效与好用。举例来说,jdk中的buffer在读完数据写之前,必须调用一个flip()方法,否则数据出错但不报错,这很容易引起bug。而Netty的Buffer中增加了一个write index,将读写分开,解决了这个问题。另外,jdk的buffer是固定的,而netty还提供了一个可变长的buffer,方便操作。

而Channel在Netty中也重新设计,提供了很多种Channel,照顾到不同程序的需要。而Selector和SelectionKey,还是使用jdk自己的。

重要的地方,是Netty定义了很多事件,如connected, messageReceived, messageSent等等。我们可以继承一个Handler,来实现对应的操作,它们将在对应事件发生的时候,被自动调用。这就是“事件驱动”。

为了简化操作,我们还可以使用Encoder和Decoder将传送于网络间的二进制数据与我们操作的pojo进行互转,这样在程序中无须直接操作底层数据。

Netty提供了不少协议的实现,如http等,让Netty有了初步的处理http请求的能力。其http的encoder和decoder,在底层处理http请求的交互数据,将其变为了request, cookie, response等对象。因此现在有很多web框架尝试将Netty作为自己内嵌的http服务器,以达到更佳的性能与方便的操作。不过据我观察,Netty提供的支持还比较简单(如request, response等类中,方法很少),如果真要使用,还需要对它进行扩展。

Netty使用一个Boss线程来处理新连接,而将数据读取和处理等,分给若干个Worker线程。它在内部其实还是使用了“轮询”,去调用selector.select()得到可用事件,最终转变为对Hander中相关回调方法的调用。这一点我以前在用Mina的时候不太明白,因为我一直觉得这是一件很神奇的事情,怎么会用最简单的轮询呢?原来还是自己想多了,真的是轮询,现在总算是放下心来。

这两天的收获如下:

  1. Nio没有想像中那么深奥难懂
  2. Netty使用nio,其原理与nio基本相似,并不难懂。可看见对nio的扩展与优化。
  3. Netty使用轮询来得到nio的可用事件
  4. Netty支持http,但比较简单。如果希望使用它作为http server,需要自己扩展。
comments powered by Disqus