Netty笔记 (一)初识Netty

140 阅读3分钟

Netty是什么

netty是一个异步的、事件驱动的网络应用程序框架,可用于快速开发可维护的、高性能的协议服务器和客户端。

Netty的优势

  1. 支持Http等常用的应用层协议
  2. 解决了传输问题,比如TCP传输过程中出现的粘包和半包问题
  3. 支持流量控制等定制化功能
  4. 具有完善的异常处理功能。例如,网络闪断、拥塞等

Netty核心组件

NioEventLoop

Netty的NioEventLoop并不是一个纯粹的I/O线程,它除了负责I/O的读写之外还负责系统Task和定时任务的执行。

Channel

Channel是Netty抽象出来的网络I/O读写相关接口。采用Facade模式,对JDK原生的SocketChannel和ServerSocketChannel进行统一的接口封装,将网络I/O操作、网络I/O相关联的其他操作封装起来,统一对外提供。内部聚合Unsafe对象,协助Channel进行网络读写相关的操作。

public interface Channel extends AttributeMap, ChannelOutboundInvoker, Comparable<Channel> {

    // Channel唯一ID
    ChannelId id();

    // Channle所关联的eventLoop
    EventLoop eventLoop();

    Channel parent();

    // 配置
    ChannelConfig config();

    boolean isOpen();

    // Channel是否被注册进入eventLoop
    boolean isRegistered();

    boolean isActive();

    ChannelMetadata metadata();

    // TCP绑定的本机网络IP(网卡)+端口号
    SocketAddress localAddress();

    // 网络远端地址
    SocketAddress remoteAddress();

    ChannelFuture closeFuture();

    boolean isWritable();

    long bytesBeforeUnwritable();

    long bytesBeforeWritable();

    Unsafe unsafe();

    ChannelPipeline pipeline();

    //
    ByteBufAllocator alloc();

    @Override
    Channel read();

    // 将循环数组中的数据发送到网络
    @Override
    Channel flush();

    interface Unsafe {

        RecvByteBufAllocator.Handle recvBufAllocHandle();

        SocketAddress remoteAddress();

        void bind(SocketAddress localAddress, ChannelPromise promise);

        void connect(SocketAddress remoteAddress, SocketAddress localAddress, ChannelPromise promise);

        void disconnect(ChannelPromise promise);
        
        void close(ChannelPromise promise);

        void closeForcibly();
        
        void deregister(ChannelPromise promise);

        void beginRead();

        void write(Object msg, ChannelPromise promise);
        
        void flush();
        
        ChannelPromise voidPromise();

        ChannelOutboundBuffer outboundBuffer();
    }
}

ByteBuf

Netty的ByteBuffer的替代品是ByteBuf,一个强大的实现,既解决了JDK API的局限性,又为网络应用程序的开发者提供了更好的API。 ByteBuf有一下优点:

  1. 可以被用户自定义缓冲区类型扩展
  2. 通过内置的复合缓冲区实现了透明的零拷贝
  3. 容量可以按需增长
  4. 在读和写两种模式之间切换不需要调用ByteBuffer的flip()方法
  5. 读和写使用了不同的索引
  6. 支持方法的链式调用
  7. 支持引用计数
  8. 支持池化
  9. 可以使用堆外内存

ChannelHandler

ChannelHandler类似于Servlet的Filter过滤器,负责对I/O事件或者I/O操作进行拦截和处理,可以选择性的拦截和处理自己感兴趣的事件,也可以透传和终止事件的传递。 基于ChannelHandler接口,用户可以方便地进行业务逻辑的制定,例如打印日志、统一封装异常信息、性能统计和消息编码等。

ChannelPipeline

ChannelPipleline是ChannelHandler的容器,负责ChannelHandler的管理和事件拦截的调度。 Netty将Channel的数据管道抽象为ChannelPipleline,消息在ChannelPipleline中流动和传递。ChannelPipeline持有I/O事件拦截器ChannelHandler的链表,由ChannelHandler对I/O事件进行拦截和处理,可以方便地通过新增和删除ChannelHandler来实现不同的业务逻辑定制,不需要对已有的ChannelHandler进行修改,能够实现修改封闭和对扩展的支持。