004-核心技術-netty概述、傳統IO、Reactor線程模型

一、概述

1.1、原生NIO存在的問題

  1)NIO的類庫和API複雜,使用麻煩,需要熟練掌握Selector,ServerSocketChannel、SocketChannel、ByteBuffer等。

  2)需要具備其他的額外技能,需要熟悉Java多線程編程,因爲NIO涉及到Reactor模式,必須熟悉多線程和網絡編程,才能寫出高質量的NIO程序

  3)開發工作量和難度比較大,如,客戶端面臨斷連重連、網絡閃斷,半包讀寫、失敗緩存、網絡擁塞和異常流的處理等

  4)JDK NIO的bug,如Epoll Bug,他會導致Selector空輪詢,最終導致CPU100%,直到jdk1.7版本該問題仍存在,沒有根本解決。

1.2、Netty介紹

1.2.1、官網介紹

  官網地址:https://netty.io/

  官網含義:Netty is an asynchronous event-driven network application framework for rapid development of maintainable high performance protocol servers & clients.

  

  1)開源框架,異步的、基於事件驅動的網絡應用程序框架,用以快速開發高性能、高可靠的網絡IO程序。

  2)簡化現有NIO開發流程

  3)使用廣泛,如大數據、遊戲、通信,如ElasticSearch、Dubbo等。

1.2.2、優點

1)對JDK自帶的NIO進行了封裝,解決上述bug

2)設計優雅:適用於各種傳輸類型統一API阻塞和非阻塞Socket;基於靈活且可擴展的事件模型,可以清晰地分離關注點;高度可定製的線程模型-單線程,一個或多個線程池。

3)適用方便,無其他依賴項,JDK5(3.x)或6(netty 4.x)

4)高性能、吞吐量更高;延遲更低、減少資源消耗;最小化不必要的內存複製

5)安全;完整的ssl\TLS和StartTLS支持

1.2.3、版本

netty3.X 比較舊;netty5.x廢棄;netty4.x推薦適用,適用maven引入

<dependency>
    <groupId>io.netty</groupId>
    <artifactId>netty-all</artifactId>
    <version>4.1.65.Final</version>
</dependency>

二、Netty線程模型

2.1、 線程模型介紹

不同線程模型,對程序的性能影響很大,目前從存在的線程模型有:傳統阻塞IO模型和Reactor模式;

Reactor模式

根據Reactor的數量和處理資源池線程的數量不同,有3種典型的實現:單Reactor單線程、單Reactor多線程、主從Reactor多線程

Netty線程模式:主要基於主從Reactor多線程模型做了一定改進,其中主從Reactor多線程模型有多個Reactor。

參看書籍:Scalable IO in java

2.1.1、傳統IO阻塞服務模型

1)工作原理圖

2)模型特點

a、採用阻塞IO模式獲取輸入

b、每個連接都需要獨立的線程完成數據的輸入,業務處理、數據返回

3)問題分析

a、當併發數很大,就會創建大量的線程、佔用很大系統資源

b、連接創建後,如果當前線程這哪是沒有數據可讀,該線程就會阻塞在read操作,造成線程資源浪費;

2.1.2、Reactor模式

Reactor常用叫法:反應器模式;2分發者模式(DIspatcher)3通知這模式(notifier)

a、針對傳統IO服務模型的2個缺點,解決方案:

1)基於IO複用模型,多個連接共用一個阻塞對象,應用程序只需要在一個阻塞對象等待,無需阻塞等待所有連接。當某個連接有新的數據可以處理時,操作系統通知應用程序,線程從阻塞狀態返回,開始進行業務處理

2)基於線程池服用線程資源,不必再爲每個連接創建線程,將連接完成後的業務處理任務分配給線程進行處理,一個線程可以處理多個連接的業務。

b、設計思想:IO複用結合線程池

說明:Reactor模式,通過一個或多個輸入同時傳遞給服務處理器的模式(基於事件驅動)

2)服務器端程序處理傳入的多個請求,並將它們同步分派到相應的處理線程,因此Reactor模式也叫Dispatcher模式

3)Reactor模式號私用IO複用監聽事件,收到事件後,分發給某個線程,這點就是網絡服務器高併發處理關鍵。

c、核心組成

1)Reactor,在一個單獨的線程中運行,負責監聽和分發事件,分發給適當的處理程序來對IO事件作出反應。

2)Handlers,處理程序執行IO事件要完成的實際事件。Reactor通過調度適當的處理程序來相應IO事件,處理程序執行非阻塞操作。

d、Reactor優點

1)響應快,不必爲單個同步時間所阻塞,雖然Reactor本身依然是同步的;2)可以最大程度的避免複雜的多線程及同步問題,並且避免了多線程/進程的切換開銷

3)擴展性號,可以方便的通過增加Reactor實例個數來充分利用CPU資源;4)複用性好,Reactor模型本身與具體事件處理邏輯無關,具有很高的複用性

2.1.2.1、單Reactor單線程【不常用,原Redis使用】

  

上節的NIO原生API的羣聊即是此種模式

方案說明:1)Select就是前面IO複用模型介紹的標準網絡編程API,可以實現應用程序通過一個阻塞對象監聽多路連接請求。

2)Reactor對象通過Select監控客戶端請求事件,收到事件後通過DIspatch進行分發

3)如果是建立連接請求事件,則由Acceptor通過Accept處理連接請求,然後創建一個Handler對象處理連接完成後的後續業務處理

4)如果不是建立連接事件,則Reactor會分發調用連接對應的Handler來響應

5)Handler會完成Read→業務處理→Send的完整業務流程

優缺點:優點:1)模型簡單,沒有多線程,進程通信、競爭的問題,全部都在一個線程中完成

缺點1)性能問題,只有一個線程,無法完全發揮多核CPU的性能。Handler在處理某個連接上的業務時,整個進程無法處理其他連接事件,很容易導致性能瓶頸

缺點2)可靠性問題,線程意外終止,或者進入死循環,會導致整個系統通信模塊不可用,不能接收和處理外部消息,造成節點故障。

使用場景:客戶端的數量有限,業務處理非常快速,比如Redis在業務處理的時間複雜度O(1)的情況。

2.1.2.2、單Reactor多線程

工作原理圖:

  

說明:1)Reactor對象通過Select監控客戶端請求事件,收到事件後,通過dispatch進行分發

2)如果建立連接請求,則由Acceptor通過accept處理連接請求,然後創建一個Handler對象處理完連接後的各種事件

3)如果不是連接請求,則由reactor分發調用連接對應的handler來處理

4)handler只負責響應事件,不做具體的業務處理,通過read讀取數據後,會分發給後面的worker線程池的某個線程處理業務

5)wocker線程池會分配獨立線程完成真正的業務,並將結果返回給handler

6)handler收到相應後,通過send將結果返回給client

b、優缺點

優點:可以充分利用多核CPU的處理能力

缺點:多線程數據共享和訪問比較複雜,reactor處理所有的事件的監聽和響應,在單線程運行,在高併發場景容易出現性能瓶頸

2.1.2.3、主從Reactor多線程

針對單Reactor多線程模型中,在單線程運行,在高併發場景容易出現性能瓶頸,可以讓Reactor在多線程中運行

工作原理圖

優缺點:優點:父線程與子線程的數據交互簡單職責明確,父線程只需要接收新鏈接,子線程完成後續的業務處理;

缺點:編程複雜度較高

應用:Nginx主從Reactor多進程模型,Memcached主從多線程模式,Netty主從多線程模式

 

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