Java网络编程中,OIO和NIO的网络模型是截然不同的,然而Netty为所有阻塞和非阻塞的IO提供了一个通用的API,使用这个API,可以简化不同传输的改变,屏蔽了上层的感知

我们看下不使用Netty来使用NIO和OIO

图片

上面是一段阻塞式的方法获取连接的应用程序,如果改为了非阻塞的话,需要完全的重写吧

而使用Netty实现就会完全不一样

图片

非阻塞版本只需要将EventLoopGroup从原本的OIO的EventLoopGroup改为

new NioEventLoopGroup

channel改为 NioServerSocketChannel.class

这样,Netty为每种传输的实现暴露了相同的API

这样外部的代码基本可以不受影响的使用

所有需要实现的,只有ChnanelPipeline和ChannelHandler

接下来,我们说下传输的API本身

核心是interface Channel

用于所有的IO操作.Channel类层次

图片

每个Channel都包含一个ChannelPipeline和ChannelConfig的引用持有

为了保证其有序性,Channel还额外实现了Comparable的接口

ChannelPipeline持有所有处理入站和出站事件的ChannelHandler的实例

ChannelHandler常见的用法有

将数据从一种格式进行转为另一种

提供异常通知

提供Channel的活动通知

提供当Channel注册到EventLoop或者从EventLoop注销的时候通知

提供有关用户自定义事件的通知

Channel中也有很多的其他方法

常见的在列表中

图片

比如我们写到Channel的话,可能出现并发的问题,不过Channel的写入是线程安全的,可以保证消息按照顺序发送

图片

Netty还内置了写传输,但是并非所有的传输都支持每一种协议,我们需要选择一个和应用程序使用协议相容的传输

提供的Netty的传输列表如下

NIO 使用java.nio.channels作为基础–基于选择器的方式

Epoll io.netty.channel.epoll 由JNI驱动的epoll和非阻塞IO,更适合在Linux上使用

OIO 使用java.net作为基础–阻塞流

Local VM内部利用管道进行本地的通信

Embedded Embedded 使用ChannelHander测试的时候使用,不需要创建一个真正的基于网络的传输

那么不同的传输协议之间的区别在于

1.NIO是一个完全的异步的实现,一个基于选择器的API

选择器就是一个注册器,我们可以将监视者注册到选择器里面,等到Channel的状态发生时候得到通知,可能的变化有

新的Channel准备好了

连接完成

Channel已经有了就绪的可以读的数据

Channel可以用于写数据

整体的传输流程如下

图片

2.Epoll

用于Linux本地非阻塞的传输

因为Linux提供了高性能的可扩展的IO事件通知特性

性能更加的好,也是Linux上非阻塞网络编程的事实标准,JDK NIO API使用了这些epoll调用

Netty为Linux提供了一组NIO API,其以一种和其本身的设计更加一致的方式使用epoll,并且以一种更加轻量的方式使用中断,应用程序旨在运行Linux系统,epoll是合适的选择

如果要进行使用 只需要将NioEventLoopGroup替换为EpollEventLoopGroup,并且NioServerSocketChannel.class改为EpollServerSocketChannel.class

3.oio

老式的传统的传输API,建立在java.net包的阻塞上的,并不是异步的

Netty的支持手段在于设置了SO_TIMEOUT的标志,等待一个IO操作完成的最大毫秒数,操作在指定时间内没有完成,抛出一个SocketTimeout Exception的标志,Netty捕获异常并继续进行处理循环,EventLoop下一次运行时,再次尝试.

图片

3.Local传输

Local传输,用于在同一个JVM中运行客户端和服务器程序交互,传输也不需要真正的网络流量

4.Embedded传输

方便创建单元测试用例

发表评论

邮箱地址不会被公开。 必填项已用*标注