怎樣用Java去編寫基於netty的RPC框架呢?

2021-01-08 Java高階

開頭我們先來說下RPC是什麼吧,RPC(Remote Procedure Call Protocol)--遠程過程調用協議,它是一種通過網絡從遠程電腦程式上請求服務,而不需要了解底層網絡技術的協議。RPC協議假定某些傳輸協議的存在,如TCP或UDP,為通信程序之間攜帶信息數據。在OSI網絡通信模型中,RPC跨越了傳輸層和應用層。有多種 RPC模式和執行。最初由 Sun 公司提出。IETF ONC 憲章重新修訂了 Sun 版本,使得 ONC RPC 協議成為 IETF 標準協議。現在使用最普遍的模式和執行是開放式軟體基礎的分布式計算環境(DCE)。

阻塞IO:當阻塞I/O在調用InputStream.read()方法是阻塞的,一直等到數據到來時才返回,同樣ServerSocket.accept()方法時,也是阻塞,直到有客戶端連接才返回,I/O通信模式如下:

缺點:當客戶端多時,會創建大量的處理線程,並且為每一個線程分配一定的資源;阻塞可能帶來頻繁切換上下文,這時引入NIO

NIO: jdk1.4引入的(NEW Input/Output),是基於通過和緩存區的I/O方式,(插入一段題外話,學的多忘得也多,之前有認真研究過NIO,後來用到的時候,忘得一乾二淨,所以學習一些東西,經常返回看看),NIO是一種非阻塞的IO模型,通過不斷輪詢IO事件是否就緒,非阻塞是指線程在等待IO的時候,可以做其他的任務,同步的核心是Selector,Selector代替線程本省的輪詢IO事件,避免了阻塞同時減少了不必要的線程消耗;非阻塞的核心是通道和緩存區,當IO事件的就緒時,可以將緩存區的數據寫入通道

其工作原理:

1事件驅動機制:事件到的時候才觸發,而不是同步監視

2線程通訊:線程之間通訊通過wait,notify等方式通訊,保證每次上下文切換都是有意義的,減少沒必要的線程切換

3由專門的線程來處理所有的IO事件,並且負責轉發

通道:是對原I/O包中流的模擬,所有數據必須通過Channel對象,常見的通道FileChannel,SocketChannel,ServerSocketChannel,DatagramChannel

Buffer緩存區:實際上是一個容器,一個連續的數組,任何讀寫的數據都經過Buffer

Netty:是由JBOSS提供的一個java開源框架,是一個高性能,異步事件驅動的NIO框架,基於JAVA NIO提供的API實現,他提供了TCP UDP和文件傳輸的支持,,所有操作都是異步非阻塞的.通過Futrue-Listener機制,本質就是Reactor模式的現實,Selector作為多路復用器,EventLoop作為轉發器,而且,netty對NIO中buffer做優化,大大提高了性能

Netty中Bootstrap和Channel的生命周期

Bootstarp:引導程序,將ChannelPipeline,ChannelHandler,EventLoop進行整體關聯

Bootstrap具體分為兩個實現

Bootstrap:用於客戶端,只需要一個單獨的Channel,配置整個Netty程序,串聯起各個組件

ServerBootstrap:用於服務端,使用一個ServerChannel接收客戶端的連接,並創建對應的子Channel

二者的主要區別:

客戶端的Bootstrap一般用一個EventLoopGroup,而伺服器的ServerBootstrap會用兩個第一個EventLoopGroup專門負責綁定到埠監聽連接事件,而第二個EventLoopGroup專門用來處處理每個接收的連接,這樣大大提高了並發量

ServerBootstrap用於Server端,通過調用bind()綁定一個埠監聽連接,Bootstrap用於Client端,需要調用connect()方法來連接伺服器端,我們也可以調用bind()方法接收返回ChannelFuture中Channel

其他組件:

Handle:為了支持各種協議和處理數據的方式,可以是連接,數據接收,異常,數據格式轉換等

ChannelInboundHandler:最常用的Handler,作用是處理接收數據的事件,來處理我們的核心業務邏輯。

ChannelInitializer:,當一個連結建立時,我們需要知道怎麼來接收或者發送數據,當然,我們有各種各樣的Handler實現來處理它,那麼ChannelInitializer便是用來配置這些Handler,它會提供一個ChannelPipeline,並把Handler加入到ChannelPipeline。

ChannelPipeline:一個Netty應用基於ChannelPipeline機制,這種機制依賴EventLoop和EventLoopGroup,這三個都和事件或者事件處理相關

EventLoopGroup:包含多個EventLoop

Channel:代表一個Socket連接

EventLoop: 為Channel處理IO操作,一個EventLoop可以為多個Channel服務

Future:在Netty中所有的IO操作都是異步的,,因此我們不知道,過來的請求是否被處理了,所以我們註冊一個監聽,當操作執行成功或者失敗時監聽自動觸發,所有操作都會返回一個ChannelFutrue

ChannelFuture:Netty是一個非阻塞的,事件驅動的,網絡編程框架,我們通過一張圖理解一下,Channel,EventLoop以及EventLoopGroup之間的關係

解釋一下,當一個連接過來,Netty首先會註冊一個channel,然後EventLoopGroup會分配一個EventLoop綁定到這個channel,在這個channel的整個生命周期過程中,這個EventLoop一直為他服務,這個玩意就是一個線程

Netty如何處理數據?

handler數據處理核心,,而ChannelPipeline負責安排Handler的順序和執行,我們可以這樣理解,數據在ChannelPipeline中流動,其中ChannelHandler就是一個個閥門,這些數據都會經過每一個ChannelHandler並且被他處理,其中ChannelHandler的兩個子類ChannelOutboundHandler和ChannelInboundHandler,根據不同的流向,選擇不同的Handler

由圖可以看出,一個數據流進入ChannelPipeline時,一個一個handler挨著執行,各個handler的數據傳遞,這需要調用方法中ChannelHandlerContext來操作,而這個ChannelHandlerContext可以用來讀寫Netty中的數據流

Netty中的業務處理

netty中會有很多Handler.具體哪一種Handler還要看繼承是InboundAdapter還是OutboundAdapter,Netty中提供一系列的Adapter來幫助我們簡化開發,在ChannelPipeline中的每一個handler都負責把Event傳遞個洗下一個handler,有這些adapter,這些工作可以自動完成,,我們只需覆蓋我們真正實現的部分即可,接下來比較常用的三種ChannelHandler

Encoders和Decodeers:我們在網絡傳輸只能傳輸字節流,在發送數據時,把我們的message轉換成bytes這個過程叫Encode(編碼),相反,接收數據,需要把byte轉換成message,這個過程叫Decode(解碼)

Domain Logic:我們真正關心的如何處理解碼以後的數據,我們真正的業務邏輯便是接收處理的數據,Netty提供一個常用的基類就是SimpleChannelInboundHandlerT,其中T就是Handler處理的數據類型,消息到達這個Handler,會自動調用這個Handler中的channelRead0方法,T就是傳過來的數據對象

大家可以jia摳qun捌陸零170肆一陸獲取學習視頻資料

看了本文想必大家對用Java去編寫基於netty的RPC框架有一個了解與掌握了吧,如果還是不怎麼了解的我那邊還有專門的視頻資料mianfei給你們學習。

