zoukankan      html  css  js  c++  java
  • dubbo实战之一:准备和初体验

    欢迎访问我的GitHub

    https://github.com/zq2599/blog_demos

    内容:所有原创文章分类汇总及配套源码,涉及Java、Docker、Kubernetes、DevOPS等;

    《dubbo实战》系列导航

    1. 准备和初体验
    2. 与SpringBoot集成
    3. 使用Zookeeper注册中心
    4. 管理控制台dubbo-admin

    关于dubbo

    1. Apache Dubbo (发音ˈdʌbəʊ) 是一款高性能、轻量级的开源Java RPC框架,它提供了三大核心能力:面向接口的远程方法调用,智能容错和负载均衡,以及服务自动注册和发现;
    2. 以下是来自官方的架构图:

    在这里插入图片描述

    版本简介和选定

    • 截止写此文时,Dubbo 社区主力维护的有 2.6.x 和 2.7.x 两大版本;
    • 2.6.x 主要以 bugfix 和少量 enhancements 为主,因此能完全保证稳定性;
    • 2.7.x 作为社区的主要开发版本,得到持续更新并增加了大量新 feature 和优化,同时也带来了一些稳定性挑战;
    • 综上所述,《dubbo实战》系列选择了社区推荐的2.7.6版本,这是2.7系列的稳定版;

    环境信息

    我这边用来编码的环境如下:

    1. 操作系统:macOS Catalina 10.15.5
    2. JDK:1.8.0_121
    3. Maven:33.3.9
    4. 开发工具:IntelliJ IDEA 2019.3.2 (Ultimate Edition)

    注意事项

    如果您是在windows环境运行代码,并且安装了VMWare,请您关闭对应的虚拟网卡,否则在广播模式(Multicast)时,consumer可能无法找到自己所需的服务;

    本篇概览

    • 作为《dubbo实战》系列的开篇,本文的主要内容如下:
    1. 创建整个《dubbo实战》系列的父工程;
    2. 创建整个《dubbo实战》系列的公共二方库;
    3. 初步体验dubbo框架,为了简单,本篇的实战暂不使用注册中心,而是服务提供方启动时广播自己的地址,再由消费方启动时订阅,并随时远程调用,调用逻辑如下图所示:

    在这里插入图片描述
    4. 先创建一个提供远程服务的子工程,名为helloxmldirectprovider,并运行起来;
    5. 再创建名为helloxmldirectconsumer的子工程,运行起来后,会调用helloxmldirectprovider提供的远程服务,将远端返回的内容打印出来;

    • 接下来开始编码

    源码下载

    1. 如果您不想编码,可以在GitHub下载所有源码,地址和链接信息如下表所示:
    名称 链接 备注
    项目主页 https://github.com/zq2599/blog_demos 该项目在GitHub上的主页
    git仓库地址(https) https://github.com/zq2599/blog_demos.git 该项目源码的仓库地址,https协议
    git仓库地址(ssh) git@github.com:zq2599/blog_demos.git 该项目源码的仓库地址,ssh协议
    1. 这个git项目中有多个文件夹,本章的应用在dubbopractice文件夹下,如下图红框所示:

    在这里插入图片描述
    3. dubbopractice是父子结构的工程,本篇的代码在helloxmldirectproviderhelloxmldirectconsumer这两个子工程中,如下图:

    在这里插入图片描述

    《dubbo实战》系列的父工程

    1. 为了方便管理《dubbo实战》系列的代码和依赖库版本的管理,这里创建名为dubbopractice的父maven工程,整个系列的后续源码都会作为它的子工程;
    2. dubbopractice的pom.xml内容如下:
    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modules>
            <module>practiceinterface</module>
            <module>helloxmldirectprovider</module>
            <module>helloxmldirectconsumer</module>
            <module>springbootzkprovider</module>
            <module>springbootzkconsumer</module>
            <module>springbootmulticastprovider</module>
            <module>springbootmulticastconsumer</module>
        </modules>
        <properties>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
            <maven.compiler.source>1.8</maven.compiler.source>
            <maven.compiler.target>1.8</maven.compiler.target>
            <java.version>1.8</java.version>
            <dubbo.version>2.7.6</dubbo.version>
            <springboot.version>2.3.3.RELEASE</springboot.version>
        </properties>
    
        <modelVersion>4.0.0</modelVersion>
        <groupId>com.bolingcavalry</groupId>
        <artifactId>dubbopractice</artifactId>
        <version>1.0-SNAPSHOT</version>
        <packaging>pom</packaging>
    
        <dependencyManagement>
            <dependencies>
                <dependency>
                    <groupId>org.apache.dubbo</groupId>
                    <artifactId>dubbo-dependencies-bom</artifactId>
                    <version>${dubbo.version}</version>
                    <type>pom</type>
                    <scope>import</scope>
                </dependency>
                <dependency>
                    <groupId>io.netty</groupId>
                    <artifactId>netty-all</artifactId>
                    <version>4.1.25.Final</version>
                </dependency>
                <!-- dubbo相关 -->
                <dependency>
                    <groupId>org.apache.dubbo</groupId>
                    <artifactId>dubbo</artifactId>
                    <version>${dubbo.version}</version>
                </dependency>
                <dependency>
                    <groupId>org.apache.dubbo</groupId>
                    <artifactId>dubbo-dependencies-zookeeper</artifactId>
                    <version>${dubbo.version}</version>
                    <type>pom</type>
                </dependency>
                <dependency>
                    <groupId>org.apache.dubbo</groupId>
                    <artifactId>dubbo-spring-boot-starter</artifactId>
                    <version>${dubbo.version}</version>
                </dependency>
                <dependency>
                    <groupId>org.apache.dubbo</groupId>
                    <artifactId>dubbo-registry-multicast</artifactId>
                    <version>${dubbo.version}</version>
                </dependency>
                <dependency>
                    <groupId>org.apache.zookeeper</groupId>
                    <artifactId>zookeeper</artifactId>
                    <version>3.4.7</version>
                </dependency>
                <dependency>
                    <groupId>com.github.sgroschupf</groupId>
                    <artifactId>zkclient</artifactId>
                    <version>0.1</version>
                </dependency>
                <dependency>
                    <groupId>org.projectlombok</groupId>
                    <artifactId>lombok</artifactId>
                    <version>1.16.16</version>
                </dependency>
                <dependency>
                    <groupId>com.fasterxml.jackson.core</groupId>
                    <artifactId>jackson-databind</artifactId>
                    <version>2.11.0</version>
                    <scope>compile</scope>
                </dependency>
                <dependency>
                    <groupId>com.fasterxml.jackson.datatype</groupId>
                    <artifactId>jackson-datatype-jdk8</artifactId>
                    <version>2.11.0</version>
                    <scope>compile</scope>
                </dependency>
                <dependency>
                    <groupId>org.slf4j</groupId>
                    <artifactId>slf4j-log4j12</artifactId>
                    <version>1.7.25</version>
                    <scope>compile</scope>
                </dependency>
                <dependency>
                    <groupId>commons-io</groupId>
                    <artifactId>commons-io</artifactId>
                    <version>2.7</version>
                    <scope>compile</scope>
                </dependency>
                <dependency>
                    <groupId>org.apache.commons</groupId>
                    <artifactId>commons-lang3</artifactId>
                    <version>3.10</version>
                    <scope>compile</scope>
                </dependency>
                <!-- swagger依赖 -->
                <dependency>
                    <groupId>io.springfox</groupId>
                    <artifactId>springfox-swagger2</artifactId>
                    <version>2.5.0</version>
                </dependency>
                <!-- swagger-ui -->
                <dependency>
                    <groupId>io.springfox</groupId>
                    <artifactId>springfox-swagger-ui</artifactId>
                    <version>2.5.0</version>
                </dependency>
            </dependencies>
        </dependencyManagement>
    </project>
    

    《dubbo实战》系列的二方库

    1. 涉及到多个工程之间的服务调用,因此要有个工程保存公用的数据结构、接口定义等,因此新建名为practiceinterface的子工程;
    2. practiceinterface工程的pom.xml内容如下,非常简单:
    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <parent>
            <artifactId>dubbopractice</artifactId>
            <groupId>com.bolingcavalry</groupId>
            <version>1.0-SNAPSHOT</version>
            <relativePath>../pom.xml</relativePath>
        </parent>
        <modelVersion>4.0.0</modelVersion>
        <groupId>com.bolingcavalry</groupId>
        <artifactId>practiceinterface</artifactId>
        <version>1.0-SNAPSHOT</version>
        <name>practiceinterface</name>
        <description>Beans of all app</description>
    </project>
    
    1. 此工程目前只有一个接口定义,后面多个子工程都会用到:
    package com.bolingcavalry.dubbopractice.service;
    
    public interface DemoService {
        String sayHello(String name);
    }
    

    编码(服务提供方)

    • 先创建提供服务的工程helloxmldirectprovider,一共要创建6个文件,创建顺序和功能如下表:
    创建顺序 文件名 作用
    1 pom.xml 工程的pom文件
    2 src/main/java/com/bolingcavalry/helloxmldirectprovider/ProviderApplication.java 启动类
    3 src/main/java/com/bolingcavalry/helloxmldirectprovider/service/impl/DemoServiceImpl.java 提供具体的服务
    4 src/main/resources/log4j.properties 日志配置文件
    5 src/main/resources/dubbo.properties dubbo配置文件
    6 src/main/resources/spring/dubbo-provider.xml spring的bean配置
    • 完整的文件位置如下图:

    在这里插入图片描述

    • 接下来逐个创建上述内容;
    1. 创建名为helloxmldirectprovider的子工程,pom.xml内容如下,可见刚才新建的二方库practiceinterface也被依赖了:
    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <parent>
            <artifactId>dubbopractice</artifactId>
            <groupId>com.bolingcavalry</groupId>
            <version>1.0-SNAPSHOT</version>
        </parent>
    
        <modelVersion>4.0.0</modelVersion>
        <groupId>com.bolingcavalry</groupId>
        <artifactId>helloxmldirectprovider</artifactId>
        <version>1.0-SNAPSHOT</version>
    
        <dependencies>
            <dependency>
                <groupId>com.bolingcavalry</groupId>
                <artifactId>practiceinterface</artifactId>
                <version>${project.version}</version>
            </dependency>
            <dependency>
                <groupId>org.apache.dubbo</groupId>
                <artifactId>dubbo</artifactId>
            </dependency>
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
            </dependency>
            <dependency>
                <groupId>org.slf4j</groupId>
                <artifactId>slf4j-log4j12</artifactId>
            </dependency>
        </dependencies>
    </project>
    
    1. 编写启动类ProviderApplication.java,可见就是个普通的后台程序,加载spring配置做初始化:
    package com.bolingcavalry.helloxmldirectprovider;
    
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    public class ProviderApplication {
        public static void main(String[] args) throws Exception {
            ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring/dubbo-provider.xml");
            context.start();
            System.in.read();
        }
    }
    
    1. 编写提供具体服务的业务实现类DemoServiceImpl.java,只是个简单的接口实现类而已:
    package com.bolingcavalry.helloxmldirectprovider.service.impl;
    
    import com.bolingcavalry.dubbopractice.service.DemoService;
    import lombok.extern.slf4j.Slf4j;
    import org.apache.dubbo.rpc.RpcContext;
    
    @Slf4j
    public class DemoServiceImpl implements DemoService {
        @Override
        public String sayHello(String name) {
            log.info("Hello " + name + ", request from consumer: " + RpcContext.getContext().getRemoteAddress());
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return "Hello " + name + ", response from provider: " + RpcContext.getContext().getLocalAddress();
        }
    }
    
    1. 日志配置文件log4j.properties,内容如下:
    ###set log levels###
    log4j.rootLogger=info, stdout
    ###output to the console###
    log4j.appender.stdout=org.apache.log4j.ConsoleAppender
    log4j.appender.stdout.Target=System.out
    log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
    log4j.appender.stdout.layout.ConversionPattern=[%d{dd/MM/yy HH:mm:ss:SSS z}] %t %5p %c{2}: %m%n
    
    1. 在同样位置创建dubbo配置文件dubbo.properties,内容很简单只有qos的端口设置,用于支持telnet命令:
    dubbo.application.qos.port=22222
    
    1. 在resources目录下新建文件夹spring,在此文件夹下创建文件dubbo-provider.xml,要重点关注的是dubbo:registry的配置,其address属性值为multicast://224.5.6.7:1234,代表当前服务通过广播让消费者获得自身信息:
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:dubbo="http://dubbo.apache.org/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://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd">
    
        <dubbo:application name="demo-provider"/>
        <!--广播模式-->
        <dubbo:registry address="multicast://224.5.6.7:1234" />
    
        <bean id="demoService" class="com.bolingcavalry.helloxmldirectprovider.service.impl.DemoServiceImpl"/>
        <dubbo:service interface="com.bolingcavalry.dubbopractice.service.DemoService" ref="demoService"/>
    </beans>
    
    1. 至此,服务提供方编码完成,直接在IDEA上运行ProviderApplication类即可启动服务,启动成功后的日志输出如下图:

    在这里插入图片描述

    编码(服务消费方)

    • 现在网络上已经有了服务,接下来创建一个消费该服务的工程helloxmldirectconsumer,一共要创建5个文件,创建顺序和功能如下表:
    创建顺序 文件名 作用
    1 pom.xml 工程的pom文件
    2 src/main/java/com/bolingcavalry/helloxmldirectconsumer/ConsumerApplication.java 启动、调用远端服务、再结束自身进程
    3 src/main/resources/log4j.properties 日志配置文件
    4 src/main/resources/dubbo.properties dubbo配置文件
    5 src/main/resources/spring/dubbo-consumer.xml spring的bean配置
    • 完整的文件位置如下图:

    在这里插入图片描述

    • 接下来逐个创建上述文件;
    1. 创建名为helloxmldirectconsumer的子工程,pom.xml内容如下,可见刚才新建的二方库practiceinterface也被依赖了:
    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <parent>
            <artifactId>dubbopractice</artifactId>
            <groupId>com.bolingcavalry</groupId>
            <version>1.0-SNAPSHOT</version>
        </parent>
    
        <modelVersion>4.0.0</modelVersion>
        <groupId>com.bolingcavalry</groupId>
        <artifactId>helloxmldirectconsumer</artifactId>
        <version>1.0-SNAPSHOT</version>
    
        <dependencies>
            <dependency>
                <groupId>com.bolingcavalry</groupId>
                <artifactId>practiceinterface</artifactId>
                <version>${project.version}</version>
            </dependency>
            <dependency>
                <groupId>org.apache.dubbo</groupId>
                <artifactId>dubbo</artifactId>
            </dependency>
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
            </dependency>
            <dependency>
                <groupId>org.slf4j</groupId>
                <artifactId>slf4j-log4j12</artifactId>
            </dependency>
        </dependencies>
    </project>
    
    1. 编写唯一的java文件ConsumerApplication.java,里面用了最简单的方法初始化spring环境,然后取得服务实例,执行过方法后结束进程:
    package com.bolingcavalry.helloxmldirectconsumer;
    
    import com.bolingcavalry.dubbopractice.service.DemoService;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    public class ConsumerApplication {
        public static void main(String[] args) throws Exception {
            ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring/dubbo-consumer.xml");
            context.start();
            DemoService demoService = context.getBean("demoService", DemoService.class);
            String hello = demoService.sayHello("world1");
            System.out.println("result: " + hello);
        }
    }
    
    1. 日志配置文件log4j.properties,内容如下:
    ###set log levels###
    log4j.rootLogger=info, stdout
    ###output to console###
    log4j.appender.stdout=org.apache.log4j.ConsoleAppender
    log4j.appender.stdout.Target=System.out
    log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
    log4j.appender.stdout.layout.ConversionPattern=[%d{dd/MM/yy HH:mm:ss:SSS z}] %t %5p %c{2}: %m%n
    
    1. 在同样位置创建dubbo配置文件dubbo.properties,内容很简单只有qos的端口设置,用于支持telnet命令,本例中是用不上的,因为远程调用后进程就会结束:
    dubbo.application.qos.port=33333
    
    1. 在resources目录下新建文件夹spring,在此文件夹下创建文件dubbo-consumer.xml,要重点关注的是dubbo:registry的配置,其address属性值为multicast://224.5.6.7:1234?unicast=false,代表当前服务通过广播让消费者获得自身信息,unicast=false表示多个消费者都能收到广播:
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:dubbo="http://dubbo.apache.org/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://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd">
    
        <dubbo:application name="demo-consumer"/>
        <dubbo:registry address="multicast://224.5.6.7:1234?unicast=false"/>
        <dubbo:reference id="demoService" check="false" interface="com.bolingcavalry.dubbopractice.service.DemoService" timeout="2000"/>
    </beans>
    
    1. 上面的dubbo-consumer.xml中还有一处要注意,就是dubbo:referencetimeout属性,这是远程调用的超时时间,此处设置为2秒,要注意的是前面helloxmldirectprovider提供的服务延时了1秒才返回,所以这里设置不能低于1秒;
    2. 至此,服务消费方编码完成,直接在IDEA上运行ConsumerApplication类即可启动,如下图,红框中就是远程调用helloxmldirectprovider服务返回的内容:

    在这里插入图片描述

    • 至此,《dubbo实战》系列的准备和初体验都完成了,接下来的章节,咱们会通过更多实战来学习这个优秀的框架;

    你不孤单,欣宸原创一路相伴

    1. Java系列
    2. Spring系列
    3. Docker系列
    4. kubernetes系列
    5. 数据库+中间件系列
    6. DevOps系列

    欢迎关注公众号:程序员欣宸

    微信搜索「程序员欣宸」,我是欣宸,期待与您一同畅游Java世界...
    https://github.com/zq2599/blog_demos

  • 相关阅读:
    引擎设计跟踪(一)
    Gamebyro 加入CEGUI
    开播庆祝
    引擎设计跟踪(八) Mile stone 2 准备中
    引擎设计跟踪(六)
    编辑器框架的思考
    地形法线贴图的优化
    引擎设计跟踪(五)
    引擎设计跟踪(九.2) 3DS MAX 导出插件 继续
    引擎设计跟踪(三)
  • 原文地址:https://www.cnblogs.com/bolingcavalry/p/14478153.html
Copyright © 2011-2022 走看看