日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

让我带你弄明白什么是RPC ,帮你整理一下你的小脑瓜!

發布時間:2024/3/13 编程问答 50 豆豆
生活随笔 收集整理的這篇文章主要介紹了 让我带你弄明白什么是RPC ,帮你整理一下你的小脑瓜! 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、系統架構的演變

1、單一應用架構

將所有的功能模塊都放在1個工程中編碼、編譯、打包并且部署在1個tomcat容器中的架構。這樣維護成本比較低。

優點:

  • 項目前期開發周期快,團隊成員少的時候能夠快速迭代;
  • 架構簡單:MVC架構,只需借助IDE開發,調試即可。
  • 易于測試:只通過單元測試或者瀏覽器完成
  • 易于部署
  • 缺點:

  • 隨著時間推移業務增加,功能不斷迭代,項目會變得臃腫,業務耦合嚴重

  • 新增業務困難

  • 核心業務與邊緣業務混在一塊兒,出現問題相互影響。

  • 2、垂直架構

    為了解決單體框架出現的問題,開始按著業務做垂直劃分。把原來的一個單體拆成一堆單體應用,這時候就由原來的單應用變成多應用部署。

    優點:

  • 可以針對不同模塊進行優化;
  • 方便水平擴展,負載均衡,容錯率提高。
  • 系統間相互獨立,互不影響,新的業務迭代時會更加高效。
  • 缺點:

  • 服務之間相互調用,如果某個服務的端口或者IP地址發生改變,調用的系統得手動改變。
  • 搭建集群之后,實現負載均衡比較復雜;
  • 服務之間調用方式不統一,基于httpclient、webservice,接口協議不統一。
  • 服務監控不到位:除了依靠端口、進程的監控,調用的成功率、失敗率、總耗時等等這些的監控指標是沒有用的。
  • 3、SOA架構

    【領取資料】 即面向服務的架構。其思想就是根據實際業務,把業務拆分成合適的、獨立部署的模塊,模塊之間相互獨立(通過Webservice/Double等技術進行通信)

    二、RPC

    1、RPC核心和調用的大體流程

    1)RPC(remote procedure call) 遠程過程調用,簡單的理解是一個節點請求另外1個節點的服務。

    調用過程:

    客戶端(Client):服務調用。

    客戶端存根(Client Stub):存放服務端地址信息,將客戶端的請求參數數據信息打包成網絡消息, 再通過網絡傳輸發送給服務端。

    服務端存根(Server Stub):接受客戶端發送過來的消息并解包,再調用本地服務進行處理。

    服務端(Server):服務的真正提供者。

    Network Service:底層傳輸,可以是 TCP 或 HTTP

    2、完整的RPC架構圖

    在一個典型RPC的使用場景中,包括了服務發現、負載、容錯、網絡傳輸、序列化等組件,其中RPC協議就指了程序如何進行網絡傳輸和序列化。

    3、RPC核心功能及實現

    服務尋址

    數據流的序列化和反序列化

    三、網絡傳輸

    1、服務尋址

  • 在RPC中,所有的函數都必須有自己的一個ID。這個ID在所有進程中都是唯一確定的。
  • 客戶在做遠程調用時必須附上這個ID。然后我們還需要在客戶端和服務端分別維護一個 函數和Call ID的對應表。
  • 當客戶端需要進行遠程調用時,它就查下這個表,找出相應的 Call ID,然后把它傳給服務端,服務端也通過查表,來確定客戶端需要調用的函數,然后執行相應函數的代碼
  • 2、序列化和反序列化

    本地調用,我們只需要把參數壓到棧里,然后然函數直接從棧里讀就行。但是在遠程調用時客戶端和服務端是不同的進程,不能通過內存傳遞參數。這時就需要客戶端把參數轉換成一個字節流,傳給服務端后,再把字節流轉成自己能讀取的格式。

    定義:

    序列化:將對象轉換轉換成二進制流程的過程叫做序列化

    反序列化:將二進制流轉換成對象的過程叫做反序列化

    3、網絡傳輸

    【領取資料】 網絡傳輸層需要把call ID和序列化的參數字節流傳給服務端,然后再把序列化好的調用結果傳給客戶端。

    所以,要實現一個RPC框架,只需要把以下三點實現了就基本完成; :

  • call id映射:可以直接使用函數字符串,也可以使用整數ID。映射表一般是1個Hash表。
  • 序列化反序列化:可以自己寫,也可以使用protobuf或者FlatBuffers之類的。
  • 網絡傳輸,可以自己寫Socket,或者用Netty
  • 四、Dubbo

    經典的RPC框架

    調用關系說明:?

  • 服務容器負責啟動,加載,運行服務提供者。
  • 服務提供者在啟動時,向注冊中心注冊自己提供的服務。
  • 服務消費者在啟動時,向注冊中心訂閱自己所需的服務。
  • 注冊中心返回服務提供者地址列表給消費者,如果有變更,注冊中心將基于長連接推送變更數據給消費者。
  • 服務消費者,從提供者地址列表中,基于軟負載均衡算法,選一臺提供者進行調用,如果調用失敗,再選另一臺調用。
  • 服務消費者和提供者,在內存中累計調用次數和調用時間,定時每分鐘發送一次統計數據到監控中心。
  • Config 配置中心

    Proxy 代理

    Registry 注冊中心

    Cluster 負載均衡、路由(輪詢、權重、一致性hash)

    Monitor 監控

    Protocal 發起調用

    Exchange 交換

    Transport 傳輸(netty)

    Serialize 序列化

    dubbo 架構特點分別是連通性健壯性伸縮性、以及向未來架構的升級

    連通性

    • 注冊中心負責服務地址的注冊與查找,相當于目錄服務,服務提供者和消費者只在啟動時與注冊中心交互,注冊中心不轉發請求,壓力較小
    • 監控中心負責統計各服務調用次數,調用時間等,統計先在內存匯總后每分鐘一次發送到監控中心服務器,并以報表展示
    • 服務提供者向注冊中心注冊其提供的服務,并匯報調用時間到監控中心,此時間不包含網絡開銷
    • 服務消費者向注冊中心獲取服務提供者地址列表,并根據負載算法直接調用提供者,同時匯報調用時間到監控中心,此時間包含網絡開銷
    • 注冊中心,服務提供者,服務消費者三者之間均為長連接,監控中心除外
    • 注冊中心通過長連接感知服務提供者的存在,服務提供者宕機,注冊中心將立即推送事件通知消費者
    • 注冊中心和監控中心全部宕機,不影響已運行的提供者和消費者,消費者在本地緩存了提供者列表
    • 注冊中心和監控中心都是可選的,服務消費者可以直連服務提供者 監控中心宕掉不影響使用,只是丟失部分采樣數據
    • 數據庫宕掉后,注冊中心仍能通過緩存提供服務列表查詢,但不能注冊新服務
    • 注冊中心對等集群,任意一臺宕掉后,將自動切換到另一臺 注冊中心全部宕掉后,服務提供者和服務消費者仍能通過本地緩存通訊
    • 服務提供者無狀態,任意一臺宕掉后,不影響使用
    • 服務提供者全部宕掉后,服務消費者應用將無法使用,并無限次重連等待服務提供者恢復
    • 注冊中心為對等集群,可動態增加機器部署實例,所有客戶端將自動發現新的注冊中心
    • 服務提供者無狀態,可動態增加機器部署實例,注冊中心將推送新的服務提供者信息給消費者

    ?

    健壯性

    • 監控中心宕掉不影響使用,只是丟失部分采樣數據
    • 數據庫宕掉后,注冊中心仍能通過緩存提供服務列表查詢,但不能注冊新服務
    • 注冊中心對等集群,任意一臺宕掉后,將自動切換到另一臺
    • 注冊中心全部宕掉后,服務提供者和服務消費者仍能通過本地緩存通訊
    • 服務提供者無狀態,任意一臺宕掉后,不影響使用
    • 服務提供者全部宕掉后,服務消費者應用將無法使用,并無限次重連等待服務提供者恢復

    伸縮性

    • 注冊中心為對等集群,可動態增加機器部署實例,所有客戶端將自動發現新的注冊中心
    • 服務提供者無狀態,可動態增加機器部署實例,注冊中心將推送新的服務提供者信息給消費者

    五、Springboot 中Dubbo使用

    1、安裝

  • 安裝zookeeper
  • 監控中心 dubbo admin
  • 2、使用方式

    配置類、注解方式

    Service 一定要引入dubbo的注解。

    看官網

    3、超時配置

    【領取資料】

    <dubbo:reference interface="com.foo.BarService" check="false"timeout="1000"/>

    配置超時時間的優先順序如下:

  • 方法級優先,接口級次之,全局配置再次之
  • 如果級別一樣,則消費方優先,提供方次之。
  • 其中,服務提供方配置,通過URL經由注冊中心傳遞給消費方。

    Dubbo常用的配置

    啟動檢查

    <dubbo:reference interface="com.foo.BarService" check="false" />

    超時配置

    <dubbo:reference interface="com.foo.BarService" check="false"timeout="1000"/>

    重試次數

    冪等(設置重試次數,查詢、刪除、修改**) 非冪等(不能設置,新增)

    <dubbo:reference id="orderService"interface="com.end.dubbo.api.service.OrderService" retries="3" />

    多版本分組

    <dubbo:reference id="orderService"interface="com.end.dubbo.api.service.OrderService" group="g1" />

    六、api 和spi

    Spi:調用方來定制接口,實現方來針對接口實現不同的實現。調用方來選擇自己需要的實現方法。

    常見的spi:

  • 數據庫驅動
  • 日志log
  • dubbo擴展點開發
  • Springboot自動裝配機
  • JDK中的spi實現方式

    原理:

    在ServiceLoader的load方法中首先會獲取上下文類加載器,然后構造一個ServiceLoader,在 ServiceLoader中有一個懶加載器,懶加載器會通過BufferedReader來從META-INF/services路徑 下讀取 對應的接口名的全路徑名文件,也就是我們配置的文件,然后通過文件的類解析器讀取文件中的內 容,再通過類加載器加載類的全路徑。

    缺點:

  • 無法按需加載;
  • 不具有IOC的功能;
  • serviceLoader不是線程安全的,會出現線程安全問題
  • dubbo中的spi實現方式

    man=dubbo.impl.Man

    woman=dubbo.impl.Woman

    可以按需加載,可擴展的能力

    七、線程派發模型

    1、配置

    <dubbo:protocol name="dubbo" port="20880" threadpool="fixed" threads="200"iothreads="8" accepts="0" queues="100" dispatcher="all"/>

    Netty

    在netty中存在兩種線程:boss線程和worker線程

    1)boss線程

    作用:accept客戶端的連接:將接收到的連接注冊到一個worker線程上。

    通常情況下,服務端每綁定一個端口,開啟一個boss線程

    2)worker線程

    作用:處理注冊在其身上的連接connection上的各種io事件

    個數:核數+1

    注意:一個worker線程可以注冊多個connection;

    一個connection只能注冊在一個worker線程上

    八、線程池的5種派發策略

    默認是all:所有消息都派發到線程池,包括請求,響應,連接事件,斷開事件,心跳等。 即 worker線程接收到事件后,將該事件提交到業務線程池中,自己再去處理其他事。

    • direct:worker線程接收到事件后,由worker執行到底(所有消息都不派發到線程池,全部在 Io線程上直接執行)。
    • message:只有請求響應消息派發到線程池,其它連接斷開事件,心跳等消息,直接在 IO線 程上執行
    • **execution:**只請求消息派發到線程池,不含響應(客戶端線程池),響應和其它連接斷開事 件,心跳等消息,直接在 IO 線程上執行
    • **connection:**在 IO 線程上,將連接斷開事件放入隊列,有序逐個執行,其它消息派發到線程

    dubbo4個常用的threadpool:

    fixed 固定大小線程池,啟動時建立線程,不關閉,一直持有。

    cached 緩存線程池,空閑一分鐘自動刪除,需要時重建。

    limited 可伸縮線程池,但池中的線程數只會增長不會收縮。只增長不收縮的目的是為了避免收縮時突然帶來大流量引起性能問題.

    eager 優先創建Worker線程池。在任務數量大于corePoolSize但是小于maximumPoolSize時,優先創建Worker來處理任務。當任務數量大于maximumPoolSize時,將任務放入阻塞隊列中。阻塞隊列充滿時拋出RejectedExecutionException。(相比于cached:cached在任務數量超過maximumPoolSize時直接拋出異常而不是將任務放入阻塞隊列)
    ?

    Dubbo的線程派發模型

    整體步驟:(受限于派發策略,以默認的all為例)

  • 客戶端的主線程發出一個請求后獲得future,在執行get時進行阻塞等待;

  • 服務端使用worker線程(netty通信模型)接收到請求后,將請求提交到server線程池中進行處理!

  • server線程處理完成之后,將相應結果返回給客戶端的worker線程池(netty通信模型),最后,worker線程將響應結果提交到client線程池進行處理!

  • client線程將響應結果填充到future中,然后喚醒等待的主線程,主線程獲取結果,返回給客戶端。

  • 最后

    最近我整理了整套《JAVA核心知識點總結》,說實話 ,作為一名Java程序員,不論你需不需要面試都應該好好看下這份資料。拿到手總是不虧的~我的不少粉絲也因此拿到騰訊字節快手等公司的Offer

    【Java進階之路群】,找管理員獲取哦-!

    ?

    ?

    ?

    總結

    以上是生活随笔為你收集整理的让我带你弄明白什么是RPC ,帮你整理一下你的小脑瓜!的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。