相關焦點

  • 基於Netty的高性能RPC框架Nifty 服務端啟動全解析
    前言Thrift是Facebook貢獻給apache的rpc框架,但是這款框架的java版本在公司內部並不是那麼受待見,因為其性能相比C++版本差了很多,但是後續基於netty重寫了以後性能得到了極大的提升,相比於C++版本已經差距不大了。
  • Netty實現高性能RPC伺服器優化篇之消息序列化
    在文章的最後提及到,其實基於該方案設計的RPC伺服器的處理性能,還有優化的餘地。於是利用周末的時間,在原來NettyRPC框架的基礎上,加以優化重構,本次主要優化改造點如下:1、NettyRPC中對RPC消息進行編碼、解碼採用的是Netty自帶的ObjectEncoder、ObjectDecoder(對象編碼、解碼器),該編碼、解碼器基於的是java的原生序列化機制,從已有的文章以及測試數據來看
  • 手寫一個基於Netty+Kyro+Zookeeper的RPC框架,項目經驗妥妥拿下
    介紹這是一款基於 Netty+Kyro+Zookeeper 實現的 RPC 框架。推薦基於 NIO 的 Netty 框架。序列化 :既然涉及到網絡傳輸就一定涉及到序列化,你不可能直接使用 JDK 自帶的序列化吧!JDK 自帶的序列化效率低並且有安全漏洞。所以,你還要考慮使用哪種序列化協議,比較常用的有 hession2、kyro、protostuff。
  • grpc-example 基於gRPC實現的簡單rpc框架
    grpc-example 基於gRPC實現的簡單rpc框架基於gRPC實現的簡單rpc框架,本身gRpc已經是一個全功能的通訊框架,基於http/2.0標準協議可以實現更好的性能。>Maven依賴 <dependencies> <dependency> <groupId>io.grpc</groupId> <artifactId>grpc-netty</artifactId> <version>${grpc.version}<
  • RPC 框架,底層到底什麼原理?
    本文轉載自【微信公眾號:java進階架構師,ID:java_jiagoushi】經微信公眾號授權轉載,如需轉載與原文作者聯繫1.上面是一個簡單的軟體系統結構,我們拆分出來用戶系統和訂單系統做為服務存在,讓不同的站點去調用。只需要引入各個服務的接口包,在代碼中調用RPC服務就跟調用本地方法一樣,我剛接觸到這種調用方式的時候頗為驚奇,我明明調用的就是java語言方法啊(已java為例,現在RPC框架一般都支持多語言),怎麼就調用了遠程的服務了呢??
  • 手寫了一個RPC框架,成功幫助讀者斬獲字節等大廠offer
    介紹guide-rpc-framework 是一款基於 Netty+Kyro+Zookeeper 實現的 RPC 框架。推薦基於 NIO 的 Netty 框架。序列化 :既然涉及到網絡傳輸就一定涉及到序列化,你不可能直接使用 JDK 自帶的序列化吧!JDK 自帶的序列化效率低並且有安全漏洞。 所以,你還要考慮使用哪種序列化協議,比較常用的有 hession2、kyro、protostuff。
  • 手寫一個RPC框架,成功幫讀者斬獲字節、阿里等大廠Offer
    介紹guide-rpc-framework 是一款基於 Netty+Kyro+Zookeeper 實現的 RPC 框架。推薦基於 NIO 的 Netty 框架。序列化 :既然涉及到網絡傳輸就一定涉及到序列化,你不可能直接使用 JDK 自帶的序列化吧!JDK 自帶的序列化效率低並且有安全漏洞。 所以,你還要考慮使用哪種序列化協議,比較常用的有 hession2、kyro、protostuff。
  • 我手寫完RPC框架,成功幫助讀者斬獲阿里等大廠offer
    介紹guide-rpc-framework 是一款基於 Netty+Kyro+Zookeeper 實現的 RPC 框架。推薦基於 NIO 的 Netty 框架。序列化 :既然涉及到網絡傳輸就一定涉及到序列化,你不可能直接使用 JDK 自帶的序列化吧!JDK 自帶的序列化效率低並且有安全漏洞。 所以,你還要考慮使用哪種序列化協議,比較常用的有 hession2、kyro、protostuff。
  • 手寫一個 RPC 框架。畢設/項目經驗穩了
    原文連結:https://mp.weixin.qq.com/s/Avq4JBT-6-Dxgl7q8M251Qguide-rpc-framework 是一個 一款基於 Netty+Kyro+zookeeper 實現的自定義 RPC 框架。
  • 適合初中級Java程式設計師修煉手冊從0搭建整個Web項目(一)
    Http請求【基於Netty的請求級Web伺服器】 到mvc【接口封裝轉發)】,再到ioc【依賴注入】,aop【切面】,再到 rpc【遠程過程調用】最後到orm【資料庫操作】全部自己擼一個(簡易)的輪子。
  • GRPC:谷歌發布的首款基於HTTP/2和protobuf的RPC框架
    GRPC是一個高性能、開源、通用的RPC框架,面向移動和HTTP/2設計,是由谷歌發布的首款基於Protocol Buffers的RPC框架。目前提供C、Java和Go語言版本,這三個版本的源碼全都託管在Github上,分別是:grpc, grpc-java, grpc-go。
  • 神煩,老大要我寫一個RPC框架
    ,你可以嘗試去寫一個簡易版的框架出來,就比如如果你想理解 Spring IOC 的思想,最好的方式就是自己實現一個小型的 IOC 容器,自己慢慢體會。所以本文嘗試帶領大家去設計一個小型的 RPC 框架,同時對於框架會保持一些拓展點。通過閱讀本文,你可以收穫:理解 RPC 框架最核心的理念。學習在設計框架的時候,如何保持拓展性。
  • Guide自己動手寫了一個簡單的RPC框架
    Guide-rpc-framework 目前只實現了 RPC 框架最基本的功能,一些可優化點都在下面提到了,有興趣的小夥伴可以自行完善。介紹guide-rpc-framework 是一款基於 Netty+Kyro+zookeeper 實現的 RPC 框架。
  • Netty 3.2.4 Final 發布,NIO網絡框架
    netty  3.2.4 final 發布,距離上一個版本3.2.3 final 足足相隔了近3個月時間,不能不說netty  更新腳步變慢了。
  • RPC框架除了Dubbo或SpringCloud之外的選擇——Motan
    今天介紹一個在這兩者之外的其他框架Motan基本介紹Motan是一套基於java開發的RPC框架,由新浪微博開源。可靠性經過新浪微博生產環境驗證。除了常規的點對點調用外,Motan還提供服務治理功能,包括服務節點的自動發現、摘除、高可用和負載均衡等。
  • 大家都用 Netty,為什麼不用Java NIO?
    中間件開發中對IO及netty的設計?BIO,NIO,EPOLL,同步,異步,阻塞,非阻塞是一直圍繞程式設計師的問題,雖然優秀的框架,工具將這些點隱藏,但是,高素質,進大廠,突破薪資瓶頸都是需要對這些點準確理解。
  • RPC框架的原理和應用方法
    最後一個屏蔽程式設計師對遠程調用的細節實現,其實也就是第二點中提到的那些功能的封裝,我們不用去關係rpc到底是如何實現的,也不用關心它是如何運作的,對於業務開發人員來說,通過約定的方式進行類似於本地方法調用的形式來調用遠程服務接口就可以了。那麼如何實現透明化的遠程調用呢?什麼樣的內部封裝才能讓我們覺得像以本地調用方式調用遠程服務呢?
  • 還在被Java NIO虐?該試試Netty了
    Netty的特點:高並發:Netty 是一款基於 NIO(Nonblocking IO,非阻塞IO)開發的網絡通信框架,對比於 BIO(Blocking I/O,阻塞IO),它的並發性能得到了很大提高。傳輸快:Netty 的傳輸依賴於零拷貝特性,儘量減少不必要的內存拷貝,實現了更高效率的傳輸。
  • 程式設計師:利用Netty來寫一個簡單的聊天室、心跳檢測
    NettyNetty是由JBOSS提供的一個java開源框架,現為 Github上的獨立項目。Netty提供異步的、事件驅動的網絡應用程式框架和工具,用以快速開發高性能、高可靠性的網絡伺服器和客戶端程序。
  • gRPC 1.8.2 發布,Google 高性能 RPC 框架
    gRPC 1.8.2 已發布,該版本主要是修復 bug,具體如下:下載地址gRPC 是一個高性能、開源、通用的 RPC 框架,面向移動和 HTTP/2 設計