概述
提起Channel,会想到JDK的NIO类库的重要组成部分:java.nio.SocketChannel
和java.nio.ServerSocketChannel
,用于非阻塞的I/O操作。
类似于NIO的Channel,Netty提供自己的Channel及其子类实现,用于异步I/O操作和其他相关的操作。
Unsafe是内部接口,聚合在Channel中协助进行网络读写相关的操作,因为它的设计初衷就是Channel的内部辅助类,不应该被Netty框架的上层使用者调用。
Channel工作原理
Channel是Netty抽象出来的网络I/O读写相关的接口,为什么不使用JDK NIO原生的Channel而要另外炉灶,主要原因:
1)JDK的SocketChannel和ServerSocketChannel没有统一的Channel接口供业务开发者使用,对于用户而言,没有统一的操作视图,使用起来并不方便;
2)JDK的SocketChannel和ServerSocketChannel的主要职责就是网络I/O操作,由于他们是SPI类接口,由具体的虚拟机厂家来提供,所以通过继承SPI功能类来扩展其功能的难度很大;直接实现ServerSocketChannel和SocketChannel抽象类,其工作量和重新开发一个新的Channel功能类是差不多的;
3)Netty的Channel需要能够跟Netty的整体架构融合在一起,例如I/O模型、基于ChannelPipeline的定制模型,以及基于元数据描述配置化的TCP参数等,这些JDK的ScoketChannel和ServerSocketChannel都没有提供,需要重新封装;
4)自定义的Channel,功能实现更加灵活。
基于上述4个原因,Netty重新设计了Channel接口,并且给予了很多不同的实现。它的设计原理比较简单,但是功能却比较繁杂,主要的设计理念:
1)在Channel接口层,采用Façade模式进行统一封装,将网络I/O操作、网络I/O相关联的其他操作封装起来,统一对外提供;
2)Channel接口的定义尽量大而全,为SocketChannel和ServerSocketChannel提供统一的视图,由不同子类实现不同的功能,公共功能在抽象父类中实现,最大程度上实现功能和接口的重用;
3)具体实现采用聚合而非包含的方式,将相关的功能聚合在Channel中,由Channel统一负责配置和调度。
io.netty.channel.Channel
是Netty网络操作抽象类的主要功能:
1)网络的读、写;
2)客户端发起连接、主动关闭连接
3)链路关闭
4)获取通信双方的网络地址
5)获取该Channel的EventLoop
6)获取缓冲区分类器ByteBufAllocator和pipeline等
7)获取元数据metadata()
4)parent():对于服务端Channel为空;对于客户端Channel为创建它的ServerSocketChannel
5)id() 返回ChannelId对象 Channel的唯一标识符:机器MAC地址+当前进程ID+时间毫秒+时间纳秒+32位随机整数+32位自增序列数。
Channel类图
AbstractChannel:采用聚合的方式封装各种功能:
public abstract class AbstractChannel extends DefaultAttributeMap implements Channel {
……
private final Channel parent;
private final ChannelId id;
private final Unsafe unsafe;
private final DefaultChannelPipeline pipeline;
private final VoidChannelPromise unsafeVoidPromise = new VoidChannelPromise(this, false);
private final CloseFuture closeFuture = new CloseFuture(this);
private volatile SocketAddress localAddress;
private volatile SocketAddress remoteAddress;
private volatile EventLoop eventLoop;
private volatile boolean registered;
/** Cache for the string representation of this channel */
private boolean strValActive;
private String strVal;
可以从成员变量的定义可以看出来,聚合了:parent, id, unsafe, pipeline, eventLoop等。
Unsafe
Unsafe接口实际上是Channel接口的辅助接口,它不应该被用户直接调用。实际的网络I/O读写操作都是由Unsafe接口及其功能类负责实现的。它的含义不是说它的方法是不安全的,而是说它的接口是给框架本身调用的,不要暴露给业务层调用。
Unsafe的最底层实现类采用了模板方法模式,NioMessageUnsafe
绑定到了NioServerSocketChannel
,NioByteUnsafe
绑定到NioSocketChannel
,最终的IO读写方法实现在NioServerSocketChannel
和NioByteUnsafe
中,调用了Java的ServerSocketChannel
和SocketChannel
来实现。
最后
以上就是狂野星星为你收集整理的Channel和Unsafe的全部内容,希望文章能够帮你解决Channel和Unsafe所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复