netty 學習 基於 netty in action 5th, 官網資料,網絡博客等html
netty 是一箇中間層的抽象java
"all problems in computer science can be solved by another
level of indirection"
netty 是一箇中間層的抽象,由於底層的網絡編程的各類問題編程
Netty is a NIO client server framework which enables quick and easy development of network applications such as protocol servers and clients.segmentfault
"Quick And Easy"是如何保證的
Netty 的實現者汲取了 它人實現 FTP, SMTP, HTTP, WebSocket, SPDY and various binary and text-based legacy protocols 中遇到的問題,take great care in its design。並無在可擴展,靈活性,穩定性上作出妥協。api
2011年Netty 之父離開redhat加入Twitter, 因此redhat、twitter是netty的兩個主要貢獻公司,
netty的許多特性也是衆多大公司項目需求致使的。數組
參考:https://segmentfault.com/a/11...
java io 會涉及到copy,
好比,一個請求有兩個bytebuffer, 分別是請求頭,和請求正文,那麼,咱們接收請求後的處理是,定義一個大的bytebuffer將這兩個bytebuffer的內容copy到大數組中。
netty能夠用CompositeByteBuf,利用一個抽象的邏輯Buffer來避免這個事情。網絡
好比,java 的文件讀寫,咱們通常會定義一個小數組,在輸入流和輸出流之間讀寫,這樣就涉及了一次copy.
netty 的FileRegion 利用Java NIO FileChannel.transfer能夠避免這個問題。
還有其它的狀況。app
傳統的 Java I/O API 在應對不一樣的傳輸協議時須要使用不一樣的類型和方法。好比異步
bio、nio、aio api 也是不一樣的socket
參考:https://www.cnblogs.com/cz123...
FutureTask:
構造函數接收一個Callable對象,這個對象只有一個call 方法,有返回值,會拋出異常。
FutureTask繼承Runnable,說明能夠做爲一個參數傳到Thread中,其中的run方法,調用的是Callable中的call方法。
FutureTask繼承Future,Future中有isDone,cancel,is...方法能夠控制Callable的call方法返回情況。
參考:java-netty-study-1-bio和nio(https://segmentfault.com/a/11...)
jdk1.4的nio,和jdk1.7的nio2的api不一樣,可是底層的一些特性是相同的,好比都是用bytebuffer作爲數據的容器。
ByteBuffer:
BYTEBUFFER
A ByteBuffer is fundamental to both NIO APIs and, indeed, to Netty. A ByteBuffer can
either be allocated on the heap or directly, which means its stored outside of the HeapSpace. Usually, using a direct buffer is faster when passing it to the channel, but the
allocation/deallocation costs are higher. In both cases, the API for a ByteBuffer is the same,
which provides a unified way of accessing and manipulating data. A ByteBuffer allows the
same data to be easily shared between ByteBuffer instances without the need to do any
memory copying.
bytebuffer,要注意,一個是堆外內存,適用於頻繁使用的臨時區域
(通常java讀取數據,都是後現將數據從堆內copy一份到堆外,而後再操做)
selector
簡單說,就是Selector會不斷的輪詢註冊在其上的通道(Channel),若是某個通道發生了讀寫操做,這個通道就處於就緒狀態,會被Selector輪詢出來,而後經過SelectionKey能夠取得就緒的Channel集合,從而進行後續的IO操做。一個多路複用器(Selector)能夠負責成千上萬的通道(Channel),沒有上限。這也是JDK使用了epoll代替傳統的select實現,得到鏈接句柄(客戶端)沒有限制。那也就意味着咱們只要一個線程負責Selector的輪詢,就能夠接入成千上萬個客戶端,這是JDK NIO庫的巨大進步
Nio Vs Aio
nio和aio 區別:在NIO的基礎上引入了異步通道的概念,並提供了異步文件和異步套接字通道的實現,從而在真正意義上實現了異步非阻塞,以前的NIO只是非阻塞而並不是異步。AIO不須要經過對多路複用器對註冊的通道進行輪詢操做便可實現異步讀寫,從而簡化NIO編程模型。
一、nio 是圍繞selector,selector上註冊的serversocketchannel,socketchannel,及肯定的註冊事件。
二、aio 簡化了nio操做,當一個event(Accept,Connect,read,write)發生時,CompletionHandler會處理,使得用戶專一於業務邏輯。
1、Nio 依賴底層的操做系統,有跨平臺問題。
When using NIO you often find that your code works fine on Linux, for example, but has problems on Windows.
同時,jdk1.4支持nio, 1.7 支持nio2. 若是是jdk1.6 怎麼辦
最後,到目前位置,nio.2 支持tcp, 不支持udp.
2、沒法擴展
做爲nio的核心,bytebuffer 沒法擴展,私有構造函數。netty 實現了本身的bytebuffer.
3、NIO對緩衝區的聚合和分散操做可能會操做內存泄露
4、 epoll bug