阿里 RPC 框架 DUBBO 初體驗


最近研究了一下阿里開源的分布式RPC框架dubbo,樓主寫了一個 demo,體驗了一下dubbo的功能。

快速開始

實際上,dubbo的官方文檔已經提供了如何使用這個RPC框架example代碼,基於 Netty 的長連接。樓主看這個框架主要是為了在微服務,service mesh大火的今天做一些技術儲備以及了解一下分布式 RPC 框架的設計。

當然即便是寫一個dubbo的demo也不能隨便寫寫就好了,要認真對待說不定哪一天可以派上用場呢,下面是樓主寫的代碼的目錄結構:
dubboCode圖

下面我來一一說明一下每個model的作用,

  1. micro-service-dubbo-common是通用工具模塊其他的model都需要依賴它 。
  2. micro-service-dubbo-dal是整個項目的dao模塊,有關數據庫操作的相關代碼都放在這里。
  3. micro-service-dubbo-interface 是通用接口模塊,專門用來聲明接口,被consumer與provider同時依賴,這么做是為了項目的可拆分與分布式部署。
  4. micro-service-dubbo-model是公用的實體類模塊,不限於數據庫對應的model,也可以放DTO,VO等。
  5. micro-service-dubbo-provider項目的服務提供者。
  6. micro-service-dubbo-web 項目的消費者,也是直接跟前端交互的controller層。

另外需要在pom文件中添加相關依賴

<!--dubbo-->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>dubbo</artifactId>
    <version>${dubbo.version}</version>
</dependency>

<dependency>
    <groupId>com.101tec</groupId>
    <artifactId>zkclient</artifactId>
    <version>${zkclient_version}</version>
</dependency>

<dependency>
    <groupId>org.apache.zookeeper</groupId>
    <artifactId>zookeeper</artifactId>
    <version>${zookeeper_version}</version>
</dependency>

<dependency>
    <groupId>org.apache.curator</groupId>
    <artifactId>curator-framework</artifactId>
    <version>${curator_version}</version>
</dependency>

接口創建

既然是 RPC 服務,那就需要一個接口,再有一個實現類。在這里的接口定義是在我們的micro-service-dubbo-interface,具體實現是在provider這里創建,在樓主的項目中就是在micro-service-dubbo-provider中創建DemoService 的實現。

public interface DemoService {
    String sayHello(String name);

    public List getUsers();
}
@Service("demoService")
public class DemoServiceImpl implements DemoService {

    @Override
    public String sayHello(String name) {
        System.out.println("[" + new SimpleDateFormat("HH:mm:ss").format(new Date()) + "] Hello " + name + ", request from consumer: " + RpcContext
                .getContext().getRemoteAddress());
        return "Hello " + name + ", response from provider: " + RpcContext.getContext().getLocalAddress();
    }

    @Override
    public List getUsers() {
        List list = new ArrayList();
        User u1 = new User();
        u1.setName("hejingyuan");
        u1.setAge(20);
        u1.setSex("f");

        User u2 = new User();
        u2.setName("xvshu");
        u2.setAge(21);
        u2.setSex("m");


        list.add(u1);
        list.add(u2);

        return list;
    }
}

然后consumer的 pom.xml 添加對這個接口的依賴,在這里的接口定義是在我們的consumer就是micro-service-dubbo-web

<dependency>
  <groupId>com.whforever</groupId>
    <artifactId>micro-service-dubbo-provider</artifactId>
    <version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
    <groupId>com.whforever</groupId>
    <artifactId>micro-service-dubbo-interface</artifactId>
    <version>1.0-SNAPSHOT</version>
</dependency>

有了接口,就需要配置一下。

接口配置

首先在提供方這里發布接口。創建一個 xml 文件,名為:dubbo-provider.xml

文件內容:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
       xmlns="http://www.springframework.org/schema/beans"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
       http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd">

    <!-- provider's application name, used for tracing dependency relationship -->
    <dubbo:application name="demo-provider"/>

    <!-- use multicast registry center to export service -->
    <dubbo:registry protocol="zookeeper" address="127.0.0.1:2181" />

    <!-- use dubbo protocol to export service on port 20880 -->
    <dubbo:protocol name="dubbo" port="20880"/>

    <!-- service implementation, as same as regular local bean -->
    <bean id="demoProviderService" class="com.whforever.service.impl.DemoServiceImpl"/>

    <!-- declare the service interface to be exported -->
    <dubbo:service interface="com.whforever.service.DemoService" ref="demoProviderService"/>

