Netty完勝Java I/O與NIO?

前言

在面對不少當前的互聯網應用程序時,其核心底層功能大多須要高性能網絡編程來支撐,而對於Java來講是幸運的,由於在這個領域已經有了一個正在不斷健壯的框架,他就是Netty(一款異步的事件驅動的網絡應用程序框架,支持快速地開發可維護的高性能的面向協議的服務器和客戶端)。java

那麼這個框架入手容易嗎?git

實際上是有必定難度的,即便是一些例子(具有高性能的系統),想要了解並熟知,不只須要一流的編程技巧,還須要幾個複雜領域(網絡編程、多線程處理和併發)的專業知識。github

可是Netty確實提供了極爲豐富的網絡編程工具集,值得咱們花大量時間來消化它。編程

其終究是框架

Netty的架構方法和設計原則是:每一個小點都和它的技術性內容同樣重要,無比精妙。咱們能夠更關注如下幾點:安全

關注點分離——業務和網絡邏輯解耦
模塊化和可複用性
可測試性做爲首要的要求

瞭解Java I/O與NIO

代碼示例 阻塞I/O
ServerSocket serversocket = new ServerSocket(portNumber);
Socket clientSocket = serverSocket.accept();
BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
String request, response;
while((request = in.readLine()) != null){
    if("Done".equals(request)){
        break;
    }
    response = processRequest(request);
    out.println(response);
}

恰如以上代碼就實現了Socket API的基本模式之一。或許你應該注意到如下幾點:服務器

  • ServerSocket上的accept()方法將會一直阻塞到一個鏈接創建,隨後返回一個新的Socket用於客戶端和服務器之間的通訊。該ServerSocket將繼續監聽傳入的鏈接。
  • BufferedReader和PrintWriter都衍生自Socket的輸入輸出流,前者從一個字符輸入流中讀取文本,後者打印對象的格式化的表示到文本輸出流。
  • readLine()方法將會阻塞,直到有一個換行符或者回車符結尾的字符串被讀取到。
  • processRequest()方法即服務端對客戶端的請求進行處理。
這段代碼是否存在弊端?
  • 其只能同時處理一個鏈接,要管理多個併發客戶端,須要爲每一個新的客戶端Socket建立一個新的Thread。(以下圖所示)

圖片描述

那麼你或許能夠考慮到如下幾點影響?
  • 一、在任什麼時候候均可能有大量的線程處於休眠狀態,只是等待輸入或者輸出數據就緒,這可能算是一種資源浪費。
  • 二、爲每一個線程的調用棧分配內存,根據操做系統默認值區間通常爲64KB到1MB。
  • 三、即便Java虛擬機(JVM)在物理上能夠支持很是大數量的線程,可是遠在到達該極限以前,上下文切換所帶來的開銷就已經很是麻煩了。
結論是?

雖然以上對於支撐中小數量的客戶端來講還算能夠接受,可是在面對100 000或更多併發鏈接資源使用它是很不理想的。網絡

很幸運,你還可使用NIO這種方式!(2002年Java引入對於非阻塞I/O的支持)
  • 使用setsocket()方法配置套接字,以便讀/寫調用在沒有數據的時候當即返回
  • 使用操做系統的事件通知API註冊一組非阻塞套接字,以肯定它們中是否有任何的套接字已經有數據可供讀寫。
  • 以上兩點就字面理解可能比較困難,那麼你能夠抽象記憶如下的觀點與流程圖!
使用Selector的非阻塞I/O

圖片描述

  • 上圖是一種非阻塞設計,Java.nio.channels.Selector是Java的非阻塞I/O實現的關鍵。
  • 它使用了事件通知API以肯定在一組非阻塞套接字中有哪些已經就緒可以進行I/O相關的操做。
  • 一個單一的線程即可以處理多個併發的鏈接。
相比之下,與阻塞I/O相比,它能更好的利用資源
  • 使用較少的線程即可以處理許多鏈接,減小了內存管理和上下文切換帶來的開銷
  • 當沒有I/O操做須要處理的時候,線程也能夠被用於其餘任務。

Netty的出場!!!

儘管你能夠直接使用這些API進行直接構建應用程序(在高負載下可靠和高效的處理和調度I/O操做),可是要作到徹底正確與安全是很難處理,那麼這是咱們將工做留給高性能的網絡編程專家Netty或許更合適。多線程

相關項目 By GitHub

項目名:InChat
項目地址:https://github.com/UncleCatMy...
項目介紹:基於Netty4與SpringBoot,聊天室WebSocket(文字圖片)加API調用Netty長連接執行發送消息(在線數、用戶列表)、Iot物聯網-MQTT協議、TCP/IP協議單片機通訊,異步存儲聊天數據架構


若是本文對你有所幫助,歡迎關注我的技術公衆號併發

圖片描述

相關文章
相關標籤/搜索