javaDubbo是做什么的

本篇內(nèi)容介紹了“java Dubbo是做什么的”的有關(guān)知識(shí),在實(shí)際案例的操作過程中,不少人都會(huì)遇到這樣的困境,接下來就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!

為岢嵐等地區(qū)用戶提供了全套網(wǎng)頁設(shè)計(jì)制作服務(wù),及岢嵐網(wǎng)站建設(shè)行業(yè)解決方案。主營業(yè)務(wù)為網(wǎng)站設(shè)計(jì)、網(wǎng)站制作、岢嵐網(wǎng)站設(shè)計(jì),以傳統(tǒng)方式定制建設(shè)網(wǎng)站,并提供域名空間備案等一條龍服務(wù),秉承以專業(yè)、用心的態(tài)度為用戶提供真誠的服務(wù)。我們深信只要達(dá)到每一位用戶的要求,就會(huì)得到認(rèn)可,從而選擇與我們長(zhǎng)期合作。這樣,我們也可以走得更遠(yuǎn)!

什么是 RPC

RPC,Remote Procedure Call 即遠(yuǎn)程過程調(diào)用,遠(yuǎn)程過程調(diào)用其實(shí)對(duì)標(biāo)的是本地過程調(diào)用,本地過程調(diào)用你熟悉吧?

想想那青蔥歲月,你在大學(xué)趕著期末大作業(yè),正在攻克圖書管理系統(tǒng),你奮筆疾書瘋狂地敲擊鍵盤,實(shí)現(xiàn)了圖書借閱、圖書歸還等等模塊,你實(shí)現(xiàn)的一個(gè)個(gè)方法之間的調(diào)用就叫本地過程調(diào)用。

你要是和我說你實(shí)現(xiàn)圖書館里系統(tǒng)已經(jīng)用了服務(wù)化,搞了遠(yuǎn)程調(diào)用了,我只能和你說你有點(diǎn)東西。

java Dubbo是做什么的

簡(jiǎn)單的說本機(jī)上內(nèi)部的方法調(diào)用都可以稱為本地過程調(diào)用,而遠(yuǎn)程過程調(diào)用實(shí)際上就指的是你本地調(diào)用了遠(yuǎn)程機(jī)子上的某個(gè)方法,這就是遠(yuǎn)程過程調(diào)用。

java Dubbo是做什么的

小結(jié)一下

讓我們小結(jié)一下,大致上一個(gè) RPC 框架需要做的就是約定要通信協(xié)議,序列化的格式、一些容錯(cuò)機(jī)制、負(fù)載均衡策略、監(jiān)控運(yùn)維和一個(gè)注冊(cè)中心!

簡(jiǎn)單實(shí)現(xiàn)一個(gè) RPC 框架

沒錯(cuò)就是簡(jiǎn)單的實(shí)現(xiàn),上面我們?cè)谒伎既绾卧O(shè)計(jì)一個(gè) RPC 框架的時(shí)候想了很多,那算是生產(chǎn)環(huán)境使用級(jí)別的功能需求了,我們這是 Demo,目的是突出 RPC框架重點(diǎn)功能 - 實(shí)現(xiàn)遠(yuǎn)程調(diào)用。

所以啥七七八八的都沒,并且我用偽代碼來展示,其實(shí)也就是刪除了一些保護(hù)性和約束性的代碼,因?yàn)榭雌饋硖嗔瞬惶庇^,需要一堆 try-catch 啥的,因此我刪減了一些,直擊重點(diǎn)。

Let's Do It!

首先我們定義一個(gè)接口和一個(gè)簡(jiǎn)單實(shí)現(xiàn)。

public interface AobingService {  
    String hello(String name);  
} public class AobingServiceImpl implements AobingService {  
    public String hello(String name) {  
        return "Yo man Hello,I am" + name;  
    }  
}

然后我們?cè)賮韺?shí)現(xiàn)服務(wù)提供者暴露服務(wù)的功能。

public class AobingRpcFramework { 
     public static void export(Object service, int port) throws Exception { 
          ServerSocket server = new ServerSocket(port);
          while(true) {
              Socket socket = server.accept();
              new Thread(new Runnable() {
                  //反序列化                  ObjectInputStream input = new ObjectInputStream(socket.getInputStream()); 
                  String methodName = input.read(); //讀取方法名                  Class<?>[] parameterTypes = (Class<?>[]) input.readObject(); //參數(shù)類型                  Object[] arguments = (Object[]) input.readObject(); //參數(shù)                  Method method = service.getClass().getMethod(methodName, parameterTypes);  //找到方法                  Object result = method.invoke(service, arguments); //調(diào)用方法                  // 返回結(jié)果                  ObjectOutputStream output = new ObjectOutputStream(socket.getOutputStream());
                  output.writeObject(result);
              }).start();
          }
     }
    public static <T> T refer (Class<T> interfaceClass, String host, int port) throws Exception {
       return  (T) Proxy.newProxyInstance(interfaceClass.getClassLoader(), new Class<?>[] {interfaceClass}, 
            new InvocationHandler() {  
                public Object invoke(Object proxy, Method method, Object[] arguments) throws Throwable {  
                    Socket socket = new Socket(host, port);  //指定 provider 的 ip 和端口                    ObjectOutputStream output = new ObjectOutputStream(socket.getOutputStream()); 
                    output.write(method.getName());  //傳方法名                    output.writeObject(method.getParameterTypes());  //傳參數(shù)類型                    output.writeObject(arguments);  //傳參數(shù)值                    ObjectInputStream input = new ObjectInputStream(socket.getInputStream());  
                    Object result = input.readObject();  //讀取結(jié)果                    return result;  
               }
        });  
    }  
}

