ESLE:Netty 用于和标签通信(接收与发送)

ESLE:Netty 用于和标签通信(接收与发送)前言HTTP服务器之所以称为HTTP服务器,是因为编码解码协议是HTTP协议,如果协议是Redis协议,那它就成了Redis服务器,如果协议是WebSocket,那它就成了WebSocket服务器,等等

前言

    HTTP服务器之所以称为HTTP服务器,是因为编码解码协议是HTTP协议,如果协议是Redis协议,那它就成了Redis服务器,如果协议是WebSocket,那它就成了WebSocket服务器,等等。

    使用Netty你就可以定制编解码协议,实现自己的特定协议的服务器。

    上面我们说的是一个传统的多线程服务器,这个也是Apache处理请求的模式。在高并发环境下,线程数量可能会创建太多,操作系统的任务调度压力大,系统负载也会比较高。那怎么办呢?

1、NIO(noblocking IO)

    NIO不是java的概念,又称为IO多路复用,它是由操作系统提供的系统调用,早期这个操作系统调用的名字是select,但是性能低下,后来渐渐演化成了Linux下的epoll和Mac里的kqueue。我们一般就说是epoll,因为没有人拿苹果电脑作为服务器使用对外提供服务。而Netty就是基于Java NIO技术封装的一套框架。

    NIO又是什么呢?非阻塞IO,与传统阻塞IO的区别,下面先说一下传统阻塞IO: 

  1. Accept是阻塞的,只有新连接来了,Accept才会返回,主线程才能继
  2. Read是阻塞的,只有请求消息来了,Read才能返回,子线程才能继续处理
  3. Write是阻塞的,只有客户端把消息收了,Write才能返回,子线程才能继续读取下一个请求

所以传统的多线程服务器是BlockingIO模式的,从头到尾所有的线程都是阻塞的。

ESLE:Netty 用于和标签通信(接收与发送)

1.1、Netty并发多

    NIO的单线程能够处理多连接。当连接建立时,有两个步骤:第一步是接收客户端发过来的全部数据;第二步是服务器处理完请求业务之后返回response给客户端。

    BIO与NIO的区别在第一步,在BIO中,等待客户端发数据这个过程是阻塞的,这造成一个线程只能处理一个请求的情况,而机器支持的最大线程数是有限的,这就是BIO不能支持高并发的原因。而NIO中,当一个Socket请求建立连接时,Thread并不会阻塞地去接收这个Socket,而是将这个请求交给Selector,Selector会不断去遍历所有Socket,一旦有一个Socket建立完成,它就会通知Thread,Thread线程开始处理请求并返回数据(这个过程是不阻塞的),这样就能一个Thread处理多个请求了。

ESLE:Netty 用于和标签通信(接收与发送)

1.2、Netty传输快

    Netty传输依赖NIO的一个特性:零拷贝。Java的内存有堆内存、栈内存和字符串常量池等,其中堆内存是Java对象存放的地方,是占用内存空间最大的一块。一般我们的数据如果需要从IO读取到堆内存,中间需要经过Socket缓冲区,也就是说一个数据会被拷贝两次才能到达他的的终点,如果数据量大,就会造成不必要的资源浪费。

    针对这种情况,Netty在接收数据的时候,会在堆内存之外开辟一块单独内存,数据直接从IO读到这块内存中去,在netty里面通过ByteBuf(netty数据处理的容器)可以直接对这些数据进行操作,从而加快了传输速度。

1.3、Netty封装好

    Netty封装好主要体现在三个地方:Channel(表示一个连接)、ByteBuf(存储字节的容器)、Codec(编码/解码器)。

1.3.1、Channel

    数据传输流,与channel相关的概念有以下四个:

    ESLE:Netty 用于和标签通信(接收与发送)

  • Channel,表示一个连接,可以理解为每一个请求,就是一个Channel;
  • ChannelHandler,用于处理业务;
  • ChannelHandlerContext,用于传输业务数据;
  • ChannelPipeline,用于保存处理过程需要用到的ChannelHandler和ChannelHandlerContext。

1.3.2、ByteBuf

    ByteBuf是一个存储数据(字节)的容器,特点是使用方便。它既有自己的读索引和写索引,方便你对整段字节缓存进行读写,也支持get/set,方便你对其中每一个字节进行读写。他有三种使用模式,分别如下:

  • Heap  Buffer堆缓存区:将数据存储在堆空间;
  • Direct Buffer直接缓存区:内存分配不发生在堆,jdk1.4后引入的nio的ByteBuffer类允许jvm通过本地方法调用分配内存;
  • Composite Buffer 复合缓冲区:复合缓冲区相当于多个不同ByteBuf的视图,这是netty提供的,jdk不提供这样的功能。

1.3.3、Codec

    Netty中的编码/解码器,通过他你能完成字节与pojo(Plain Ordinary Java Object 简单Java对象)、pojo与pojo的相互转换,从而达到自定义协议的目的。
    在Netty里面最有名的就是HttpRequestDecoder(编码)和HttpResponseEncoder(解码)了。

2、NIO与BIO的优缺点

  • BIO,同步阻塞IO,阻塞整个步骤,如果连接少,他的延迟是最低的,因为一个线程只处理一个连接,适用于少连接且延迟低的场景,比如说数据库连接;
  • NIO,同步非阻塞IO,阻塞业务处理但不阻塞数据接收,适用于高并发且处理简单的场景,比如聊天软件;
  • 基于NIO的netty框架的特点:并发高、传输快、封装好。

3、搭建简单的Netty服务器、实现长连接

用idea搭建简单的netty服务器

 

4、Netty在本项目中的应用

4.1、netty后台项目结构

ESLE:Netty 用于和标签通信(接收与发送)

 

4.2、netty被动监听流程

ESLE:Netty 用于和标签通信(接收与发送)

  • 每当路由器发送数据到8087端口时,系统会解析出字节数组的class和id,确定命令含义,新开线程调用相应的处理器进行操作。
  • 每当路由器断开时,会更新路由器表中的isWorking置为0。
  • 以上处理器除了注册处理器会发送应答ACK或NACK,其他处理器均不会发送应答。

 

 

今天的文章ESLE:Netty 用于和标签通信(接收与发送)分享到此就结束了,感谢您的阅读。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/82572.html

(0)
编程小号编程小号

相关推荐

发表回复

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