Vert.x與Netty的區別

雖然Vert.x是基於Netty的更高級封裝,但它們解決的問題是不太一樣的。可以認爲Vert.x是Netty的超集,它利用Netty的Eventloop爲開發者提供了更友好的編程模型。

Netty解決了如何支撐大量連接的問題

Netty作爲一個網絡I/O工具,使用起來隨時都能清晰的感受到你在操作網絡,在操作字節等這些與業務不太相關的東西。很明顯,Netty解決的同高吞吐的網絡I/O問題,而不是編程問題。我們在使用Netty時,通常都會編寫一些ChannelHandler, 先對請求進行解碼,封裝成任務再投遞到我們自己的業務線程池中跑業務,然後再編碼響應,調用writeAndFlush()發送響應對客戶端。然而,我們的業務線程池中會跑的任務,往往還是那些會阻塞線程的數據庫查詢、網絡I/O等操作,在執行這些操作時,當前的業務線程一直在等I/O完成也會浪費業務線程池的資源。在這種情況下,使用Netty其實只解決了如何用少量線程支撐起大量連接的問題,你連接是建立起來了,但是你的業務處理邏輯並沒有因此而變的更快(吞吐量更高)

我們可以再思考一下,平時用的Tomcat這種Servlet容器,其網絡I/O也是NIO實現的,那跟Netty其實差不了太多。在你使用同步Servlet的情況下,區別也就在於Servlet有一些規範導致它會笨重一些,然後在調用XXXXStream返回響應時需要block當前線程,而Netty則會先判斷當前是否處在指定NIO線程中,如果不是則封裝成事件投遞到任務隊列中等待執行,這樣就不會block當前業務線程了。

Vert.x進一步解決了業務編程/工程實現問題

Vert.x在Netty的基礎上,提供了對一個工程上對程序員更加友好的封裝。

Vert.x鼓勵你將JDBC調用、Redis查詢、文件I/O等所有可能會導致線程阻塞的操作全都異步化以進一步壓榨CPU利用率。爲了實現這一點,Vert.x官方就提供了很多常見服務的異步化實現,如jdbc-client, redis-client, mongodb-client, web-client等,用起來就跟node.js一樣,都是在發起操作時註冊一個回調,當處理完成後回調方法就會得到執行。

與此同時,Vert.x還提供了很多好用的異步協調工具,如CompositeFeature,允許你將多個異步調用組合起來,當滿足一定條件時再觸發另一個回調,這正是當你嘗試用Netty將業務邏輯異步化時Netty所欠缺的組件。

不僅如此,在工程上面Vert.x還提供了"一站式"的工程解決方案, 如Event Bus, 允許你將Verticle部署到多臺服務器上(集羣),每個實例通過Event Bus通信,甚至還有針對時下流行的微服務架構而準備的註冊中心Vert.x Service Discovery, 斷路器Vert.x Circuit Breaker等。

在這角度上看,Vert.x是Netty的超集,更加註重解決工程問題,而不僅僅是單純的網絡I/O問題。筆者就曾在業務上遇到過一個需要大量調用HTTP接口的場景。如果使用傳統的線程池,則不太可能單實例下支撐起每秒萬級的併發數,如果使用Netty,則需要編寫大量跟I/O更加接近的"底層"代碼,比較繁瑣。最後使用Vert.x解決了問題,代碼非常簡潔,而且性能一樣很猛。

那麼Vert.x有沒有什麼劣勢?到現在爲止,筆者只感受到了一個劣勢,就是Vert.x對二進制協議的解析不夠友好。因爲封裝程度較高,導致對二進制協議的解析不夠靈活,有時候甚至要使用取巧的方法來實現。因此,如果你是在做以二進制協議爲基礎的服務端就用,還是不推薦Vert.x,老老實實用Netty吧。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章