Dubbo 簡要介紹和使用 學習(一)

筆記簡述
本學習筆記主要是介紹了dubbo的基礎內容,簡單說明了dubbo、rpc、soa、zk等概念,并沒有直接貼出dubbo的組件調用圖等內容,而是利用實際的代碼介紹dubbo的服務提供方以及調用方的配置,對dubbo有一個感性的認識并通過dubbo-admin以及telnet查看dubbo的運行數據
后續會深入學習和分析dubbo spi以及暴露服務等等源碼
更多內容可看[目錄]Dubbo 源碼學習

目錄

Dubbo 介紹和使用 學習
1、前言
1.1、Dubbo 簡介
1.2、RPC 簡介
1.3、SOA 簡介
1.4、Zookeeper 簡介&安裝
2、Dubbo 服務提供方
3、Dubbo 服務調用方
4、參考鏈接

1、前言

1.1、Dubbo 簡介

Dubbo是由阿里巴巴基于java開發的一個RPC框架,經歷過了長時間的停止維護后又重新開始維護,現在(2018年04月17日)已經劃入了Apache孵化項目中,github地址:https://github.com/apache/incubator-dubbo,在國內屬于一個應用廣泛的RPC框架,接下來就一起來學習Dubbo是如何使用的,其原理又是如何。
TODO 提個問題那么Dubbo和Spring Cloud又有什么同異呢?

1.2、RPC 簡介

RPC全稱Remote Procedure Call,中文名叫遠程過程調用,通過網絡利用TCP或者UDP協議實現的不同機器之間的數據傳輸協議,A機器想調取B機器提供的服務,A機器拼接好自身請求的參數之后由RPC框架包裝成為特定格式的數字,序列化后后通過網絡發送到B機器上,B機器的RPC框架反解析出參數數據后去invoke調用自身機器的服務,最后按照原路返回到A機器上。

RPC是C/S模式,而且屏蔽了傳輸層和應用層,再基于特定的協議,使得用戶只需要關注自身的業務即可。

1.3、SOA 簡介

SOA全稱Service-Oriented Architecture,中文名叫面向服務編程,另一個常用的名稱是服務發現。業務繁多而且復雜就需要有一種統一的管理服務的機制,在分布式架構中,新加入的機器或者宕掉的機器后系統如何自動調整,一方面使得流量分發均衡,另一方面能夠及時發現出現異常的服務;控制服務與服務的調用關系等,確保服務合理正常的運行,例如zookeeper可以統一管理各機器以及機器上的服務運行情況。

在我們介紹的dubbo也會使用zookeeper作為其服務注冊中心

1.4、Zookeeper 簡介&安裝

zookeeper是為分布式應用提供一致性服務的軟件,提供的功能包括:配置維護、域名服務、分布式同步、組服務等。

進入到http://mirrors.hust.edu.cn/apache/zookeeper/頁面選擇一個合適的版本,進入下載其tar.gz包,隨便解壓到一個本地目錄,如下圖

image

進入到conf文件夾,可以看到zoo_sample.cfg文件,直接cp一個名字為zoo.cfg的文件,可以把內容修改為如下內容

$ cat zoo.cfg
tickTime=2000
dataDir=../data      // 工作路徑,表示為conf的上一級目錄的data文件夾
dataLogDir=../logs  // 日志的路徑
clientPort=2182  // zk啟動的端口

現在就可以啟動zk了,進入到bin目錄,Windows環境選擇zkServer.cmd,Unix類環境選擇zkServer.sh

$ ./zkServer.sh
JMX enabled by default
Using config: ./../conf/zoo.cfg
Usage: ./zkServer.sh {start|start-foreground|stop|restart|status|upgrade|print-cmd}

如上述執行結果,很明顯已經確實加載了之前配置的zoo.cfg文件,但是需要加上啟動參數,其中有{start|start-foreground|stop|restart|status|upgrade|print-cmd}

  • start-foreground 前臺啟動,可以看到實時日志
  • start 后臺啟動

在這遇到一個,當前臺啟動之后,執行stop命令時,會提示沒有發現對應的服務pid,可是如果以start方式啟動,就可以正常使用stop關閉zk服務

