JAVA的 IO NIO AIO筆記

    IO
     linux內核將全部外部設備都看作一個文件來操做,對一個文件的讀寫會調用內核系統命令,放回一個file descriptor(文件描述符),
對一個socket的讀寫也會有相應的描述符,稱爲socketfd
     Java NIO的核心類庫多路複用器Selector就是基於epoll的多路複用技術實現
     I/O多路複用技術經過把多個I/O的阻塞複用到同一個select的阻塞上,從而使得系統在單線程的狀況下能夠同時處理多個客戶端請求
    
     epoll和select的原理比較相似,並作了不少重大改進
     1  支持一個進程打開的socket描述符(FD)不受限制(僅受限於操做系統的最大文件句柄數),1GB內存的機器上大約是10萬個句柄左右,
       具體值能夠經過cat /proc/sys/fs/file- max查看
     2  I/O效率不會隨着FD數目的增長而線性降低,socket集合的維護成本上,epoll只會對活躍的socket進行操做,由於在內核實現中,
      epoll是根據每一個fd上面的callback函數實現額,只有活躍的socket纔會去主動調用callback函數
     3 使用mmap加速內核與用戶空間的消息傳遞,epoll是經過內核和用戶空間mmap同一塊內存來實現的
 
     JDK1.7升級了原來的NIO類
     1 提供可以批量獲取文件屬性的API,這些API具備平臺無關性,另外還提供了標準文件系統的SPI,供各個服務提供商擴展的實現
     2 提供AIO功能,支持基於文件的異步I/O操做和針對網絡套接字的異步操做
     3  完成了定義的通道功能,包括對配置和多播數據報的支持
     
     同步阻塞I/O,阻塞的時間取決於對方I/O線程的處理速度和網絡I/O的傳輸速度
     僞異步I/O
     採用線程池和任務隊列能夠實現一種叫作僞異步的I/O通訊框架
     缺陷,當對Socket的輸入流進行讀取操做的時候,它會一直阻塞下去,直到發生以下三件事:1有數據可讀2可用數據已經讀取完畢3發生空指針或者I/O異常
     僞異步I/O實際上僅僅是對以前I/O線程模型的一個簡單優化,沒法從根本上解決同步I/O致使的通訊阻塞問題
 
     
     NIO(Non-block I/O)
     與Socket類和ServerSocket類相對應,NIO也提供了SocketChannel和ServerSocketChannel兩種不一樣的套接字通道實現,這兩種新增的通道同時支持阻塞和非阻塞兩種模式
     NIO彌補了原來同步阻塞I/O的不足,在標準Java代碼中提供了高速的、面向塊的I/O
     在NIO類庫中加入了Buffer(緩衝區)對象,體現了新庫與原I/O的一個重要區別,緩衝區不只僅是一個數組,還提供了對數據的結構化訪問以及維護讀寫位置等信息
     每一種Java基本類型(除了Boolean類型)都對應有一種緩衝區,大多數標準I/O操做都使用ByteBuffer
 
     Channel是一個通道,通道與流的不一樣之處在於通道時雙向的,流只是在一個方向上移動,而通道能夠用於讀、寫或者兩者同時進行,Channel是全雙工的,
UNIX底層操做系統通道都是全雙工的,因此它能夠更好的映射底層操做系統API
     Channel分爲兩大類:用於網絡讀寫的SelectableChannel和用於文件操做的FileChannel
 
     多路複用器Selector
     多路複用器提供選擇已經就緒的任務的能力,Selector會不斷地輪詢註冊在其上的Channel,若是某個Channel上面發生讀或者寫事件,這個Channel就處於就緒狀態,會被Selector輪詢出來,
而後經過SelectionKey能夠獲取就緒Channel的集合,進行後續的I/O操做,因爲JDK使用了epoll代替了傳統的select實現,因此它並無最大鏈接句柄1024/2048的限制
 
     AIO
     NIO 2.0引入了新的異步通道的概念,並提供了異步文件通道和異步套接字通道的實現,異步通道提供如下兩種方式獲取操做結果
     1 經過java.util.concurrent.Future類來表示異步操做的結果
     2 在執行異步操做的時候傳入一個java.nio.channels
它不須要經過多路複用器對註冊的通道進行輪詢操做便可以實現異步讀寫
 
Netty
TCP粘包拆包
使用LineBasedFrameDecoder和StringDecoder能夠解決TCP粘包致使的讀半包問題,這二者的組合就是按行切換的文本解碼器
DelimiterBasedFrameDecoder自動完成以分隔符作結束標誌的消息的解碼
FixedLengthFrameDecoder能夠自動完成對定長消息的解碼
 
編解碼技術
基於JDK默認的序列化機制可讓程序員避免操做底層的字節數組,序列化的目的主要是網絡傳輸和對象持久化
     當進行跨進程服務調用時,須要把被傳輸的Java對象編碼爲字節數組或者ByteBuffer對象,而當遠程服務讀取到ByteBuffer對象或字節數組時,須要將其    解碼爲發送時的Java對象,這被稱爲Java對象編解碼技術,Java序列化僅僅是Java編解碼技術的一種
     採用JDK序列化機制編碼後的二進制數組大小是二進制編碼的5倍多
     編解碼框架的優點每每從如下幾個方面考量:是否支持跨語言,編碼後的碼流大小,編解碼的性能,類庫是否小巧方便使用
 
協議棧開發就是基於現有的基礎協議(eg http協議)進行的封裝擴展
WebSocket協議開發
HTTP協議的弊端  半雙工協議,在客戶端和服務端兩個方向上傳輸,可是不能同時傳輸;消息採用文本傳輸,冗長繁瑣;長時間輪詢
比較新的一種輪詢技術是Comet,使用AJAX,這種技術雖然能夠達到雙向通訊,但依然須要發出請求,並且廣泛使用了長鏈接,會大笑消耗帶寬和資源
 
HTML5定義了WebSocket協議,能更好的節省服務器資源和帶寬並達到實時通訊
相關文章
相關標籤/搜索