Netty詳解

近日在學習netty,卻發現沒那麼容易上手,專研了幾天後算是弄清楚了netty究竟是幹什麼的,所看資料比較多,此文章便把這些資料與個人思考作一個總結幫助你們更好入門。編程

要更好理解netty首先要了解如下一些前置知識後端

  • Blocking I/O ,請看如下Java 網絡編程的一段代碼
public class PlainOioServer {
 public void serve(int port) throws IOException {
 final ServerSocket socket = new ServerSocket(port);
 try {
 for (;;) {
 //accept一直阻塞直到獲取一個客戶端,所謂阻塞就是不執行後面代碼,不阻塞就是繼續執行後續代碼
 final Socket clientSocket = socket.accept();
 System.out.println(
 "Accepted connection from " + clientSocket);
 //建立一個新的Thread處理
 new Thread(new Runnable() {
 @Override
 public void run() {
 OutputStream out;
 try {
 out = clientSocket.getOutputStream();
 out.write("Hi!\r\n".getBytes(
 Charset.forName("UTF-8")));
 out.flush();
 clientSocket.close();
 }
 catch (IOException e) {
 e.printStackTrace();
 }
 finally {
 try {
 clientSocket.close();
 }
 catch (IOException ex) {
 // ignore on close
 }
 }
 }
 }).start();
 }
 }
 catch (IOException e) {
 e.printStackTrace();
 }
 }
}

當請求不少的時候會爲每個請求建立一個線程,每個線程都會分配必定的內存,並且這些線程都會阻塞,致使資源利用率低下,這樣的設計必定知足不了高併發。網絡

  • Non-blocking I/O ,爲了知足多個請求Java引入了NIO包進行編程,這裏得引入幾個名詞多線程

    回調(Callback):A方法裏有B方法的一個引用,當B方法完成某一條件後能夠通知A方法
       事件驅動(Event-driven):當一個事件放生時,能夠在任什麼時候間響應這個事件

    具體代碼就不貼了了,涉及不少類看着頭暈,網上也有不少解析,對着下面一張圖我說一下原理架構

clipboard.png
對於每個socket,就對應一個Channel,每一個Channel會到Selector註冊,當某一個Channel狀態改變的時候,就會觸發響應的事件,而後根據事件的類型去執行相應的動做。Channel狀態改變會通知selector,這就是上面指的回調,根據發生事件的類型去執行任務就是所謂的事件驅動,流程算是清楚了,可是爲何這麼作呢,這一點我再好好解釋。併發

典型的後端服務分爲通訊層和業務邏輯層,通訊層一般鏈接數不少(用戶大部分時間實在瀏覽而非點擊),收發數據是慢速I/O。傳統方式作的話每一個請求分配線程,並且線程經常由於等待I/O阻塞,且不一樣線程間頻繁切換,這都是很浪費資源的。多線程的好處就是當一個線程阻塞時,另外一個線程能夠繼續執行任務,而這種模式下大部分線程都會因I/O而阻塞。怎麼令線程不阻塞呢,咱們就要使用異步回調的方式,用一個線程去管理這些請求的狀態,當某個請求數據準備好了就去調用它,沒準備好就操做下一個請求,這就是上面的selector。框架

Netty的產生緣由是使Java NIO的編程更容易。異步


Netty

定義:一個異步事件驅動的網絡應用框架,幫助快速開發高性能的客戶端與服務端。socket

clipboard.png

上面是Netty的一張架構圖。ide

每個Channel(一個客戶端請求)註冊一個EventLoop,這個EventLoop會處理這個請求的I/O事件直到這個請求結束。

未完待續。。。

相關文章
相關標籤/搜索