image

zk服務已經正常啟動了,如下圖,1896端口的服務就是zk啟動的java進程服務

image

2、Dubbo 服務提供方

整個的文件目錄結構


image

spring-product.xml

<context:property-placeholder location="pro.properties" />

<!-- 消費方應用名 -->
<dubbo:application name="${dubbo.application.name}" owner="${dubbo.application.owner}" />
<dubbo:provider loadbalance="random" default="true"/>
<dubbo:registry protocol="zookeeper" address="${dubbo.zk.servers}" client="zkclient" group="${dubbo.zk.group}"/>
<dubbo:protocol name="${dubbo.application.protocol.name}" port="${dubbo.application.protocol.port}"/>
<!--<dubbo:monitor address="${dubbo.monitor.address}" />-->
<dubbo:consumer check="false" />

<bean class="com.jwfy.dubbo.product.ProductServiceImpl" id="productService" />
<!--  基礎的bean 配置-->

<dubbo:service interface="com.jwfy.dubbo.product.ProductService" ref="productService" />
<!-- dubbo 對外暴露的接口,映射到的實體bean是productService-->

pro.properties

# dubbo
dubbo.application.name=dubbo-demo
dubbo.application.owner=jwfy
dubbo.application.protocol.name=dubbo
dubbo.application.protocol.port=20880

# dubbo.monitor.address=dubbo://127.0.0.1:20888
dubbo.zk.servers=127.0.0.1:2182
dubbo.zk.group=dubbo-demo

dubbo的相關配置,包含了使用的協議以及端口還有zk的配置情況,這里就使用了2182端口,到時候就會連上上文啟動的zk服務

ProductService 接口

public interface ProductService {
    void print();
    String getStr();
}

dubbo對外暴露的時候都是通過動態代理反射的,必須存在相關接口

ProductServiceImpl 實現類

public class ProductServiceImpl implements ProductService {

    public void print() {
        System.out.println("print");
    }

    public String getStr() {
        return "Hello World Product";
    }
}

ProductBootstrap 啟動類

public class ProductBootstrap {
    
