Java IO編程全解(六)——4種I/O的對比與選型

来源:http://www.cnblogs.com/Joanna-Yan/archive/2017/11/09/7804185.html
-Advertisement-
Play Games

轉載請註明出處:http://www.cnblogs.com/Joanna-Yan/p/7804185.html 前面講到:Java IO編程全解(五)——AIO編程 為了防止由於對一些技術概念和術語的理解或者叫法不一致而引起歧義,這裡對涉及到的專業術語或者技術用語做下聲明:如果它們與其他一些地方的 ...


  轉載請註明出處:http://www.cnblogs.com/Joanna-Yan/p/7804185.html 

  前面講到:Java IO編程全解(五)——AIO編程

  為了防止由於對一些技術概念和術語的理解或者叫法不一致而引起歧義,這裡對涉及到的專業術語或者技術用語做下聲明:如果它們與其他一些地方的稱呼不一致,請以本解釋為準。

非同步非阻塞I/O

  很多人喜歡將JDK1.4提供的NIO框架成為非同步非阻塞I/O,但是,如果嚴格按照UNIX網路編程模型和JDK的實現進行區分,實際上它只能被稱為非阻塞I/O,不能叫非同步非阻塞I/O。在早期的JDK1.4和1.5 update10版本之前,JDK的Selector基於select/poll模型實現,它是基於I/O復用技術的非阻塞I/O,不是非同步I/O。在JDK1.5 update10和Linux core2.6以上版本,Sun優化了Selector實現,它在底層使用epoll替換了select/poll,上層的API並沒有變化,可以認為是JDK NIO的一次性能優化,但是它仍舊沒有改變I/O的模型。

  由JDK1.7提供的NIO 2.0,新增了非同步的套接字通道,它是真正的非同步I/O,在非同步I/O操作的時候可以傳遞信號變數,當操作完成之後會回調相關的方法,非同步I/O也被稱為AIO。

  NIO類庫支持非阻塞讀和寫操作,相比於之前的同步阻塞讀和寫,它是非同步的,NIO類庫支持非阻塞讀和寫操作,相比於之前的同步阻塞讀和寫,它是一部的,因此很多人習慣稱NIO為非同步非阻塞I/O,包括很多介紹NIO編程的書籍也沿用了這個說法。為了符合大家的習慣,這裡也會將NIO稱為非同步非阻塞I/O或者非阻塞I/O。請大家理解,不要過分糾結在一些技術術語的咬文嚼字上。

多路復用器Selector 

  幾乎所有的中文技術書籍都將Selector翻譯為選擇器,但是實際上我認為這樣的翻譯並不恰當,選擇器僅僅是字面上的意思,體現不出Selector的功能和特點。

  前面介紹過Java NIO的實現關鍵是多路復用I/O技術,多路復用的核心就是通過Selector來輪詢註冊在其上的Channel,當發現某個或者多個Channel處於就緒狀態後,從阻塞狀態返回就緒的Channel的選擇鍵集合,進行I/O操作。由於多路復用器是NIO實現非阻塞I/O的關鍵,它又是主要通過Selector實現的,所以這裡將Selector翻譯為多路復用器,與其他技術書籍所說的選擇器是同一個東西,請大家瞭解。

偽非同步I/O

  偽非同步的概念完全來源於實現。在JDK NIO編程沒有流行之前,為瞭解決Tomcat通信線程同步I/O導致業務線程被掛住的問題,大家想到了一個辦法:在通信線程和業務線程之前做個緩衝區,這個緩衝區用於隔離I/O線程和業務線程間的直接訪問,這樣業務線程就不會被I/O線程阻塞。而對於後端的業務側來說,將消息或者Task放到線程池後就返回了,它不再直接訪問I/O線程或者進行I/O讀寫,這樣就不會被同步阻塞。類似的設計還包括前端啟動一組線程,將接收到的客戶端封裝成Task,放到後端的線程池執行,用於解決一連接一線程問題。像這樣通過線程池做緩衝區的做法,這裡習慣於稱它為偽非同步I/O,而官方並沒有偽非同步I/O這種說法,請大家註意。

1. 不同I/O模型對比

  不同的I/O模型由於線程模型、API等差別很大,所以用法的差異也非常大。

  實際開發中,具體選擇什麼樣的I/O模型或者NIO框架,完全基於業務的實際應用場景和性能訴求,如果客戶端併發連接數不多,周邊對接的網元不多,伺服器的負載也不重,那就完全沒必要選擇NIO做伺服器;如果是相反情況,那就要考慮選擇合適的NIO框架進行開發。

2.選擇Netty的理由

  開發出高質量的NIO程式並不是一件簡單的事情,除去NIO固有的複雜性和BUG不談,作為一個NIO伺服器,需要能夠處理網路的閃斷、客戶端的重覆接入、客戶端的安全認證、消息的編解碼、半包讀寫等情況,如果你沒有足夠的NIO編程經驗積累,一個NIO框架的穩定往往需要半年甚至更長的時間。更為糟糕的是,一旦在生產環境中發生問題,往往會導致跨節點的服務調用中斷,嚴重的可能會導致整個集群環境都不可用,需要重啟伺服器,這種非正常停機會帶來巨大的損失。

  從可維護性角度看,由於NIO採用了非同步非阻塞編程模型,而且是一個I/O線程處理多條鏈路,它的調試和跟蹤非常麻煩,特別是生產環境中的問題,我們無法進行有效的調試和跟蹤,往往只能靠一些日誌來輔助分析,定位難度很大。

