Netty和IO
Netty项目致力于提供一个异步事件驱动的网络应用程序框架和工具,以快速开发可维护的高性能和高可扩展性协议服务器和客户端。
最早的网络编程开发人员是通过复杂的C语言套接字库来进行网络编程通信,例如使用Java的ServerSocket,JDK1.0时期的产物。这种解决方式最大的问题来源是高并发情况下线程的休眠浪费,内存浪费和上下文切换带来的性能瓶颈。
在JDK1.4之后引入了NIO的概念,使用操作系统的事件通知API注册一组非阻塞套接字,以确定他们中是否有任何的套接字可以提供数据的读写。IO则相当于一个socket对应了一个线程,NIO则相当于是有一个选择器来处理多个Socket。
NIO的困难在于Java的提供的JDK过于详细,封装的层度不及到初学者可以简单实用。后面就有了高级封装出的Netty。
Netty在性能上使用了一点的池化和复用策略和更少的内存复制。在使用上更加的贴近业务逻辑开发人员的思路。
非阻塞网络调用使得我们不必等待一个操作的完成,完成的异步IO正是基于这个特性构建的,并且更进一步:异步方法会立刻返回,并且在完成时,会直接或者在稍后的某个时间点通知用户。
选择器可以使得我们能够通过较少的线程来监视许多连接上的事件。
Netty核心组件:Channel、回调、Future、事件、ChannelHandler
Channel:JavaNIO的一个基本构造,目前Channel看做是传入或者传出数据的载体。
回调:一个方法,指向已经被挺给另外一个方法的引用。例如操作完之后通知A。Netty在内部使用了回调来处理时间,当一个回调被触发的时候,相关的事件可以被一个interfaceChannelHandler的的实现处理,一个新的连接已经被建立时,ChannelHandler的channelActive()回调方法会被调用。
Future:提供了一种在操作完成时通知应用程序的方法,这个对象可以看做是一个异步操作的结果的占位符,在完成的时候对其进行访问。JDK预置了java.util.concurrent.Future,但具体的实现只能允许手动检查对应的操作是否完成,或者一直阻塞直到它完成,这是非常繁琐,Netty则实现了自己的一套Future,称为:ChannelFuture。ChannelFuture提供了方式来支持注册一个或者多个ChannelFutureListener。监听器的回调方法operationComplete(),将会在对应的操作完成时被调用。由ChannelFutureListener提供的通知机制消除了手工检查对应的操作是否完成的必要。所有Netty的出站IO都将返回一个ChannelFuture——————>Netty完全是异步和时间驱动的
如何使用ChannelFutureListener
1.连接到远程节点上
2.注册一个新的ChannelFutureListener到对connect()方法的调用返回的ChannelFuture上
3.当该监听器被通知连接已经建立的时候,要检查对应的状态
4.如果成功则会写到Channel,否则从ChannelFuture中检索Throwable
对于错误的处理可以由自己进行控制,ChannelFutureListener可以看作是回调的更加精细的一个版本,回调和Future是一个互补的组合。
事件:Netty使用不同的事件来通知我们状态的更改或者是操作的状态 eq.记录日志,数据转化,流控制,应用程序逻辑等情况。事件是按照它们入站和出站数据流的相关性进行分类的。出站的动作包括 打开或者关闭到远程节点的连接,讲数据写到或者冲刷到套接字。
Netty通过触发事件讲Selector从应用程序中抽象出来,消除了所有本来讲需要手动编写的派发代码,在内部会给每一个Channel分配一个EventLoop,用以处理所有事件包括:
注册感兴趣的事件;讲事件派发给ChannelHandler;安排进一步的动作等