匠心零度 轉載請注明原創出處,謝謝!
疑惑
我們都知道bio nio 以及nio2(也就是aio),如果不是特別熟悉可以看看我之前寫的網絡 I/O模型,那么netty為什么還經常看到類似下面的這段代碼呢?
EventLoopGroup ……= new NioEventLoopGroup();
……
……
b.group(……).channel(NioSocketChannel.class)……
……
……
ChannelFuture f = b.bind(PORT).sync();
不選擇bio模型我們知道,那么為什么不選擇aio模式呢?而還是選擇nio模式呢?這是一個值得思考的問題,我就一直很好奇,因為在網絡 I/O模型里面介紹的,明顯AIO要比NIO模型還要好。
那么為什么Netty還是選擇的NIO模型呢?
Netty一些組件簡單介紹
Netty中這樣定義EventLoop的,本篇重點不在這里,后續繼續介紹EventLoop。
Will handle all the I/O operations for a [
Channel
] once registered. One [EventLoop
] instance will usually handle more than one [Channel
] but this may depend on implementation details and internals.
Netty中這樣定義EventLoopGroup的,本篇重點不在這里,后續繼續介紹EventLoopGroup。
Special [
EventExecutorGroup
] which allows registering [Channel
]s that get processed for later selection during the event loop.
Netty中這樣定義Channel的,本篇重點不在這里,后續繼續介紹Channel。
A nexus to a network socket or a component which is capable of I/O operations such as read, write, connect, and bind.
A channel provides a user:
- the current state of the channel (e.g. is it open? is it connected?),
- the [configuration parameters] of the channel (e.g. receive buffer size),
- the I/O operations that the channel supports (e.g. read, write, connect, and bind), and
- the [
ChannelPipeline
] which handles all I/O events and requests associated with the channel.
Netty中這樣定義ChannelFuture的,本篇重點不在這里,后續繼續介紹ChannelFuture。
The result of an asynchronous [
Channel
] I/O operation.All I/O operations in Netty are asynchronous. It means any I/O calls will return immediately with no guarantee that the requested I/O operation has been completed at the end of the call. Instead, you will be returned with a [
ChannelFuture
] instance which gives you the information about the result or status of the I/O operation.A [
ChannelFuture
] is either uncompleted or completed. When an I/O operation begins, a new future object is created. The new future is uncompleted initially - it is neither succeeded, failed, nor cancelled because the I/O operation is not finished yet. If the I/O operation is finished either successfully, with failure, or by cancellation, the future is marked as completed with more specific information, such as the cause of the failure. Please note that even failure and cancellation belong to the completed state.
Netty提供的網絡傳輸實現
備注: 這個是參考netty實戰書籍的。
看看RocketMQ里面的寫法,等netty系列完成了,后續RocketMQ會繼續分析的。
備注:
If you are running on linux you can use EpollEventLoopGroup and so get better performance, less GC and have more advanced features that are only available on linux.
epoll對文件描述符有兩種操作模式--LT(level trigger水平模式)和ET(edge trigger邊緣模式)
簡單來講,LT是epoll的默認操作模式,當epoll_wait函數檢測到有事件發生並將通知應用程序,而應用程序不一定必須立即進行處理,這樣epoll_wait函數再次檢測到此事件的時候還會通知應用程序,直到事件被處理。
而ET模式,只要epoll_wait函數檢測到事件發生,通知應用程序立即進行處理,后續的epoll_wait函數將不再檢測此事件。因此ET模式在很大程度上降低了同一個事件被epoll觸發的次數,因此效率比LT模式高。
解釋為什么epoll默認是LT的原因(超哥解釋,個人覺得還是非常不錯的)
LT(level triggered):LT是缺省的工作方式,並且同時支持block和no-block socket。在這種做法中,內核告訴你一個文件描述符是否就緒了,然后你可以對這個就緒的fd進行IO操作。如果你不作任何操作,內核還是會繼續通知你的,所以,這種模式編程出錯誤可能性要小一點。傳統的select/poll都是這種模型的代表。
Netty為啥去掉支持AIO?
根據這個疑問搜索了下,查看到github上面的說明:https://github.com/netty/netty/issues/2515。
備注:總的來說可能支持AIO Not faster than NIO (epoll) on unix systems (which is true) 而且性價比不高,可能覺得不值得,反正netty已經封裝好,用戶調用起來也很簡單和底層用nio或者aio其實用戶不需要關心的,只要快就行。
由於自己水平問題,可能很多理解不到位,歡迎大家積極在留言區進行留言討論,感謝。在后面合適的機會我們繼續討論,AIO Not faster than NIO (epoll) on unix systems (which is true) 這是為什么呢? 目前我還是先學習netty主干,后續會繼續回到這個話題上面。
如果讀完覺得有收獲的話,歡迎點贊、關注、加公眾號【匠心零度】,查閱更多精彩歷史!!!