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

2021-01-15 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給你們學習。

相關焦點

  • getty 發布,一個完全基於 java 實現的 aio 框架
    說說寫這個框架的原因:1、作者本人是一個碼農,比較喜歡研究技術,特別是網絡通訊。2、JDK1.7升級了NIO類庫,升級後的NIO類庫被稱為NIO 2.0。
  • 微服務RPC框架選美
    說到RPC框架,可能大家能想到一堆RPC開源框架,那麼在微服務平臺中,微服務間的服務調用,不可避免的會遇到一個問題,該選用哪一個RPC框架好呢?今天我們就請到三位RPC框架,來進行一場選美大賽,看看誰更適合微服務平臺中的服務間調用。
  • gRPC首頁、文檔和下載 - RPC 框架 - OSCHINA - 中文開源技術交流...
    gRPC 是一個高性能、開源和通用的 RPC 框架目前提供 C、Java 和 Go 語言版本,分別是:grpc, grpc-java, grpc-go. 其中 C 版本支持 C, C++, Node.js, Python, Ruby, Objective-C, PHP 和 C# 支持.
  • smart-doc 1.9.7 發布,Java 零註解文檔生成工具
    smart-doc是一款同時支持java restful api和apache dubbo rpc接口文檔生成的工具
  • 從零開始,徒手擼一個簡單的 RPC 框架,輕鬆搞定!
    所以就想著試試自己實現一個簡單的RPC框架,即鞏固了基礎的知識,也能更加深入的了解RPC原理。當然一個完整的RPC框架包含了許多的功能,例如服務的發現與治理,網關等等。本篇只是簡單的實現了一個調用的過程。傳參出參分析一個簡單請求可以抽象為兩步
  • 從0 到 1:全面理解 RPC 遠程調用!
    光說不練嘴把式,接下來,我將分別用三種不同的方式全面地讓你搞明白 rpc 遠程調用是如何實現的。01、基於 xml-rpcPython實現 rpc,可以使用標準庫裡的 SimpleXMLRPCServer,它是基於XML-RPC 協議的。有了這個模塊,開啟一個 rpc server,就變得相當簡單了。
  • Mars-java 2.2.2 發布,不需要容器的 Java Web 開發框架
    默認請求方式為get 新增了RequestMethod註解,用來指定http接口的請求方式(不加默認為get) 將Resource註解換成了MarsWrite註解,用法保持不變(防止跟jdk自帶的Resource混淆) 將redis模塊從Mars-extends項目移到了主項目,以後連接redis不在需要導入Mars-extends擴展包了 對Mars-config項目進行了整理,並且將依賴的Mars-java
  • Quarkus 1.0 發布,Java 雲原生、容器優先框架
    Quarkus 是一個用於編寫 Java 應用的雲原生、容器優先框架。Java 開發人員能夠使用 Quarkus 構建具有比傳統的基於 Java 的微服務框架更快的啟動時間並佔用更少內存的應用。它包括靈活、易於使用的 API,這些 API 使開發人員能夠構建雲原生應用,同時還包含大多數開發人員已經熟悉的同類最佳框架,比如 Eclipse MicroProfile、Apache Kafka、RESTEasy(JAX-RS)、Hibernate ORM(JPA)、CDI、Spring 相關、Infinispan 與 Camel 等。
  • 五分鐘學後端技術:如何學習Java工程師必須掌握的RPC
    目前流行的開源 RPC 框架還是比較多的,有阿里巴巴的 Dubbo、Facebook 的 Thrift、Google 的 gRPC、Twitter 的 Finagle 等。常用的RPC框架gRPC:是 Google 公布的開源軟體,基於最新的 HTTP 2.0 協議,並支持常見的眾多程式語言。
  • 【行業資訊】SOFARPC v5.7.4 發布,螞蟻金服開源 Java RPC 框架
    SOFARPC 是一個高可擴展性、高性能、生產級的 Java RPC 框架。在螞蟻金服 SOFARPC 已經經歷了十多年及五代版本的發展。SOFARPC 致力於簡化應用之間的 RPC 調用,為應用提供方便透明、穩定高效的點對點遠程服務調用方案。
  • 搜狗開源srpc:自研高性能通用RPC框架
    9月15日,作為Workflow最重要的生態項目——srpc,一個基於其打造的輕量級RPC框架,也在GitHub上開源了。GitHub搜索「sogou srpc」即可找到該項目。一個性能更好的thrift/brpcsrpc與thrift/brpc是協議與IDL均互通的。
  • AJAXRPC: javascript調用服務端方法
    它允許你使用Javascript調用服務端方法,基於JSON數據協議,開源授權(LGPL),可同步和異步調用。 使用AJAXRPC,您可以像開發傳統的C/S程序一樣,來開發WEB程序,讓WEB開發更簡單和高效。 支持服務端語言:Java、.Net、PHP。 支持瀏覽器:IE、FireFox、Opera、Safari、Chrome。
  • 微服務之RPC簡述
    為實現該目標,RPC 框架需提供一種透明調用機制讓使用者不必顯式的區分本地調用和遠程調用。二、為什麼需要rpc1、分布式部署及微服務當我們的系統訪問量增大、業務增多時,我們會發現一臺單機運行此系統已經無法承受。此時,我們可以將業務拆分成幾個互不關聯的應用,分別部署在各自機器上,以劃清邏輯並減小壓力。
  • Springmvc框架對json的支持 Java程式設計師必看
    json是一種前後端分離思想所使用的存儲數據的格式,然而使用Springmvc這個框架在對前臺參數處理時會遇到很多坑,下面我們就模擬一下前臺發送json數據看springmvc能否成功接收。但是在寫json的時候還是出現了許多問題,用eclipse寫js代碼經常除了bug卻不知道問題出來哪裡。我們可以使用alert()或console.info()函數來進行判斷問題出在哪一行上。解決了發送json的問題後,又遇到一個bug,發送的json字符串返回的確實一個http415錯誤代碼,大概是說後端接收的參數類型不正確的意思,下面請看java代碼。
  • 2018年阿里巴巴關於Java重要開源項目匯總
    企業級流式計算引擎 JStormJStorm 是參考 Apache Storm 實現的實時流式計算框架,在網絡IO、線程模型、資源調度、可用性及穩定性上做了持續改進,已被越來越多企業使用。JStorm 可以看作是 storm 的 java 增強版本,除了內核用純java實現外,還包括了thrift、python、facet ui。
  • gRPC 通信框架實現存在數據洩露等安全問題
    gRPC 是一個高性能、開源和通用的 RPC 框架,面向移動和 HTTP/2 設計。目前提供 C、Java 和 Go 語言版本,分別是:grpc, grpc-java, grpc-go.將gRPC與其他RPC框架(例如SOAP和REST)進行了比較,儘管RESTful API被廣泛使用,並且通常使用HTTP在應用程式或服務與JavaScript Object Notation(JSON)數據格式之間交換信息,但是它們具有性能和基於文本的方向限制。許多組織已經將其API從REST遷移到gRPC,以利用更適合於服務間通信的gRPC二進位協議。
  • Java經典面試題Spring是什麼 Spring框架入門詳解
    到目前為止Sping框架就搭建完畢了。bean的name可以隨便取,一會我們會用到,class就是pojo的完整類名。那麼spring是否能夠完成我們自定義java對象的注入呢?除了構造外,spring還支持p名稱空間注入和spel表達式注入,spel基於set方法和構造方法注入的,所以我們通過圖中的注入方式足矣,也是主流的注入方式。
  • Java 反射:框架設計的靈魂
    講到這裡,有些同學可能會有疑問:「反射有什麼用?我明明都已經知道了要使用的類是 ArrayList ,我不能直接 new 一個對象然後執行裡面的方法麼?」當然可以!FaceRecognitionInterface faceRe = Class.forName(configStr).newInstance();faceRe.faceRecognition(faceImg);如果上面這個例子,你依然覺得在調用方法中做 if-else 判斷,和使用反射實現並沒有差太多,但是如果程式設計師 A 提供接口,程式設計師 B 提供實現,程式設計師 C 寫客戶端呢?
  • Java 反射最佳實踐
    本文的示例代碼主要是基於jOOR行編寫的,如果想了解更多請查看這裡的測試代碼。做普通的業務開發的話),僅僅在自己寫一些框架和註解框架時會用到,所以對api總是不熟悉。那麼什麼時候該用反射,什麼時候不用反射呢?用什麼方式來避免反射呢?如果不明白什麼時候用反射,就很難將反射活學活用了。二、分析當我們接到上面需求後,我長舒一口氣,因為這回的需求還比較簡單。