</beans>

很簡單,發布了一個接口,類似 Spring 的一個 bean。

同樣的,在consumer即micro-service-dubbo-web的 resource 文件下,也創建一個dubbo-consumer.xml文件。內容稍有不同。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
       xmlns="http://www.springframework.org/schema/beans"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
       http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd">

    <!-- consumer's application name, used for tracing dependency relationship (not a matching criterion),
    don't set it same as provider -->
    <dubbo:application name="demo-consumer"/>

    <!-- use multicast registry center to discover service -->
    <!--<dubbo:registry address="multicast://224.5.6.7:1234"/>-->
    <dubbo:registry protocol="zookeeper" address="127.0.0.1:2181" />

    <!-- generate proxy for the remote service, then demoService can be used in the same way as the
    local regular interface -->
    <dubbo:reference id="demoConsumerService" check="false" interface="com.whforever.service.DemoService"/>

</beans>

從上面可以看出這兩個文件的注冊發現協議是zookeeper,因此在服務啟動之前需要啟動zookeeper,具體移步Zookeeper 注冊中心安裝啟動

准備測試

測試之前還要做點點工作。

在啟動provider事需要一部分引導程序,請看如下代碼:

public class ProviderMain {
    public static void main(String[] args) throws IOException {
        System.setProperty("java.net.preferIPv4Stack", "true");
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("dubbo-provider.xml");
        context.start();

        System.in.read(); // press any key to exit
    }
}

consumer代碼


@Controller
@RequestMapping("/")
public class IndexController {

    @Autowired
    DemoService demoService;

    @RequestMapping("/echo")
    @ResponseBody
    public String echo() {
        System.out.println(">>>>>>echo");
        return JSON.toJSONString(demoService.getUsers());
    }
}

運行

先運行provider:

[06/06/18 11:56:29:029 CST] main  INFO config.AbstractConfig:  [DUBBO] The service ready on spring started. service: com.whforever.service.DemoService, dubbo version: 2.6.1, current host: 192.168.1.120
[06/06/18 11:56:30:030 CST] main  INFO config.AbstractConfig:  [DUBBO] Export dubbo service com.whforever.service.DemoService to local registry, dubbo version: 2.6.1, current host: 192.168.1.120
[06/06/18 11:56:30:030 CST] main  INFO config.AbstractConfig:  [DUBBO] Export dubbo service com.whforever.service.DemoService to url dubbo://192.168.1.120:20880/com.whforever.service.DemoService?anyhost=true&application=demo-provider&bind.ip=192.168.1.120&bind.port=20880&dubbo=2.6.1&generic=false&interface=com.whforever.service.DemoService&methods=sayHello,getUsers&pid=13992&side=provider&timestamp=1528300589682, dubbo version: 2.6.1, current host: 192.168.1.120
[06/06/18 11:56:30:030 CST] main  INFO config.AbstractConfig:  [DUBBO] Register dubbo service com.whforever.service.DemoService url dubbo://192.168.1.120:20880/com.whforever.service.DemoService?anyhost=true&application=demo-provider&bind.ip=192.168.1.120&bind.port=20880&dubbo=2.6.1&generic=false&interface=com.whforever.service.DemoService&methods=sayHello,getUsers&pid=13992&side=provider&timestamp=1528300589682 to registry registry://127.0.0.1:2181/com.alibaba.dubbo.registry.RegistryService?application=demo-provider&dubbo=2.6.1&pid=13992&registry=zookeeper&timestamp=1528300589673, dubbo version: 2.6.1, current host: 192.168.1.120
[06/06/18 11:56:30:030 CST] main  INFO transport.AbstractServer:  [DUBBO] Start NettyServer bind /0.0.0.0:20880, export /192.168.1.120:20880, dubbo version: 2.6.1, current host: 192.168.1.120

再運行sonsumer:

consumer圖

通過查看dubbo監控中心,可以看到如下所示的情況,具體dubbo監控中心如何安裝部署請移步Simple 監控中心安裝

dubboAdmin圖

小結

對於dubbo聽其大名已久,直到最近才動手寫了一些demo,總體來看上手還是比較簡單,官方也提供了比較詳細的文檔,社區也比較活躍。關於本篇博客中的代碼,樓主已經放到了github,該興趣的小伙伴,請移步Dubbo初體驗Demo模板代碼

號外

樓主造了一個輪子,LIGHTCONF 是一個基於Netty實現的一個配置管理平台,其核心設計目標是“為業務提供統一的配置管理服務”,可以做到開箱即用。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM