1. 程式人生 > >dubbo學習筆記(3):快速搭建

dubbo學習筆記(3):快速搭建

imp 阿裏巴巴 zkclient 80端口 spa gin zh-cn work 遠程服務調用

搭建一個簡單的dubbo服務

參考地址:

dubbo官網:http://dubbo.apache.org/zh-cn/docs/user/references/registry/zookeeper.html
博客:http://www.cnblogs.com/lighten/p/6828026.html

以上兩個教程經實踐發現都有部分謬誤,本教程做了一定更正

1.簡介

dubbo是一個分布式服務框架,由阿裏巴巴的工程師開發,致力於提供高性能和透明化的RPC遠程服務調用。可惜的是該項目在2012年之後就沒有再更新了,之後由當當基於dubbo開發了dubbox。這裏對dubbo的入門構建進行簡單的介紹。不涉及dubbo的運行機制,只是搭建過程,方便學習者快速構建項目,運行、熟悉該框架。

dubbo提供了兩種構建項目的方法:

  1. 通過Spring容器快速構建,其中還有註解的方式;
  2. 通過直接使用API(不推薦)。以下對其一一說明。

2.spring配置的形式

1.導入maven依賴

<!--如果引入的是2.6.2以下版本,xml文件頭引入的xsd地址會報錯-->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>dubbo</artifactId>
    <version>2.6.3</version>
    <exclusions>
        <exclusion>
            <!-- 排除傳遞spring依賴 -->
            <artifactId>spring</artifactId>
            <groupId>org.springframework</groupId>
        </exclusion>
    </exclusions>
</dependency>

<!--下面分別是兩種不同的zookeeper客戶端實現,選擇一種就好-->
<dependency>
     <groupId>com.101tec</groupId>
     <artifactId>zkclient</artifactId>
     <version>0.4</version>
 </dependency>

<dependency>
    <groupId>org.apache.curator</groupId>
    <artifactId>curator-framework</artifactId>
    <version>2.12.0</version>
</dependency>

<!--後期可能還會用到如下zookeeper客戶端jar包依賴,但是目前這個demo不引入也沒有問題-->
<dependency> 
    <groupId>org.apache.zookeeper</groupId>
    <artifactId>zookeeper</artifactId>
    <version>3.3.3</version> 
</dependency>

<!--spring配置方式,自然需要spring相關的依賴-->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>3.2.17.RELEASE</version>
    <exclusions>
        <exclusion>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
        </exclusion>
    </exclusions>
</dependency>
<dependency>
    <groupId>commons-logging</groupId>
    <artifactId>commons-logging</artifactId>
    <version>1.2</version>
</dependency>

<!--打印日誌相關-->
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-log4j12</artifactId>
    <version>1.6.4</version>
</dependency>

zkclient和curator

curator和zkclient分別為兩種不同的zookeeper實現,兩者使用的同時都需要開啟先zookeeper註冊中心的服務端。(關於如何下載配置並啟動zookeeper服務端,參考win10環境下搭建zookeeper偽集群)
在本項目中,它默認是使用了curator實現的,要改成zkclient實現,需要在<dubbo:registry address="zookeeper://127.0.0.1:2181/" client="zkclient" />標簽中加入 client="zkclient"

,並換成zkclient的依賴。
(在dubbo官網中稱2.5以上的dubbo版本默認使用zookeeper實現,但是實測結果卻相反)

2.定義服務接口(對提供方和調用方都可見)

package dubboXml;

public interface DemoService {
    String sayHello(String name);
}

3.服務提供方配置

  1. 實現服務接口

    package dubboXml;
    
    public class DemoServiceImpl implements DemoService{
        public String sayHello(String name) {
            return "Hello " + name;
        }
    }
  2. spring配置

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"
           xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
           http://dubbo.apache.org/schema/dubbo
           http://dubbo.apache.org/schema/dubbo/dubbo.xsd">
    
        <!-- 提供方應用信息,用於計算依賴關系 -->
        <dubbo:application name="hello-world-app"  />
    
        <!-- 使用zookeeper註冊中心暴露服務地址 -->
        <dubbo:registry address="zookeeper://127.0.0.1:2181" client="zkclient" />
    
        <!-- 用dubbo協議在20880端口暴露服務 -->
        <dubbo:protocol name="dubbo" port="20880" />
    
        <!-- 聲明需要暴露的服務接口 -->
        <dubbo:service interface="dubboXml.DemoService" ref="demoService" />
    
        <!-- 和本地bean一樣實現服務 -->
        <bean id="demoService" class="dubboXml.DemoServiceImpl" />
    </beans>
  3. 讀取配置,提供服務

    package dubboXml;
    
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    public class Provider {
        public static void main(String[] args) throws Exception {
            ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[] {"provider.xml"});
            context.start();
            System.in.read(); // 按任意鍵退出
        }
    }

4.服務調用方配置

  1. spring配置

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"
           xsi:schemaLocation="http://www.springframework.org/schema/beans
                   http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
                   http://dubbo.apache.org/schema/dubbo
                   http://dubbo.apache.org/schema/dubbo/dubbo.xsd">
    
        <!-- 消費方應用名,用於計算依賴關系,不是匹配條件,不要與提供方一樣 -->
        <dubbo:application name="consumer-of-helloworld-app"  />
    
        <!-- 使用zookeeper註冊中心暴露發現服務地址 -->
        <dubbo:registry address="zookeeper://127.0.0.1:2181" />
    
        <!-- 生成遠程服務代理,可以和本地bean一樣使用demoService -->
        <dubbo:reference id="demoService" interface="dubboXml.DemoService" />
    </beans>
  2. 讀取配置,調用服務

    package dubboXml;
    
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    public class Consumer {
        public static void main(String[] args) throws Exception {
            ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[] {"consumer.xml"});
            context.start();
            DemoService demoService = (DemoService)context.getBean("demoService"); // 獲取遠程服務代理
            String hello = demoService.sayHello("nihao"); // 執行遠程方法
            System.out.println( hello ); // 顯示調用結果
        }
    }

