基于docker的zookeeper+dubbo入门案例

环境

  • 虚拟机:Ubuntu 16.04

  • docker版本

    image-20210222150253654

创建容器myzookeeper并运行

步骤

docker run --name myzookeeper -d -p 2181:2181 zookeeper
  • docker run 创建一个新的容器并运行一个命令

  • --name 后接容器名称

  • -d 后台运行容器,并返回容器ID

  • -p 指定端口映射,格式为虚拟机端口:docker容器端口

  • 最后接镜像名称。

    • 直接写镜像名称默认当前使用镜像为zookeeper:latest,若docker中没有此镜像,则会自动下载。

      image-20210222151419587

      使用docker images查看镜像,会发现新增了一个latest的zookeeper。

      image-20210222151902929

    • 若需要指定版本,则可表示为zookeeper:版本号(tag)

      image-20210222151621851

查看容器运行情况

docker ps

image-20210222152319250

(这里换行有点难受...然后就是前面讲解了创建容器时带版本与不带版本的区别,所以这里有两个zookeeper容器在运行,觉得别扭的话可以使用docker stop 容器名/容器id关闭其中一个容器。)

查看zookeeper内部信息

这个步骤做拓展使用,下面介绍的内容仅仅在查看zookeeper信息,并未作任何配置。

进入zookeeper容器,并进入其bin目录

docker exec -it 容器名/容器id bash

image-20210224161642720

关于docker exec命令的使用,可以参考菜鸟教程:Docker exec命令

  1. 查看zookeeper当前的状态

    ./zkServer.sh status
    

    image-20210224161845392

    • Mode:standalone 单机模式
    • 在启动容器时,docker帮我们进行了zookeeper的启动,如果没有借用docker,在zookeeper安装完成后,可以使用./zkServer.sh start启动zookeeper。
  2. 启动zk客户端,查看信息。

    ./zkCli.sh
    

    image-20210224162641300

    • 与mysql、redis等软件一样,zookeeper也提供了客户端程序,用于对服务器上的数据进行操作。zkCli.sh是zookeeper为我们提供的客户端脚本程序。

    • 查看zookeeper的根节点信息

      ls /
      

      image-20210224163652535

      此处列出了/节点下的全部子节点信息,由于我们还没有创建任何节点,所以只有一个zookeeper节点(由zk自己默认创建)存在。

    • 后续使用dubbo-admin管理服务并完成demo发布服务后,这里会多出一个节点dubbo。继续深入节点,会发现zookeeper内部是以树状结构存储数据的,表现为/→zookeeper,dubbo→(dubbo节点)service1,servicec2.....→(service1节点)consumers、configurators、providers、routes

      image-20210224164432515

      (这里提供者的信息存在乱码...)

  3. 退出容器

    • ctrl+D:退出容器并停止容器的运行

    • ctrl+P+D:退出容器且不停止容器

Dubbo管理平台dubbo-admin的安装

dubbo-admin

图形化的服务管理页面(实际就是一个web项目,项目地址:apache/dubbo-admin),部署时需要指定注册中心地址,即可从注册中心中获取到所有的提供者 / 消费者进行配置管理。

前置条件

  • 我的dubbo-admin管控台的安装是基于zookeeper注册中心,安装前请确保已成功安装zookeeper。

步骤

创建并运行容器dubbo-admin

docker run --name dubbo-admin -d -p 9090:8080 chenchuxin/dubbo-admin:latest
  • 实验的时候我拉取apache/dubbo-admin一直失败,这里换用chenchuxin/dubbo-admin。关于apache/dubbo-admin的使用,可参考docker hub:apache/dubbo-admin

设置注册中心地址

  1. 进入容器内部

    docker exec -it dubbo-admin bash
    
    • 使用该命令进入容器内部

      image-20210224151334236

  2. 编辑dubbo-admin项目的dubbo.properties

    vi ROOT/WEB-INF/dubbo.properties
    
    • 将其中的dubbo.registry.address设置为自己的注册中心地址

      image-20210224151926408

      默认的地址为zookeeper://127.0.0.1:2181,虽然此时dubbo-admin与zookeeper的容器是位于同一台虚拟机中,ip地址为localhost理论上来说没有问题,但是经过验证,若不修改注册中心地址,dubbo-admin无法获取到注册中心中的信息。

  3. 重启容器

    docekr restart dubbo-admin
    

运行结果

容器运行状况

image-20210222165852117

访问dubbo-admin

image-20210222170907877

由于现在不存在任何消费者与提供者,所以列表中暂无信息。

补充说明

关于dubbo-admin的安装

如果不使用docker部署,在虚拟机或主机中直接部署的步骤大致为如下所示。

  1. dubbo2.5.x之前的版本

    1. 安装jdk。
    2. 安装tomcat。
    3. 下载dubbo-admin的war,并修改其配置文件application.properties中的dubbo.registry.address ,指定注册中心地址。
    4. 在tomcat上部署运行3中的项目。(期间可能存在端口冲突)
  2. dubbo2.6.0之后的版本

    在github上下载dubbo-admin的项目源码,使用maven将其打成jar包,通过java -jar xxx.jar命令启动

    (步骤可以参考github:apache/dubbo-amdin README_ZH.md 生产环境配置

关于注册中心地址的配置

关于chenchuxin/dubbo-admin的使用,我认为docker hub:chenchuxin/dubbo-admin中介绍的关于注册中心地址的配置是存在问题的。在前面的链接中写道,要设置zookeeper地址,只需要在创建容器时使用-e设置环境变量即可。但是这个环境变量是针对容器的,而zookeeper地址的配置是位于dubbo-admin项目中的配置文件中的,环境变量的设置并不会对配置文件中的值产生影响,所以前文在容器创建并运行后,我们需要进入容器内部通过修改dubbo-admin的配置文件来设置注册中心地址。

下文来验证一下docker run中的-e选项所设置的环境变量。

  1. 首先创建一个测试容器并设置环境变量:dubbo-admin-test

    docker run --name dubbo-admin-test -d -p 8888:8080 -e dubbo.registry.address=zookeeper://192.168.218.128:2181 chenchuxin/dubbo-admin:latest
    
  2. 查看容器环境变量

    docker exec dubbo-admin-test env|grep zookeeper
    
    • 使用上述命令于容器外查看容器环境变量。

      image-20210225161708815

      通过结果可知环境变量设置成功,此时打开dubbo-admin的配置文件,会发现dubbo.registry.address的值还是默认的zookeeper://127.0.0.1:2181,说明使用-e设置的环境变量对项目是不起作用的。

    • 如何查看容器的环境变量。

      如何查看docker的环境变量

      • 位于容器外

        • 可以使用docker exec 容器名/容器id env查看,结合管道和grep查看(docker exec 容器名/容器id env|grep xxx)可以避免在一堆文本中肉眼搜索。
        • docker inspect 容器名/容器id|grep xxx
        • docker exec -it 容器名/容器id env|grep xxx
      • 位于容器内

        • 容器的环境变量就是容器中1号进程的环境变量,可以利用命令cat /proc/1/environ 查看,同样,容器中其他进程的环境变量也可以通过cat /proc/{pid}/environ 查看

基于Spring的Demo

新建mavne项目DubboDemo

image-20210228103743799

新建Module

在DubboDemo下新建三个maven module:dubbo-interface、dubbo-provider、dubbo-consumer

image-20210228105620734

  • 注意此处parent可以选择DubboDemo。因为在dubbo-provider和dubbo-consumer中都需要导入zk客户端依赖和dubbo依赖,如果这里parent选择none,后面需要分别在providedr和consumer的pom.xml中导入依赖。如果选择DubboDemo,则只需要在DubboDemo的pom.xml中导入依赖,以DubboDemo为父项目的所有module就都导入了依赖。
  • idea中的Project相当于eclipse中的workspace,idea的Module相当于eclipse中的project

DubboDemo的pom.xml中导入zk客户端依赖和dubbo依赖

    <dependencies>
        <!-- zk客户端 -->
        <dependency>
            <groupId>com.github.sgroschupf</groupId>
            <artifactId>zkclient</artifactId>
            <version>0.1</version>
        </dependency>
        <!-- dubbo -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>dubbo</artifactId>
            <version>2.5.10</version>
        </dependency>
    </dependencies>

在dubbo-interface中编写IDemoService

public interface IDemoService {
    String helloDemo();
}

在dubbo-provider中实现IDemoService

  1. 在dubbo-provider的pom.xml中引入dubbo-interface

    <dependencies>
        <dependency>
            <groupId>cn.cyt</groupId>
            <artifactId>dubbo-interface</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
    </dependencies>
    
  2. 编写DemoServiceImpl

    public class DemoServiceImpl implements IDemoService {
        public String helloDemo() {
            return "Hello,Duboo!";
        }
    }
    
  3. 在resources中新建spring配置文件dubbo-provider并写入相关信息

    <?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="dubbo-provider"/>
        <!-- 指定注册中中心地址-->
        <dubbo:registry address="zookeeper://192.168.218.128:2181"/>
        <!-- 用dubbo协议在20890端口暴露服务 -->
        <dubbo:protocol name="dubbo" port="20890"/>
        <!-- 声明需要暴露的服务接口 -->
        <dubbo:service interface="cn.cyt.service.IDemoService" ref="demoService" />
        <!-- 声明Bean:demoService -->
        <bean id="demoService" class="cn.cyt.service.impl.DemoServiceImpl" />
    
    </beans>
    
    • 这里我采用xml配置,也可以采用注解配置。注解配置的使用可以参考dubbo:注解配置
  4. 新建Provider.java,加载spring配置文件发布服务

    public class Provider {
        public static void main(String[] args) throws IOException {
            ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
                    new String[]{"classpath:dubbo-provider.xml"});
            context.start();
            System.out.println("发布服务成功!");
            System.in.read(); // 按任意键退出
        }
    }
    
  5. 最后看一下dubbo-provider这个module的整体文件结构

    image-20210228112901045

在dubbo-consumer中调用IDemoService

  1. 引入dubbo-interface

  2. 在resources中新建spring配置文件dubbo-consumer并写入相关信息

    <?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="dubbo-consumer"/>
        <dubbo:registry address="zookeeper://192.168.218.128:2181"/>
        <!-- 引入服务 -->
        <dubbo:reference id="demoService" interface="cn.cyt.service.IDemoService"/>
    </beans>
    
  3. 新建Consumer.java,调用IDemoService

    public class Consumer {
        public static void main(String[] args) throws IOException {
            ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
                    new String[] {"classpath:dubbo-consumer.xml"});
            context.start();
            IDemoService demoService = (IDemoService)context.getBean("demoService"); // 获取远程服务代理对象
            String hello = demoService.helloDubbo(); 
            System.out.println( hello );
            System.in.read(); // 按任意键退出
        }
    
    }
    
    
  4. 最后看一下dubbo-consumer这个module的整体文件结构

    image-20210228113804524

运行

先运行dubbo-provider的Provider.java,再运行dubbo-consumer的Consumer.java,并在dubbo-admin中观察提供者消费者的情况。

image-20210228114707357

image-20210228114339023

image-20210228114449275

image-20210228114552322

image-20210228114611172

基于SpringBoot的Demo

新建消费者、提供者Module

在基于Spring的Demo中的DubboDemo项目中新建一个Spring Boot Module:dubbo-provider-springboot、dubbo-consumer-springboot

导入dubbo的springboot依赖

在dubbo-provider-springboot、dubbo-consumer-springboot中导入依赖

<dependency>
    <groupId>com.alibaba.boot</groupId>
    <artifactId>dubbo-spring-boot-starter</artifactId>
    <version>0.1.0</version>
</dependency>
  • 这里注意版本,我在使用0.2.1.RELEASE时会出现问题:java.lang.ClassNotFoundException: com.alibaba.dubbo.config.spring.context.properties.AbstractDubboConfigBinder

在dubbo-provider-springboot中实现IDemoService

  1. 在application.yml中写入dubbo相关信息

    # 应用服务 WEB 访问端口
    server:
      port: 8080
    dubbo:
      application:
        name: dubbo-provider-springboot
      protocol:
        port: 20880
      registry:
        protocol: zookeeper
        address: 192.168.218.128:2181
    
  2. 新建java类实现IDemoService

    package cn.cyt.providerspringboot.serviceimpl;
    
    import cn.cyt.service.IDemoService;
    import com.alibaba.dubbo.config.annotation.Service;
    import org.springframework.stereotype.Component;
    
    @Component
    @Service
    public class DemoServiceImpl implements IDemoService {
        @Override
        public String helloDemo() {
            return "Hello,springboot + dubbo!!!";
        }
    }
    
    • 需要注意这个文件的位置应该位于springboot启动类所在层级或下级,因为springboot的默认扫描位置为启动类所在包及其子包。
    • @Service用于声明服务,等于xml配置中的<dubbo:service>。注意这个@Service是来自dubbo而非spring。
    • @Component用于声明一个bean,等于xml配置中的<bean>
  3. 在启动类上使用@EnableDubbo开启dubbo服务

    @SpringBootApplication
    @EnableDubbo
    public class DubboProviderSpringbootApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(DubboProviderSpringbootApplication.class, args);
        }
    
    }
    

在dubbo-consumer-springboot中调用IDemoService

  1. 在application.yml中写入dubbo相关信息

    # 应用服务 WEB 访问端口
    server:
      port: 9090
    dubbo:
      application:
        name: dubbo-consumer-springboot
      registry:
        protocol: zookeeper
        address: 192.168.218.128:2181
    
    • 这里的server.port应该不同于dubbo-provider-springboot。因为届时消费者提供者需要同时启动,相同的话会产生端口冲突。
  2. 直接在test包下的测试类测试调用情况

    @SpringBootTest
    class DubboConsumerSpringbootApplicationTests {
    
        @Reference
        private IDemoService demoService;
    
        @Test
        void testDuboo() throws IOException {
            System.out.println(demoService.helloDemo());
            System.in.read();//使程序不会结束,便于后期在dubbo-admin中观察消费者情况
        }
    
    }
    
    • @Reference用于引入服务,等于xml配置中的<dubbo:reference>

运行

运行步骤同上一个Demo,同样可以在dubbo-admin中查看消费者与提供者信息。

image-20210228193046371

posted @ 2021-02-28 15:12  snail-coder  阅读(998)  评论(0)    收藏  举报