通俗地講,Netty 能做什麼?
百度了一下好像跟i/o有關係,但是它到底能用來做什麼呢?有什麼例子嗎,哪些企業用到了這個東西?學習難度大嗎?到能在企業服務的程度大概要學多久?
Netty是什麼?
1)本質:JBoss做的一個Jar包
2)目的:快速開發高性能、高可靠性的網路伺服器和客戶端程序
3)優點:提供非同步的、事件驅動的網路應用程序框架和工具
通俗的說:一個好使的處理Socket的東東
如果沒有Netty?
遠古:
java.net + java.io
近代:
java.nio
其他:
Mina,Grizzly
與Mina相比有什麼優勢?
1、都是Trustin Lee的作品,Netty更晚;
2、Mina將內核和一些特性的聯繫過於緊密,使得用戶在不需要這些特性的時候無法脫離,相比下性能會有所下降,Netty解決了這個設計問題;
3、Netty的文檔更清晰,很多Mina的特性在Netty里都有;
4、Netty更新周期更短,新版本的發布比較快;
5、它們的架構差別不大,Mina靠apache生存,而Netty靠jboss,和jboss的結合度非常高,Netty有對google protocal buf的支持,有更完整的ioc容器支持(spring,guice,jbossmc和osgi);
6、Netty比Mina使用起來更簡單,Netty里你可以自定義的處理upstream events 或/和 downstream events,可以使用decoder和encoder來解碼和編碼發送內容;
7、Netty和Mina在處理UDP時有一些不同,Netty將UDP無連接的特性暴露出來;而Mina對UDP進行了高級層次的抽象,可以把UDP當成"面向連接"的協議,而要Netty做到這一點比較困難。
-----------------------------------------------------------------------------------------------------------------------------------------Netty的特性
1)設計
統一的API,適用於不同的協議(阻塞和非阻塞)
基於靈活、可擴展的事件驅動模型
高度可定製的線程模型
可靠的無連接數據Socket支持(UDP)
2)性能
更好的吞吐量,低延遲
更省資源
盡量減少不必要的內存拷貝
3)安全
完整的SSL/TLS和STARTTLS的支持
能在Applet與Android的限制環境運行良好
4)健壯性
不再因過快、過慢或超負載連接導致OutOfMemoryError
不再有在高速網路環境下NIO讀寫頻率不一致的問題
5)易用
完善的JavaDoc,用戶指南和樣例
簡潔簡單
僅信賴於JDK1.5
-------------------------------------------------------------------------------------------------------------------------------------------
Netty 在哪些行業得到了應用?
互聯網行業:隨著網站規模的不斷擴大,系統並發訪問量也越來越高,傳統基於 Tomcat 等 Web 容器的垂直架構已經無法滿足需求,需要拆分應用進行服務化,以提高開發和維護效率。從組網情況看,垂直的架構拆分之後,系統採用分散式部署,各個節點之間需要遠程服務調用,高性能的 RPC 框架必不可少,Netty 作為非同步高性能的通信框架,往往作為基礎通信組件被這些 RPC 框架使用。
典型的應用有:阿里分散式服務框架 Dubbo 的 RPC 框架使用 Dubbo 協議進行節點間通信,Dubbo 協議默認使用 Netty 作為基礎通信組件,用於實現各進程節點之間的內部通信。它的架構圖如下:
其中,服務提供者和服務消費者之間,服務提供者、服務消費者和性能統計節點之間使用 Netty 進行非同步/同步通信。
除了 Dubbo 之外,淘寶的消息中間件 RocketMQ 的消息生產者和消息消費者之間,也採用 Netty 進行高性能、非同步通信。
除了阿里系和淘寶系之外,很多其它的大型互聯網公司或者電商內部也已經大量使用 Netty 構建高性能、分散式的網路伺服器。
遊戲行業:無論是手游服務端、還是大型的網路遊戲,Java 語言得到了越來越廣泛的應用。Netty 作為高性能的基礎通信組件,它本身提供了 TCP/UDP 和 HTTP 協議棧,非常方便定製和開發私有協議棧。賬號登陸伺服器、地圖伺服器之間可以方便的通過 Netty 進行高性能的通信,架構示意圖如下:
圖1-2 Netty 在遊戲伺服器架構中的應用
大數據領域:經典的 Hadoop 的高性能通信和序列化組件 Avro 的 RPC 框架,默認採用 Netty 進行跨節點通信,它的 Netty Service 基於 Netty 框架二次封裝實現。
大數據計算往往採用多個計算節點和一個/N個匯總節點進行分散式部署,各節點之間存在海量的數據交換。由於 Netty 的綜合性能是目前各個成熟 NIO 框架中最高的,因此,往往會被選中用作大數據各節點間的通信。
企業軟體:企業和 IT 集成需要 ESB,Netty 對多協議支持、私有協議定製的簡潔性和高性能是 ESB RPC 框架的首選通信組件。事實上,很多企業匯流排廠商會選擇 Netty 作為基礎通信組件,用於企業的 IT 集成。
通信行業:Netty 的非同步高性能、高可靠性和高成熟度的優點,使它在通信行業得到了大量的應用。
作為一個學Java的,如果沒有研究過Netty,那麼你對Java語言的使用和理解僅僅停留在表面水平,會點SSH,寫幾個MVC,訪問資料庫和緩存,這些只是初等Java程序員乾的事。如果你要進階,想了解Java伺服器的深層高階知識,Netty絕對是一個必須要過的門檻。
有了Netty,你可以實現自己的HTTP伺服器,FTP伺服器,UDP伺服器,RPC伺服器,WebSocket伺服器,Redis的Proxy伺服器,MySQL的Proxy伺服器等等。
如果你想知道Nginx是怎麼寫出來的,如果你想知道Tomcat和Jetty是如何實現的,如果你也想實現一個簡單的Redis伺服器,那都應該好好理解一下Netty,它們高性能的原理都是類似的。
我們回顧一下傳統的HTTP伺服器的原理
- 創建一個ServerSocket,監聽並綁定一個埠
- 一系列客戶端來請求這個埠
- 伺服器使用Accept,獲得一個來自客戶端的Socket連接對象
- 啟動一個新線程處理連接
- 讀Socket,得到位元組流
- 解碼協議,得到Http請求對象
- 處理Http請求,得到一個結果,封裝成一個HttpResponse對象
- 編碼協議,將結果序列化位元組流
- 寫Socket,將位元組流發給客戶端
- 繼續循環步驟3
HTTP伺服器之所以稱為HTTP伺服器,是因為編碼解碼協議是HTTP協議,如果協議是Redis協議,那它就成了Redis伺服器,如果協議是WebSocket,那它就成了WebSocket伺服器,等等。
使用Netty你就可以定製編解碼協議,實現自己的特定協議的伺服器。
上面我們說的是一個傳統的多線程伺服器,這個也是Apache處理請求的模式。在高並發環境下,線程數量可能會創建太多,操作系統的任務調度壓力大,系統負載也會比較高。那怎麼辦呢?
於是NIO誕生了,NIO並不是Java獨有的概念,NIO代表的一個辭彙叫著IO多路復用。它是由操作系統提供的系統調用,早期這個操作系統調用的名字是select,但是性能低下,後來漸漸演化成了Linux下的epoll和Mac里的kqueue。我們一般就說是epoll,因為沒有人拿蘋果電腦作為伺服器使用對外提供服務。而Netty就是基於Java NIO技術封裝的一套框架。為什麼要封裝,因為原生的Java NIO使用起來沒那麼方便,而且還有臭名昭著的bug,Netty把它封裝之後,提供了一個易於操作的使用模式和介面,用戶使用起來也就便捷多了。
那NIO究竟是什麼東西呢?
NIO的全稱是NoneBlocking IO,非阻塞IO,區別與BIO,BIO的全稱是Blocking IO,阻塞IO。那這個阻塞是什麼意思呢?
- Accept是阻塞的,只有新連接來了,Accept才會返回,主線程才能繼
- Read是阻塞的,只有請求消息來了,Read才能返回,子線程才能繼續處理
- Write是阻塞的,只有客戶端把消息收了,Write才能返回,子線程才能繼續讀取下一個請求
所以傳統的多線程伺服器是BlockingIO模式的,從頭到尾所有的線程都是阻塞的。這些線程就乾等在哪裡,佔用了操作系統的調度資源,什麼事也不幹,是浪費。
那麼NIO是怎麼做到非阻塞的呢。它用的是事件機制。它可以用一個線程把Accept,讀寫操作,請求處理的邏輯全乾了。如果什麼事都沒得做,它也不會死循環,它會將線程休眠起來,直到下一個事件來了再繼續幹活,這樣的一個線程稱之為NIO線程。
while true {
events = takeEvents(fds) // 獲取事件,如果沒有事件,線程就休眠
for event in events {
if event.isAcceptable {
doAccept() // 新鏈接來了
} elif event.isReadable {
request = doRead() // 讀消息
if request.isComplete() {
doProcess()
}
} elif event.isWriteable {
doWrite() // 寫消息
}
}
}
NIO的流程大致就是上面的偽代碼描述的過程,跟實際真實的代碼有較多差異,不過對於初學者,這樣理解也是足夠了。
Netty是建立在NIO基礎之上,Netty在NIO之上又提供了更高層次的抽象。
在Netty裡面,Accept連接可以使用單獨的線程池去處理,讀寫操作又是另外的線程池來處理。
Accept連接和讀寫操作也可以使用同一個線程池來進行處理。而請求處理邏輯既可以使用單獨的線程池進行處理,也可以跟放在讀寫線程一塊處理。線程池中的每一個線程都是NIO線程。用戶可以根據實際情況進行組裝,構造出滿足系統需求的並發模型。
Netty提供了內置的常用編解碼器,包括行編解碼器[一行一個請求],前綴長度編解碼器[前N個位元組定義請求的位元組長度],可重放解碼器[記錄半包消息的狀態],HTTP編解碼器,WebSocket消息編解碼器等等
Netty提供了一些列生命周期回調介面,當一個完整的請求到達時,當一個連接關閉時,當一個連接建立時,用戶都會收到回調事件,然後進行邏輯處理。
Netty可以同時管理多個埠,可以使用NIO客戶端模型,這些對於RPC服務是很有必要的。
Netty除了可以處理TCP Socket之外,還可以處理UDP Socket。
在消息讀寫過程中,需要大量使用ByteBuffer,Netty對ByteBuffer在性能和使用的便捷性上都進行了優化和抽象。
總之,Netty是Java程序員進階的必備神奇。如果你知其然,還想知其所以然,一定要好好研究下Netty。如果你覺得Java枯燥無謂,Netty則是重新開啟你對Java興趣大門的鑰匙。
Netty能用來做什麼呢?
Netty是為了簡化高性能網路應用程序的開發。如果你需要開發網路應用,有伺服器,有客戶端,有基於TCP或UDP的網路協議,Netty能提供高性能的網路通訊機制,提供基於事件和流水線的編程模型,提供一些協議的支持,比如HTTP,WebSockets,SSL等。用Netty,你可以容易地利用Java NIO來提高服務端的性能。有什麼Netty的例子嗎?
你下載Netty,裡面有很多例子可以學習。
哪些企業用到了Netty?
Netty本身只是個網路通訊框架,並不是像Oracle,Nginx,Hadoop那樣企業可以直接安裝使用。很多網路應用,RPC,分散式框架都有使用Netty進行網路通訊。Netty學習難度大嗎?
難度大不大都是相對而言,小馬過河的例子大家都知道。Netty本身只是提供一種方便網路編程(特別是NIO)的工具,如果你熟悉TCP/IP,網路編程和NIO,那麼Netty難度並不大,一個helloworld半天就能上手,也許一周就可以使用了。
如果你不熟悉TCP/IP,網路編程和NIO,那麼就先熟悉這些技術。相對於Tomcat這種Web Server(顧名思義主要是提供Web協議相關的服務的),Netty是一個Network Server,是處於Web Server更下層的網路框架,也就是說你可以使用Netty模仿Tomcat做一個提供HTTP服務的Web容器。
簡而言之,Netty通過使用NIO的很多新特性,對TCP/UDP編程進行了簡化和封裝,提供了更容易使用的網路編程介面,讓你可以根據自己的需要封裝獨特的HTTP Server活著FTP Server等.謝邀.netty是一套在java NIO的基礎上封裝的便於用戶開發網路應用程序的api. 應用場景很多,諸如阿里的消息隊列(RocketMQ),分散式rpc(Dubbo)通信層都使用到了netty(dubbo可以用服務發現自由選擇通信層). 主要優點個人總結如下:
1. netty是非阻塞事件驅動框架, 並結合線程組(group)的概念,可以很好的支持高並發,慢連接的場景。
2. 編程介面非常容易,並且也較好的解決了TCP粘包/拆包的問題.netty提供了自己的ByteBuf和channel,相比於jdk的ByteBuffer和channel來說更簡便靈活操作, 並提供了pipeline的概念,並針對每個contextHandler都可以由用戶定義, 方便直接.
3. 有一些web框架已經開始直接使用netty做為底層通信服務,諸如play. 這樣play就不用依賴於容器去進行部署,在沒有nginx做反向代理的情況下也能支持高並發.編解碼器可以隨意擴展,今天是個web,明天就可以是一個ftp或email伺服器,個人覺得比較靈活。netty是優秀的JAVA網路應用程序框架,關鍵詞是NIO和非同步。它提供了對JAVA網路編程API的封裝,屏蔽了繁雜的編程細節,讓開發者可以更加專註於業務邏輯的實現。很多中間件都是基於netty來實現的,你可以用來實現一個web容器,也能寫一個遊戲伺服器。學習netty能夠讓你更加熟悉網路編程,對個人好處還是比較大的。至於學習時間,看個人而言,有JAVA NIO編程經驗和網路編程經驗上手會更加快。
簡單來說,netty做了jdk應該做的事兒。
jdk強迫你必須用socket來寫伺服器,實際上是很繁瑣的。缺乏一個高層次的api。netty說,我來寫jdk的socket,並給你一個新的更簡潔的api,你傻瓜式的就能寫好一個網路伺服器(而且是event-driven/proactor/reactor等等)。當然,netty通過jni,引入了epoll這樣的linux系統調用,使得它不單單是jdk的一個簡單包裹,的確也加了些東西進去。
p.s. event-driven/proactor/reactor這些概念請看這裡:I/O多路復用技術(multiplexing)是什麼? - 趙老師的回答普通的伺服器10000個連接需要10000個線程,伺服器可能就直接卡住了,但對於netty伺服器可能幾個線程就夠了
非常喜歡的框架,如果比較一下 c++的一些網路框架,更加會覺得在簡單易用上 Netty 設計的多麼好。符合直覺的 apI 設計,同時不失靈活和功能強大。在性能上由於在設計和細節上優化掉了非常多的不必要開銷,不輸甚至過若干c++框架。如果想用 java 高性能處理網路 io ,目前Netty 絕對是首遠。
線程io模型框架。用來提升線程和io的資源利用率。
netty核心概念是channel和eventloop前者抽象了io模型如tcp http 等,後者抽象了線程資源。
這兩者速率是不一樣的,在一起仺做任務(hanhler)的時候一定有一方會浪費。於是採用非同步事件通知的方式 來提高利用綠。
至於nio 非阻塞 網路框架什麼的,那只是這個核心概念的實現方式之一,用neety完全可以做老io和阻塞實現,以機非網路的本地資源調肚實現 看你昨擴展
學習難肚很小。完全叄透源碼有難肚netty 是對 socket 網路編程的優秀包裝
原來用手動工具做木工,現在全套電動工具,省力省時還精準,價格便宜量又足,
用了netty後,腰不酸了,脖子也不疼了,想啥啥來,吃嘛嘛香:-)
netty 滿足了過去用 socket 進行網路編程時的幾乎所有美好願景:
易用,健壯,高性能,安全
感謝 netty 的貢獻者們,感謝開源世界
當然,前提是至少得了解 socket 網路編程原理,及其面臨的問題,才更容易理解netty為什麼讓網路編程美好許多
系統需要實現多進程通信,只有兩種方式:內存共享、消息傳遞;分散式的系統間通信只有消息傳遞,Netty可作為應用間消息傳遞實現的基礎組件,Netty位於OSI協議棧的會話層、表示層、應用層都有涉及,這樣你可以方便的擴展實現,處理會話層以上的協議和業務;
Netty封裝了java nio的api,使之成為一個非常方便是用框架;提供了提供處理IO的線程池,最重要的一點保證了一個socket處理在一個線程中完成,一個線程可以同時處理多個socket,這個比較好玩;
當然是Java高性能網路編程了,可以做很多東西,剩下的就是您的想像力了
比如Spring5 、Spark、Cassandra,還有阿里的HSF這些都是基於Netty的。
您可以購買我翻譯的《Netty實戰》這本書。
如何評價《Netty實戰》這本書? - 知乎京東預售鏈接(優先發貨):《Netty實戰》([美]諾曼·毛瑞爾(Norman Maurer),馬文·艾倫·沃爾夫泰爾(Marvin Allen Wolfthal))
netty等視頻www.it448.com教程
- 無論是BIO還是NIO,無論是Tomcat還是Netty,支持的連接數是有限的,意味著工作線程也是有限的。因此每個工作線程的效率,就很關鍵。如何提高工作效率?
- 傳統Blocking IO,每請求每線程。IO線程作為生產者,串列接受請求,不斷向隊列中發送消息(任務),線程池作為消費者,從隊列中接收消息(任務),分配給工作線程處理(執行)。而每個請求都離不開IO的讀寫阻塞,這也直接導致工作線程跟著阻塞。
- 新Netty採用的New IO,同樣是每請求每線程。同樣也是IO線程作為生產者,線程池作為消費者。唯一的區別是,相對BIO,每線程的服務時間縮短了。因為在隊列和消費者中間,插入一個輪詢線程Selector,它會不斷去詢問每個請求,是否讀寫操作準備就緒,只有操作就緒,才開啟工作線程,從而減少了單個線程的無謂等待時間,提高工作線程的整體執行效率。
比如你想寫個tomcat一樣的Server,可以用netty。
你想寫一個即時通訊的應用,可以用netty。
你想實現一個高性能Rpc框架,可以用netty。
只要是和網路有關,基本都可以用netty。眾多的java一個工具包之一。懂了io模型,沒啥難的。
netty可以讓你方便的,高效的,靈活的,處理原始的socket,實現自己的協議;一些難以自己實現的部分,比如tls等,可以直接套用別人的encoder/decoder。
以前頁游伺服器用mina,現在手游伺服器用netty
netty是tcp/udp層的NIO框架。
你可以用netty在單台伺服器上實現K級別的並發連接,而同樣的事情用傳統的Thread/Select來做就等著機器崩潰吧。
netty的作用是將並發應用中開銷最大的I/O給幹掉了(實現的原理是用boss-worker的模式,自己看源碼),但是業務邏輯代碼的計算量並沒有,所以原則上你還需要再連接若干個線程池來負責後面的功能實現。
學習netty兩本書建議深入去看,java並發編程實踐和netty實戰。非同步只是並發的一個很薄的環節,更多關於數據一致性和鎖的概念需要深入理解。實際用起來至少得有一個場景,然後實際的模擬一下業務流程,要有資料庫的參與,這樣你才能看到NIO在整個系統當中起到的和沒有起到的作用。
簡單概括可認為它是NIO框架,封裝眾多協議如tcp/udp。最知名的阿里開源的SOA治理框架dubbo中就是使用Netty。Netty是Mnia作者後又另起新作。學習時,核心要掌握它的線程模型。我使用Netty3.6搭建了公司移動推送伺服器使用Netty搭建APP推送伺服器 - 博客頻道 - CSDN.NET 推薦閱讀《Netty權威指南》
通信,我本身也想好好學習一下,現在項目正好需要,看了你的文章講述的很詳細,之前沒有接觸過NIO IO開發,一下看完還需要消化一下。總之謝謝啦,但是文章里的一些圖片完全看不見不知道怎麼回事。
netty連個官方混淆指導都沒有,網上也i查不到相關的資料。
推薦閱讀:
※Netty的Reactor線程組中的每個Reactor線程處理網路I/O為什麼一定要串列化,並行化不是更能提高系統吞吐量嗎?
※為什麼nio效率會比bio高?