好了,這個(gè) RPC 框架就這樣好了,是不是很簡(jiǎn)單?就是調(diào)用者傳遞了方法名、參數(shù)類型和參數(shù)值,提供者接收到這樣參數(shù)之后調(diào)用對(duì)于的方法返回結(jié)果就好了!這就是遠(yuǎn)程過程調(diào)用。

我們來看看如何使用

        //服務(wù)提供者只需要暴露出接口       AobingService service = new AobingServiceImpl ();  
       AobingRpcFramework.export(service, 2333);  

       //服務(wù)調(diào)用者只需要設(shè)置依賴       AobingService service = AobingRpcFramework.refer(AobingService.class, "127.0.0.1", 2333);  
       service.hello();

看起來好像好不錯(cuò)喲,不過這很是簡(jiǎn)陋,用作 demo 有助理解還是極好的!

接下來就來看看 Dubbo 吧!上正菜!

Dubbo 簡(jiǎn)介

Dubbo 是阿里巴巴 2011年開源的一個(gè)基于 Java 的 RPC 框架,中間沉寂了一段時(shí)間,不過其他一些企業(yè)還在用 Dubbo 并自己做了擴(kuò)展,比如當(dāng)當(dāng)網(wǎng)的 Dubbox,還有網(wǎng)易考拉的 Dubbok。

但是在 2017 年阿里巴巴又重啟了對(duì) Dubbo 維護(hù)。在 2017 年榮獲了開源中國 2017 最受歡迎的中國開源軟件 Top 3。

在 2018 年和 Dubbox 進(jìn)行了合并,并且進(jìn)入 Apache 孵化器,在 2019 年畢業(yè)正式成為 Apache 頂級(jí)項(xiàng)目。

目前 Dubbo 社區(qū)主力維護(hù)的是 2.6.x 和 2.7.x 兩大版本,2.6.x 版本主要是 bug 修復(fù)和少量功能增強(qiáng)為準(zhǔn),是穩(wěn)定版本。

而 2.7.x 是主要開發(fā)版本,更新和新增新的 feature 和優(yōu)化,并且 2.7.5 版本的發(fā)布被 Dubbo 認(rèn)為是里程碑式的版本發(fā)布,之后我們?cè)僮龇治觥?/p>

它實(shí)現(xiàn)了面向接口的代理 RPC 調(diào)用,并且可以配合 ZooKeeper 等組件實(shí)現(xiàn)服務(wù)注冊(cè)和發(fā)現(xiàn)功能,并且擁有負(fù)載均衡、容錯(cuò)機(jī)制等。

Dubbo 總體架構(gòu)

我們先來看下官網(wǎng)的一張圖。

java Dubbo是做什么的

大的三層分別為 Business(業(yè)務(wù)層)、RPC 層、Remoting,并且還分為 API 層和 SPI 層。

分為大三層其實(shí)就是和我們知道的網(wǎng)絡(luò)分層一樣的意思,只有層次分明,職責(zé)邊界清晰才能更好的擴(kuò)展。

而分 API 層和 SPI 層這是 Dubbo 成功的一點(diǎn),采用微內(nèi)核設(shè)計(jì)+SPI擴(kuò)展,使得有特殊需求的接入方可以自定義擴(kuò)展,做定制的二次開發(fā)。

