ESLE:Netty 用於和標籤通信(接收與發送)

前言

    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模式的,從頭到尾所有的線程都是阻塞的。

1.1、Netty併發多

    NIO的單線程能夠處理多連接。當連接建立時,有兩個步驟:第一步是接收客戶端發過來的全部數據;第二步是服務器處理完請求業務之後返回response給客戶端。

    BIO與NIO的區別在第一步,在BIO中,等待客戶端發數據這個過程是阻塞的,這造成一個線程只能處理一個請求的情況,而機器支持的最大線程數是有限的,這就是BIO不能支持高併發的原因。而NIO中,當一個Socket請求建立連接時,Thread並不會阻塞地去接收這個Socket,而是將這個請求交給Selector,Selector會不斷去遍歷所有Socket,一旦有一個Socket建立完成,它就會通知Thread,Thread線程開始處理請求並返回數據(這個過程是不阻塞的),這樣就能一個Thread處理多個請求了。

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相關的概念有以下四個:

    

  • 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後臺項目結構

 

4.2、netty被動監聽流程

  • 每當路由器發送數據到8087端口時,系統會解析出字節數組的class和id,確定命令含義,新開線程調用相應的處理器進行操作。
  • 每當路由器斷開時,會更新路由器表中的isWorking置爲0。
  • 以上處理器除了註冊處理器會發送應答ACK或NACK,其他處理器均不會發送應答。

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章