Dubbo原始碼分析:RPC協議實現-RPC過程與核心介面設計
阿新 • • 發佈:2018-12-04
RPC的基本過程
- 提供者Provider:提供服務的介面定義和介面的具體實現,然後通過URL的方式告訴消費者,某個URL對應某個service實現,一般是將服務的資訊註冊到一個註冊中心,如zookeeper或者Redis等;
- 消費者Consumer:獲取提供者的介面定義,一般通過引入jar包的方式,從而獲得提供者的介面和方法定義,如方法引數個數,引數型別;在消費者本地封裝資料,如方法引數值,對提供者提供的服務進行遠端呼叫,而這個遠端呼叫是通過消費者本地的一個代理物件進行的,即將需要呼叫的方法,進行方法呼叫的資料,交給該代理物件,由該代理物件發起對提供者的請求,獲取提供者的響應,然後將請求結果返回給消費者。
- 整個過程如下:其中1. register提供者註冊,4.invoker是由消費者呼叫均是通過代理完成的。
遠端呼叫過程:
- 核心介面
核心介面設計
Protocol:RPC協議介面
-
export方法
- 模板方法,提供者需要實現export方法,具體為AbstractProxyProtocol,定義如何將自己提供的服務暴露出去,同時設定消費者訪問呼叫請求的requestHandler,處理消費者的遠端呼叫請求。
- 具體是由AbstractProxyProtocol的實現類定義和實現doExport方法完成實際註冊操作,如HttpProtocol協議實現如下:
(1)httpBinder.bind(url, new InternalHandler()):監聽消費者請求,InternalHandler負責處理請求和進行相應;
(2)createExporter(impl, type):進行服務註冊。
-
refer方法
- 模板方法,消費者實現refer方法,具體為AbstractProxyProtocol,提供自己需要呼叫的遠端服務的class型別,provider暴露服務的url地址,獲得對遠端服務進行實際服務呼叫的代理,即該代理對服務消費者而言,就是服務提供者,代理在服務提供者和服務消費者之間作為中間人,搭建了一個服務呼叫的橋樑。
- 具體的服務呼叫由AbstractProxyProtocol的實現類定義和實現doRefer方法實現,如HttpProtocol協議實現如下:
構造httpProxyFactoryBean例項,設定好呼叫的遠端服務介面名,服務暴露的URL,呼叫相關資料,如引數值,通過httpProxyBean完成服務呼叫。
Provider相關:服務提供者提供服務
- Exporter:服務暴露介面,該介面表示提供者將服務暴露或者說註冊到了一個註冊中心,同時可以取消、回收服務的註冊。
- ExporterListener:服務暴露監聽器,在對服務進行暴露後,或者取消已經暴露的服務,進行回撥處理。
Consumer相關:服務消費者消費服務
- Invoker:服務呼叫介面,服務消費者實現該介面,定義需要消費、呼叫的介面;invoke發起對遠端服務提供者,所提供的服務的請求、呼叫。
- Invocation:封裝consumer進行遠端服務呼叫的相關資料,如要呼叫的方法,進行呼叫的相關引數、引數型別和引數值等。
- InvokerListener:服務呼叫監聽器,消費者實現該介面,在進行了對遠端服務的呼叫進行回撥;在服務提供者取消或回收了服務後,對消費者本地的消費代理進行銷燬。
ProxyFactory:代理工廠介面
- Dubbo支援兩種型別的代理,分別是javassist和jdk,可以通過URL的proxy引數來指定,預設為javassist代理,如下:
- ProxyFactory定義:所有方法均有@Adaptive註解,可以通過URL的proxy引數動態決定使用哪種proxyFactory實現,預設為javassist。
- 每個具體的RPC協議實現均包含一個proxyFactory代理工廠屬性,通過proxyFactory獲取proxy例項,從而對invoker進行封裝,通過代理進行服務呼叫。原始碼如下:
- AbstractProxyProtocal:包含setProxyFactory方法,ExtensionLoader會根據@Adaptive規則,自動注入。
- 在提供者export暴露服務時,呼叫proxy.getProxy獲取proxy例項作為doExport引數;消費者refer呼叫遠端服務時,底層呼叫doRefer(type, url)方法,該方法返回proxy例項,由該proxy例項進行服務呼叫。
- 具體RPC實現類繼承AbstractProxyProtocol