Netty是一个NIO客户端服务端框架与网络编程有什么关系?( 三 )
分别实现Encoder和Decoder , 可能是代码放在两个类里实现;Netty提供了Codec , 在一个类里实现编码和解码 。
Netty对协议的支持 , 都是通过提供编码解码器实现的 。 例如:http协议
HttpRequestEncoder , 将HttpRequest或HttpContent编码成ByteBuf HttpRequestDecoder , 将ByteBuf解码成HttpRequest和HttpContent HttpResponseEncoder , 将HttpResponse或HttpContent编码成ByteBuf HttpResponseDecoder , 将ByteBuf解码成HttpResponse和HttpContent
8、Netty 为什么高效?1)、线程模型
- Reactor单线程模型;作为NIO服务端 , 接收客户端的TCP连接;作为NIO客户端 , 向服务端发起TCP连接;读取通信对端的请求或者应答消息;向通信对端发送消息请求或者应答消息 。
- Reactor多线程模型;有专门一个NIO线程-Acceptor线程用于监听服务端 , 接收客户端的TCP连接请求;网络IO操作-读、写等由一个NIO线程池负责 , 线程池可以采用标准的JDK线程池实现 , 它包含一个任务队列和N个可用的线程 , 由这些NIO线程负责消息的读取、解码、编码和发送;1个NIO线程可以同时处理N条链路 , 但是1个链路只对应1个NIO线程 , 防止发生并发操作问题 。
- 主从Reactor多线程模型 。 为了解决1个服务端监听线程无法有效处理所有客户端连接的性能不足问题 , 有一组NIO线程处理服务器短的监听 。
2)、Zero Copy
- Netty的接收和发送ByteBuffer采用DIRECT BUFFERS , 使用堆外直接内存进行Socket读写 , 不需要进行字节缓冲区的二次拷贝 。 如果使用传统的堆内存(HEAP BUFFERS)进行Socket读写 , JVM会将堆内存Buffer拷贝一份到直接内存中 , 然后才写入Socket中 。 相比于堆外直接内存 , 消息在发送过程中多了一次缓冲区的内存拷贝 。 ByteBufAllocator 通过ioBuffer分配堆外内存:public ByteBuf ioBuffer() {return PlatformDependent.hasUnsafe() ? this.directBuffer(256) : this.heapBuffer(256);}
- Netty提供了组合Buffer对象 , 可以聚合多个ByteBuffer对象 , 用户可以像操作一个Buffer那样方便的对组合Buffer进行操作 , 避免了传统通过内存拷贝的方式将几个小Buffer合并成一个大的Buffer 。 private int addComponent0(boolean increaseWriterIndex, int cIndex, ByteBuf buffer) {......wasAdded = this.components.add(c);...... return var11;}
- Netty的文件传输采用了transferTo方法 , 它可以直接将文件缓冲区的数据发送到目标Channel , 避免了传统通过循环write方式导致的内存拷贝问题 。 linux零拷贝 , sendfile private native long transferTo0(FileDescriptor var1, long var2, long var4, FileDescriptor var6);
多路复用IO有多种实现方式 , 其中 , select/poll是所有操作系统都支持的方式 , 提出时间较早 。 JAVA NIO默认实现使用的Select , windows操作系统只支持Select 。 Epoll提出较晚 , 在linux系统提供 , 是目前比较成熟稳定的方案 。
- select/poll 函数监视的文件描述符分3类 , 分别是writefds(可写)、readfds(可读)、和exceptfds(异常) 。 调用后select函数会阻塞 , 直到有描述符就绪(有数据 可读、可写、或者有except) , 或者超时(timeout指定等待时间 , 如果立即返回设为null即可) , 函数返回 。 当select函数返回后 , 可以通过遍历fdset , 来找到就绪的描述符 。 select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);
- epoll是在2.6内核中提出的 , 是之前的select和poll的增强版本 。 首先 , epoll使用一组函数来完成 , 而不是单独的一个函数;其次 , epoll把用户关心的文件描述符上的事件放在内核里的一个事件表中 , 无须向select和poll那样每次调用都要重复传入文件描述符集合事件集 。 int epoll_create(int size); // 该函数返回的文件描述符指定要访问的内核事件表 , 是其他所有epoll系统调用的句柄 , int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event); //告诉操作系统需要关注哪些文件描述符int epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout); // 等待事件发生
- 采用Http协议 , 增加了http协议的解码编码过程
- http协议本身无状态的 , 连接的复用不好;(可通过keep-alive解决一部分连接复用的问题)
2)、服务代理 , 代表 NRedis-Proxy 参考:
NRedis-Proxy 是一个Redis中间件服务 , 第一个Java 版本开源Redis中间件 , 无须修改业务应用程序任何代码与配置 , 与业务解耦;以Spring为基础开发自定义标签 , 让它可配置化 , 使其更加容易上手;以netty 作为通信传输工具 , 让它具有高性能 , 高并发 , 可分布式扩展部署等特点,单片性能损耗约5%左右 。
- 对手|一加9Pro全面曝光,或是小米11最大对手
- 行业|现在行业内客服托管费用是怎么算的
- 王兴称美团优选目前重点是建设核心能力;苏宁旗下云网万店融资60亿元;阿里小米拟增资居然之家|8点1氪 | 美团
- 手机基带|为了5G降低4G网速?中国移动回应来了:罪魁祸首不是运营商
- 技术|做“视频”绿厂是专业的,这项技术获人民日报评论点赞
- 互联网|苏宁跳出“零售商”重组互联网平台业务 融资60亿只是第一步
- 车企|华为不造车!但任正非加了一个有效期,3年
- 体验|闭上眼睛点外卖是什么感觉?时隔一年再次体验,进步令人欣慰
- 同轴心配合|用SolidWorks画一个直角传动,画四个零件就行
- 先别|用了周冬雨的照片,我会成为下一个被告?自媒体创作者先别自乱阵脚