为什么要用Netty:JAVA NIO的缺陷

JAVA NIO相对于Old IO APIs 有非常大的改进,但是使用NIO是受限制的。有些是设计问题,有些是缺陷导致,而netty已经解决了这些问题。

①跨平台与兼容性

NIO算是底层的APIs需依赖奥佐系统的IO APIs。但Jvava NIO发现在不同系统平台会出现问题。大量测试也耗不少时间;NIO2只支持JDK1.7+,而且没提供DatagramSocket,故NIO2不支持UDP协议。

而Netty提供统一接口,同一语句无论在JDK6.X 还是JDK7.X 都可运行,无需关心底层架构功能!

②JAVA NIO的ByteBuffer构造函数私有,无法扩展。Netty提供了自己的ByteBuffer实现,通过简单APIs对其进行构造、使用和操作,一此解决NIO的一些限制。

③NIO对缓冲区的聚合与分散操作可能会导致内存泄漏。

直到JDK1.7才解决此问题。

④压碎著名的Epoll缺陷。

On Linux-like OSs the selector makes use of the epoll- IO event notification facility. This is a high-performance technique in which the OS works asynchronously with the networking stack.Unfortunately,  even  today  the “famous” epoll- bug  can  lead  to  an “invalid” state  in  the selector, resulting in 100% CPU-usage and spinning. The only way to recover is to recycle the old  selector  and  transfer  the  previously  registered  Channel  instances  to  the  newly  created Selector.

Linux-like OSs的选择器使用的是epoll-IO事件通知工具。这是一个在操作系统以异步方式工作的网络stack.Unfortunately,即使是现在,著名的epoll-bug也可能会导致无效的状态的选择和100%的CPU利用率。要解决epoll-bug的唯一方法是回收旧的选择器,将先前注册的通道实例转移到新创建的选择器上。

What  happens  here  is  that  the Selector.select() method  stops  to  block  and  returns immediately-even  if  there  are  no  selected  SelectionKeys  present.  This  is  against  the contract,  which  is  in  the  Javadocs  of  the  Selector.select()  method:Selector.select() must not unblock if nothing is selected.

这里发生的是,不管有没有已选择的SelectionKey,Selector.select()方法总是不会阻塞并且会立刻返回。这违反了Javadoc中对Selector.select()方法的描述,Javadoc中的描述:Selector.select() must not unblock if nothing is selected. (Selector.select()方法若未选中任何事件将会阻塞。)

The range of solutions to this epoll- problem is limited, but Netty attempts to automatically detect and prevent it. The following listing is an example of the epoll- bug.

NIO中对epoll问题的解决方案是有限制的,Netty提供了更好的解决方案。

下面是epoll-bug的一个例子:

while (true) {

int selected = selector.select();

Set<SelectedKeys> readyKeys = selector.selectedKeys();

Iterator iterator = readyKeys.iterator();

while (iterator.hasNext()) {

}

}

The effect of this code is that the while loop eats CPU:

这段代码的作用是while循环消耗CPU:

while (true) {

}

The value will never be false, and the code keeps your CPU spinning and eats resources. This can have some undesirable side effects as it can consume all of your CPU, preventing any other CPU-bound work.

该值将永远是假的,代码将持续消耗你的CPU资源。这会有一些副作用,因为CPU消耗完了就无法再去做其他任何的工作。

These are only a few of the possible problems you may see while using non-blocking IO. Unfortunately, even after years of development in this area, issues still need to be resolved; thankfully, Netty addresses them for you.

这些仅仅是在使用NIO时可能会出现的一些问题。不幸的是,虽然在这个领域发展了多年,问题依然存在;幸运的是,Netty给了你解决方案。

⑤ Summary

This chapter provided an overview of Netty’s features, design and benefits. I discussed the difference between blocking and non-blocking processing to give you a fundamental understanding of the reasons to use a non-blocking framework. You learned how to use the JDK API to write network code in both blocking and non-blocking modes. This included the new non-blocking API, which comes with JDK 7. After seeing the NIO APIs in action, it was also important to understand some of the known issues that you may run into. In fact, this is why so many people use Netty: to take care of workarounds and other JVM quirks. In the next chapter, you’ll learn the basics of the Netty API and programming model, and, finally, use Netty to write some useful code.

我来评几句
登录后评论

已发表评论数()

相关站点

+订阅
热门文章