2.1不選擇Java原生NIO編程的原因

  現在我們總結一下我們不建議開發者直接使用JDK的NIO類庫進行開發,具體原因如下。

  1. NIO的類庫和API繁雜,使用麻煩,你需要熟練掌握Selector、ServerSocketChannel、SocketChannel、ByteBuffer等。
  2. 需要具備其他的額外技能做鋪墊,例如熟悉Java多線程編程。這是因為NIO編程設計到Reactor模式,你必須對多線程和網路編程非常熟悉,才能編寫出高質量的NIO程式。
  3. 可靠性能力補齊,工作量和難度都非常大。例如客戶端面臨斷連重連、網路閃斷、半包讀寫、失敗緩存、網路擁塞和異常碼流的處理等問題,NIO編程的特點是功能開發相對容易,但是可靠性能力補齊的工作量和難度都非常大。
  4. JDK NIO的BUG,例如臭名昭著的epoll bug,它會導致Selector空輪詢,最終導致CPU100%,官方聲稱在JDK1.6版本的update18修複了該問題,但是直到JDK1.7版本該問題仍舊存在,只不過該BUG發生頻率降低了一些而已,它並沒有被根本解決。

  由於上述原因,在大多數場景下,不建議大家直接使用JDK的NIO類庫,除非你精通NIO編程或者有特殊的需求。在絕大多數的業務場景中,我們可以使用NIO框架Netty來進行NIO編程,它既可以作為客戶端也可以作為服務端,同時支持UDP和非同步文件傳輸,功能非常強大。

2.2為什麼選擇Netty

  Netty是業界最流行的NIO框架之一,它的健壯性、功能、性能、可定製性和可擴展性在同類框架中都是首屈一指的,它已經得到成百上千的商業項目驗證,例如Hadoop的RPC框架avro使用Netty作為底層通信框架;很多其他業界主流的RPC框架,也使用Netty來構建高性能的非同步通信能力。

  Netty的優點總結如下:

  • API使用簡單,開發門檻低;
  • 功能強大,預置了多種編解碼功能,支持多種主流協議;
  • 定製能力強,可以通過ChannelHandler對通信框架進行靈活地擴展;
  • 性能高,通過與其他業界主流的NIO框架對比,Netty的綜合性能最優;
  • 成熟、穩定,Netty修複了已經發現的所有JDK NIO BUG,業務開發人員不需要再為NIO的BUG而煩惱;
  • 社區活躍,版本迭代周期短,發現的BUG可以被及時修複,同時,更多的新功能會加入;
  • 經歷了大規模的商業應用考驗,質量得到驗證。在互聯網、大數據、網路游戲、企業應用、電信軟體等眾多行業得到成功商用,證明瞭它已經完全能夠滿足不同行業的商業應用了。

  正是因為這些優點,Netty逐漸成為Java NIO編程的首選框架。

Netty(一)——Netty入門程式

如果此文對您有幫助,微信打賞我一下吧~


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 問題 由於在初學c#的時候 使用了 線程委托去執行函數,是為了不讓軟體窗體假死。所以使用下方代碼: Thread th = new Thread(Getform); //創建線程 th.Start(); 在使用前需要引入 : using System.Threading; 但是,在Getform 函 ...
  • .NET中的線程池是受CLR管理的,TheadTool類有一個QueueUserWorkItem靜態方法,這個靜態方法接受一個委托,代表用戶自定義的一個非同步操作,在這個方法被調用之後,委托會進入到內部隊列中,如果池中沒有線程,則創建一個工作線程,把第一個委托放入工作線程。如果繼續放入委托,則池創建新... ...
  • fileStream:操作位元組的,也就是所有的文件都可以拿它去操作 / file / path / streamRead / streamWrite(這兩個都是操作字元的,它所操作的都是文本文件) fileStream 與file的區別,fileStream可以操作大文件,因為fileStream是 ...
  • 返回目錄 應該這樣理解它 非同步,早期開發人員對它有很多誤解,認為不阻塞主線程就是非同步,更有認為不阻塞UI就是非同步,但非同步歸根結底和這兩個東西關係並不大,非同步的出現主要是為了提高線程的利用率,讓可用線程更高,而不是一個線程只做一件事,這件事沒有完成就不去做下麵的事情,這是不正確的,線程應該被解放出來! ...
  • 封裝、繼承、多態,面向對象的三大特性,前兩項理解相對容易,但要理解多態,特別是深入的瞭解,對於初學者而言可能就會有一定困難了。我一直認為學習OO的最好方法就是結合實踐,封裝、繼承在實際工作中的應用隨處可見,但多態呢?也許未必,可能不經意間用到也不會把它跟“多態”這個詞對應起來。在此拋磚引玉,大家討論 ...
  • springmvc+hibernate+jdbctemplate+mysql 原文鏈接:http://blog.csdn.net/rugaxm/article/details/8551905 先看下麵小段代碼,一個controller,一個service。 controller.java代碼: .. ...
  • 在APP中內嵌H5頁面,若頁面上存在下載鏈接,沒有任何反應,為什麼呢? 原因是app中內嵌的H5頁面是WebView解析的,什麼是WebView呢? 在Android手機中內置了一款高性能webkit內核瀏覽器,在SDK中封裝為一個叫做WebView組件。 WebView控制調用相應的WEB頁面進行 ...
  • 前言 在使用tomcat時,經常會遇到連接數、線程數之類的配置問題,要真正理解這些概念,必須先瞭解Tomcat的連接器(Connector)。 在前面的文章 詳解Tomcat配置文件server.xml 中寫到過:Connector的主要功能,是接收連接請求,創建Request和Response對象 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...