    /**
    * 其實這個函數是用硬編碼的形式代替xml配置,xml配置最后都會變成如下的數據以及參數進行處理
    */
    public static void runProduct(){
        ProductService demo = new ProductServiceImpl();
        ApplicationConfig config=new ApplicationConfig("simple-spring-dubbo");

        RegistryConfig reg=new RegistryConfig("127.0.0.1:2182");
        reg.setProtocol("zookeeper");

        ProtocolConfig protocol = new ProtocolConfig();
        protocol.setName("dubbo");
        protocol.setPort(20880);

        ServiceConfig<ProductService> service=new ServiceConfig<ProductService>();
        service.setApplication(config);
        service.setRegistry(reg);
        service.setProtocol(protocol);
        service.setInterface(ProductService.class);
        service.setRef(demo);
        service.setVersion("1.0");
        service.export();
        // export是最關鍵的函數,對外暴露服務
        // 包括了向zk注冊以及啟動netty服務等待接受調用

        try {
            Thread.sleep(Integer.MAX_VALUE);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public static void runDubboProduct(){
        ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext(
                new String[]{"spring-product.xml"});

        while (true){
       // 為了讓服務不會自己終止,加個死循環
        }
    }

    public static void main(String[] args){
        //runProduct();
        runDubboProduct();
    }

}

如下圖dubbo-admin顯示的數據,服務提供方已經正常啟動,同時可以看到該服務的具體情況


image
image
image

可以通過Telnet查看當前機器上dubbo服務提供方的一些數據,當線上服務提供方添加了新的接口就可以通過該方法確認

3、Dubbo 服務調用方

調用方文件目錄結構

image

spring-consume.xml 文件

<context:property-placeholder location="application.properties" />

<!-- 消費方應用名 -->
<dubbo:application name="${dubbo.application.name}" owner="${dubbo.application.owner}" />
<dubbo:provider loadbalance="random" default="true"/>
<dubbo:registry protocol="zookeeper" address="${dubbo.zk.servers}" client="zkclient" group="${dubbo.zk.group}"/>
<dubbo:protocol name="${dubbo.application.protocol.name}" port="${dubbo.application.protocol.port}"/>
<!--<dubbo:monitor address="${dubbo.monitor.address}" />-->
<dubbo:consumer check="false" />

<dubbo:reference interface="com.jwfy.dubbo.product.ProductService" id="productService"  />

application.proerties 文件

# dubbo
dubbo.application.name=dubbo-consume
dubbo.application.owner=jwfy
dubbo.application.protocol.name=dubbo
dubbo.application.protocol.port=20880

dubbo.monitor.address=dubbo://127.0.0.1:20888
dubbo.zk.servers=127.0.0.1:2182
dubbo.zk.group=dubbo-consumer-demo
public class ConsumeBootstrap {

    private static final Logger logger = LoggerFactory.getLogger(ConsumeBootstrap.class);

    public static void runDubboConsume(){
        ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext(
                new String[]{ "spring-consume.xml" });

        ProductService productService = (ProductService)applicationContext.getBean("productService");
        
        System.out.println(productService.getStr());

        while (true){

        }
    }

    public static void main(String[] args){
        runDubboConsume();

    }

}

直接啟動,顯示連接拒絕錯誤

Exception in thread "main" com.alibaba.dubbo.rpc.RpcException: Forbid consumer 192.168.10.123 access service com.jwfy.dubbo.product.ProductService from registry 127.0.0.1:2182 use dubbo version 2.5.3, Please check registry access list (whitelist/blacklist).
    at com.alibaba.dubbo.registry.integration.RegistryDirectory.doList(RegistryDirectory.java:579)
    at com.alibaba.dubbo.rpc.cluster.directory.AbstractDirectory.list(AbstractDirectory.java:73)
    at com.alibaba.dubbo.rpc.cluster.support.AbstractClusterInvoker.list(AbstractClusterInvoker.java:260)
    at com.alibaba.dubbo.rpc.cluster.support.AbstractClusterInvoker.invoke(AbstractClusterInvoker.java:219)
    at com.alibaba.dubbo.rpc.cluster.support.wrapper.MockClusterInvoker.invoke(MockClusterInvoker.java:72)
    at com.alibaba.dubbo.rpc.proxy.InvokerInvocationHandler.invoke(InvokerInvocationHandler.java:52)
    at com.alibaba.dubbo.common.bytecode.proxy0.getStr(proxy0.java)
    at com.jwfy.dubbo.consume.ConsumeBootstrap.runDubboConsume(ConsumeBootstrap.java:22)
    at com.jwfy.dubbo.consume.ConsumeBootstrap.main(ConsumeBootstrap.java:30)

拒絕鏈接到遠程服務,這時候需要核對服務提供方以及服務調用方的配置是否不同

經過觀察發現是服務調用方的zk組寫錯了,調用方在使用不存在的zk注冊的時候,會被禁止掉,從而提示該錯誤

把application.proerties 中的dubbo.zk.group=dubbo-consumer-demo修改為dubbo.zk.group=dubbo-demo,再啟動,就恢復正常了,再看看dubbo-admin的顯示

image
image

4、參考鏈接

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • Dubbo是什么 Dubbo是Alibaba開源的分布式服務框架,它最大的特點是按照分層的方式來架構,使用這種方式...
    Coselding閱讀 17,271評論 3 196
  • 本文主要從應用的角度對ZooKeeper做了淺析,試圖闡明ZooKeeper是什么、主要應用場景有哪些、常用場景可...
    菜鳥小玄閱讀 3,440評論 0 6
  • 內容簡介此篇文章是介紹Dubbo以及它的簡單使用,會列舉運用spring boot + dubbo搭建項目運用du...
    Little_Dragon_閱讀 844評論 0 3
  • 要實現目標,有七個要素一時間,二具體,三要量化,四要操之在我,五要有挑戰性,六符合三贏的原則,七要是正向的...
    陽光心靈成長工作室閱讀 1,367評論 0 0
  • 刪除我所有的考研記錄,各種官網各種軟件各種論壇。It's over。 我所有需要做的都做了,就只剩下等成績。 今天...
    日月之約閱讀 629評論 4 2