接下來咱們?cè)賮砜纯疵恳粚佣际歉陕锏摹?/p>

  • Service,業(yè)務(wù)層,就是咱們開發(fā)的業(yè)務(wù)邏輯層。

  • Config,配置層,主要圍繞 ServiceConfig 和 ReferenceConfig,初始化配置信息。

  • Proxy,代理層,服務(wù)提供者還是消費(fèi)者都會(huì)生成一個(gè)代理類,使得服務(wù)接口透明化,代理層做遠(yuǎn)程調(diào)用和返回結(jié)果。

  • Register,注冊(cè)層,封裝了服務(wù)注冊(cè)和發(fā)現(xiàn)。

  • Cluster,路由和集群容錯(cuò)層,負(fù)責(zé)選取具體調(diào)用的節(jié)點(diǎn),處理特殊的調(diào)用要求和負(fù)責(zé)遠(yuǎn)程調(diào)用失敗的容錯(cuò)措施。

  • Monitor,監(jiān)控層,負(fù)責(zé)監(jiān)控統(tǒng)計(jì)調(diào)用時(shí)間和次數(shù)。

  • Portocol,遠(yuǎn)程調(diào)用層,主要是封裝 RPC 調(diào)用,主要負(fù)責(zé)管理 Invoker,Invoker代表一個(gè)抽象封裝了的執(zhí)行體,之后再做詳解。

  • Exchange,信息交換層,用來封裝請(qǐng)求響應(yīng)模型,同步轉(zhuǎn)異步。

  • Transport,網(wǎng)絡(luò)傳輸層,抽象了網(wǎng)絡(luò)傳輸?shù)慕y(tǒng)一接口,這樣用戶想用 Netty 就用 Netty,想用 Mina 就用 Mina。

  • Serialize,序列化層,將數(shù)據(jù)序列化成二進(jìn)制流,當(dāng)然也做反序列化。

SPI

我再稍微提一下 SPI(Service Provider Interface),是 JDK 內(nèi)置的一個(gè)服務(wù)發(fā)現(xiàn)機(jī)制,它使得接口和具體實(shí)現(xiàn)完全解耦。我們只聲明接口,具體的實(shí)現(xiàn)類在配置中選擇。

具體的就是你定義了一個(gè)接口,然后在META-INF/services目錄下放置一個(gè)與接口同名的文本文件,文件的內(nèi)容為接口的實(shí)現(xiàn)類,多個(gè)實(shí)現(xiàn)類用換行符分隔。

這樣就通過配置來決定具體用哪個(gè)實(shí)現(xiàn)!

而 Dubbo SPI 還做了一些改進(jìn),篇幅有限留在之后再談。

Dubbo 調(diào)用過程

上面我已經(jīng)介紹了每個(gè)層到底是干嘛的,我們現(xiàn)在再來串起來走一遍調(diào)用的過程,加深你對(duì) Dubbo 的理解,讓知識(shí)點(diǎn)串起來,由點(diǎn)及面來一波連連看。

java Dubbo是做什么的

服務(wù)暴露過程

首先 Provider 啟動(dòng),通過 Proxy 組件根據(jù)具體的協(xié)議 Protocol 將需要暴露出去的接口封裝成 Invoker,Invoker 是 Dubbo 一個(gè)很核心的組件,代表一個(gè)可執(zhí)行體。

然后再通過 Exporter 包裝一下,這是為了在注冊(cè)中心暴露自己套的一層,然后將 Exporter 通過 Registry 注冊(cè)到注冊(cè)中心。 這就是整體服務(wù)暴露過程。

消費(fèi)過程

接著我們來看消費(fèi)者調(diào)用流程(把服務(wù)者暴露的過程也在圖里展示出來了,這個(gè)圖其實(shí)算一個(gè)挺完整的流程圖了)。

首先消費(fèi)者啟動(dòng)會(huì)向注冊(cè)中心拉取服務(wù)提供者的元信息,然后調(diào)用流程也是從 Proxy 開始,畢竟都需要代理才能無感知。

Proxy 持有一個(gè) Invoker 對(duì)象,調(diào)用 invoke 之后需要通過 Cluster 先從 Directory 獲取所有可調(diào)用的遠(yuǎn)程服務(wù)的 Invoker 列表,如果配置了某些路由規(guī)則,比如某個(gè)接口只能調(diào)用某個(gè)節(jié)點(diǎn)的那就再過濾一遍 Invoker 列表。

剩下的 Invoker 再通過 LoadBalance 做負(fù)載均衡選取一個(gè)。然后再經(jīng)過 Filter 做一些統(tǒng)計(jì)什么的,再通過 Client 做數(shù)據(jù)傳輸,比如用 Netty 來傳輸。

傳輸需要經(jīng)過 Codec 接口做協(xié)議構(gòu)造,再序列化。最終發(fā)往對(duì)應(yīng)的服務(wù)提供者。

服務(wù)提供者接收到之后也會(huì)進(jìn)行 Codec 協(xié)議處理,然后反序列化后將請(qǐng)求扔到線程池處理。某個(gè)線程會(huì)根據(jù)請(qǐng)求找到對(duì)應(yīng)的 Exporter ,而找到 Exporter 其實(shí)就是找到了 Invoker,但是還會(huì)有一層層 Filter,經(jīng)過一層層過濾鏈之后最終調(diào)用實(shí)現(xiàn)類然后原路返回結(jié)果。

“java Dubbo是做什么的”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí)可以關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!

新聞標(biāo)題:javaDubbo是做什么的
鏈接地址:http://muchs.cn/article0/johgoo.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供品牌網(wǎng)站制作、Google、標(biāo)簽優(yōu)化網(wǎng)站設(shè)計(jì)公司、微信公眾號(hào)、自適應(yīng)網(wǎng)站

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

成都做網(wǎng)站