最終結果:

技術分享圖片

5.其他說明

  • 如果涉及傳輸對象,那麽被傳輸的對象類應該實現serializable接口。因為對象遠程傳輸是以二進制的形式進行的,那麽在傳輸之前需要實現序列化。
  • 我的demo地址:demoXml

我的目錄結構:

技術分享圖片

3.註解配置的方式

maven配置同上。

1.服務接口和傳輸對象

服務接口

package com.common.server;

import java.util.List;

public interface DemoService {

    public String greet(String name);
    public List<User> getUsers();

}

傳輸對象:實現序列化接口

package com.common.server;

import java.io.Serializable;

public class User implements Serializable {

    private static final long serialVersionUID = 1L;

    private String name;
    private int age;
    private String sex;

    public User(String name, int age, String sex) {
        this.name = name;
        this.age = age;
        this.sex = sex;
    }

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public String getSex() {
        return sex;
    }
    public void setSex(String sex) {
        this.sex = sex;
    }

    @Override
    public String toString() {
        return "User [name=" + name + ", age=" + age + ", sex=" + sex + "]";
    }
}

2.服務提供方

  1. 實現接口(註意加上相應註解)

    package com.provider;
    
    import com.alibaba.dubbo.config.annotation.Service;
    import com.common.server.DemoService;
    import com.common.server.User;
    
    import java.util.ArrayList;
    import java.util.List;
    
    /**
     * 實現類上打上service註解:註意,是dubbo的service註解
     */
    @Service
    public class DemoServiceImpl implements DemoService {
    
        @Override
        public String greet(String name) {
            return "Hello " + name;
        }
    
        @Override
        public List<User> getUsers() {
            List<User> list = new ArrayList<>();
    
            User user1 = new User("張三",10,"男");
            User user2 = new User("李四",11,"女");
            User user3 = new User("王五",12,"男");
    
            list.add(user1);
            list.add(user2);
            list.add(user3);
    
            return list;
        }
    
    }
    
  2. xml配置
    (與全xml配置服務的方式相比,這裏去掉了bean和<dubbo:service>,使用<dubbo:anotition>取代了,相當於自動掃描並暴露服務)

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
           xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://code.alibabatech.com/schema/dubbo
        http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
    
        <!-- 提供方應用信息,用於計算依賴關系 -->
        <dubbo:application name="provider"  />
    
        <!-- 使用zookeeper註冊中心暴露服務地址 -->
        <dubbo:registry address="zookeeper://127.0.0.1:2181" client="zkclient" />
        <!--<dubbo:registry address="N/A"/>-->
    
        <!-- 用dubbo協議在20880端口暴露服務 -->
        <dubbo:protocol name="dubbo" port="20880" />
    
        <!-- 註解實現,指向服務提供者實現類的包掃描-->
        <dubbo:annotation package="com.provider" />
    </beans>
  3. 開啟服務提供

    package com.provider;
    
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    import java.io.IOException;
    
    /**
     * 服務提供者
     */
    public class Provider {
    
        public static void main(String[] args) throws IOException {
            ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"provider.xml"});
            context.start();
            System.in.read();
        }
    }
    

3.服務調用方

  1. 類中註入並使用遠程服務代理(為什麽不在加載spring文件的類中註入?因為那是入口)

    package com.consumer;
    import com.alibaba.dubbo.config.annotation.Reference;
    import com.common.server.DemoService;
    import org.springframework.stereotype.Component;
    
    /**
     * 服務消費者:service是spring的註解
     */
    @Component("anotationConsumer")
    public class AnotationConsumer {
    
        /**
         * 遠程服務代理,可以和本地bean一樣使用demoService
         */
        @Reference(check = false)
        private DemoService demoService;
    
        public void print(){
            System.out.println(demoService.greet("張三"));
            System.out.println(demoService.getUsers());
        }
    }
    
  2. consumer.xml spring配置文件

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
           xmlns:context="http://www.springframework.org/schema/context"
           xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context-3.0.xsd
        http://code.alibabatech.com/schema/dubbo
        http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
    
        <dubbo:application name="consumer"/>
    
        <dubbo:registry address="zookeeper://127.0.0.1:2181" client="zkclient" />
    
        <!--指向服務調用者所在的包-->
        <dubbo:annotation package="com.consumer" />
    
        <!-- 配置spring註解包掃描 -->
        <context:component-scan base-package="com.consumer"></context:component-scan>
    
    </beans>
  3. 啟動服務

    package com.consumer;
    
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    public class Consumer {
    
        public static void main(String[] args) {
            ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"consumer.xml"});
            context.start();
    
            AnotationConsumer anotationConsumer = (AnotationConsumer) context.getBean("anotationConsumer");
            anotationConsumer.print();
        }
    }
    

調用結果:

技術分享圖片

4.附加信息

  • 無論是哪種配置方式,如果使用了註冊中心,那麽註冊和調用的時候必須先開啟註冊中心。
  • demo地址:dubboAnotation
  • 還有一種api調用的形式,由於不常用所以這裏沒有提供教程。如果有興趣可以查看參考帖。

dubbo學習筆記(3):快速搭建