Netty

Netty

一、概述

  NIO的框架,主要是可以使系统在单线程的情况下可以同时处理多个客户端请求。主要是用了NIO的多路复用的技术

二、技术特点

  零拷贝

  Netty使用堆外直接内存进行Socket读写,不需要进行缓冲区的二次拷贝,如果使用传统内存,JVM会将内存Buffer拷贝一份到直接内存中,然后才写入Socket中

  Netty提供了组合Buffer对象,可以聚合多个Buffer对象,避免了传统通过内存拷贝的方式将几个小Buffer合并成一个大的Buffer。

  Netty的文件传输蚕蛹了transferTo方法,它可以直接将文件缓冲区的数据发送到目标Channel,避免了传统通过循环write方式导致的内存拷贝问题

  内存池

  为了解决堆外直接内存的分配和回收是一件耗时的操作,Netty提供了基于内存池的缓冲区重用机制

  高效的Reactor线程模型

  Reactor单线程模型,Reactor多线程模型,主从Reactor多线程模型

Reactor单线程模型

  指所有的IO操作都在同一个NIO线程上面完成,NIO线程的职责如下

  1) 作为 NIO 服务端,接收客户端的 TCP 连接;
  2) 作为 NIO 客户端,向服务端发起 TCP 连接;
  3) 读取通信对端的请求或者应答消息;
  4) 向通信对端发送消息请求或者应答消息。
Reactor多线程模型
  与单线程最大的区别是有一组NIO线程处理IO操作。有专门一个NIO线程用于监听服务端,接收客户端的TCP连接请求。网络IO操作-读、写等由一个NIO线程池负责。

传统IO每个客户端对应一个服务端,每个连接创建成功后都需要一个线程来维护,每个线程包含一个while死循环

如果并发过多,传统IO就会创建越多的线程,这是非常消耗资源的。而且是阻塞式通信,频繁的线程切换,性能下降,而且IO是以字节流为单位,效率不高。

  NIO编程

客户端连接channel,channel注册到selector中,每个channel都有一个selectkey,buffer通过selectkey来查找对应的channel来进行读写

  所以NIO可以理解为非阻塞IO,新来一个连接,不再创建一个新的线程,而是把这条连接绑定到固定的线程,然后这条连接的所有读写都由这个线程来负责。

IO模型中,一个连接都会常见一个线程,对应一个while死循环,死循环的目的就是不断检测这条连接上是否有数据可以读。

NIO中可以把许多while死循环变成一个死循环,这个死循环由一个线程控制。这就是NIO模型中Selector的作用。来检测出有数据可读的连接。

NIO三大组件

  通道、缓冲、选择器

通道:Stream升级版,Stream是单向的,读写分离,channel是双向的可以进行读的操作,也可以进行写的操作。

缓冲:内存区域存数据

选择器,监控多个信道,实现多路复用的效果。

NIO相对于IO的优势

  IO是面向流的,每次操作都是操作系统底层一个字节一个字节的读取数据,并且数据只能从一段读取到另一端,NIO是面向缓冲区的,并且可以在缓冲区中前后移动

  IO是阻塞的,当线程读取数据或者写数据时,该线程被阻塞,直到有一些数据被读取。在数据写完前,线程不能干别的事情。

  NIO是非阻塞的,不需要一直等待操作完成才能干其他事情。而是在等待的过程中可以去做别的事情。可以最大限度的使用服务器的资源

  NIO引入了IO多路复用器Selector,提供channel注册服务的线程,可以同时对接多个channel,并在线程池中为channel适配,选择合适的线程来处理channel,由于NIO模型中线程数量大大降低,线程切换效率也因此大幅度提高。

Netty

  简单来说Netty封装了NIO,不用写一堆复杂的代码。异步事件驱动的网络应用框架。

  Netty底层IO模型可以随意切换。

  Netty自带的拆包解包,异常检测等机制,可以让使用者专心业务逻辑

  解决了空轮询的bug

  自带各种协议栈

  健壮性强大。

使用就是导入依赖

Netty的事件驱动

  例如很多系统会提供onClick事件,这个事件就代表鼠标按下事件。事件驱动模型:

  1、有一个事件队列

  2、鼠标按下时,往事件队列中增加一个点击事件

  3、有个时间泵,不断循环从队列取出时间,根据不同的事件,调用不同的函数。

  4、事件一般都各自保存各自的处理方法的引用。这样每个时间都能找到对应的处理方法

为什么使用时间驱动?

  程序中的任务可以并行执行

  任务之间高度独立,彼此之间不需要互相等待

  在等待事件到来之前,任务不会阻塞

Netty使用时间驱动的方式作为底层架构,包括:

  事件队列:接收事件的入口

  分发器:将不同的事件分发到不同的业务逻辑单元

  事件通道:分发器处理器之间的联系通道

  事件处理器:实现业务逻辑,处理完成后会发出事件,触发下一步操作

  

Netty 功能特性:

  • 传输服务,支持 BIO 和 NIO。

  • 容器集成:支持 OSGI、JBossMC、Spring、Guice 容器。

  • 协议支持:HTTP、Protobuf、二进制、文本、WebSocket 等,支持自定义协议。

具体实现:

  服务端:

    创建serverbootstrap来接收客户端的连接以及为已接收的连接创建子通道。

    然后创建两个线程,一个负责接收新连接,一个负责读取数据的线程

    服务端执行

    要把两个线程放进去,

    

group就是把两个线程放进去,channel就是写一下channel对网络套接字的I/O操作,其实就是告诉这是服务端

channelInitialize对刚创建的通道进行初始化。

将channelHandler添加到channel的处理链路中

  组件从流水线头部进入,流水线上的工人按顺序对组件进行加工。

流水线相当于channelpipeline

流水线工人相当于channelHandler

客户端:

  一样的要先创建bootstrap

  创建一个EventLoop实例,

  客户端执行

  要把group、channel、handler写一下

  客户端连接服务端

  使用while循环,用writeAndFlush发送数据。

  具体使用就是前端写这个点击事件,向这个服务端发送消息。

原文地址:https://www.cnblogs.com/gushiye/p/13991213.html