基于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

(这里换行有点难受...然后就是前面讲解了创建容器时带版本与不带版本的区别,所以这里有两个zookeeper容器在运行,觉得别扭的话可以使用docker stop 容器名/容器id关闭其中一个容器。)
查看zookeeper内部信息
这个步骤做拓展使用,下面介绍的内容仅仅在查看zookeeper信息,并未作任何配置。
进入zookeeper容器,并进入其bin目录
docker exec -it 容器名/容器id bash

关于docker exec命令的使用,可以参考菜鸟教程:Docker exec命令
-
查看zookeeper当前的状态
./zkServer.sh status![image-20210224161845392]()
- Mode:standalone 单机模式
- 在启动容器时,docker帮我们进行了zookeeper的启动,如果没有借用docker,在zookeeper安装完成后,可以使用./zkServer.sh start启动zookeeper。
-
启动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]()
(这里提供者的信息存在乱码...)
-
-
退出容器
-
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
设置注册中心地址
-
进入容器内部
docker exec -it dubbo-admin bash-
使用该命令进入容器内部
![image-20210224151334236]()
-
-
编辑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无法获取到注册中心中的信息。
-
-
重启容器
docekr restart dubbo-admin
运行结果
容器运行状况

访问dubbo-admin

由于现在不存在任何消费者与提供者,所以列表中暂无信息。
补充说明
关于dubbo-admin的安装
如果不使用docker部署,在虚拟机或主机中直接部署的步骤大致为如下所示。
-
dubbo2.5.x之前的版本
- 安装jdk。
- 安装tomcat。
- 下载dubbo-admin的war,并修改其配置文件application.properties中的dubbo.registry.address ,指定注册中心地址。
- 在tomcat上部署运行3中的项目。(期间可能存在端口冲突)
-
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选项所设置的环境变量。
-
首先创建一个测试容器并设置环境变量: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 -
查看容器环境变量
docker exec dubbo-admin-test env|grep zookeeper-
使用上述命令于容器外查看容器环境变量。
![image-20210225161708815]()
通过结果可知环境变量设置成功,此时打开dubbo-admin的配置文件,会发现dubbo.registry.address的值还是默认的zookeeper://127.0.0.1:2181,说明使用-e设置的环境变量对项目是不起作用的。
-
如何查看容器的环境变量。
-
位于容器外
- 可以使用
docker exec 容器名/容器id env查看,结合管道和grep查看(docker exec 容器名/容器id env|grep xxx)可以避免在一堆文本中肉眼搜索。 docker inspect 容器名/容器id|grep xxxdocker exec -it 容器名/容器id env|grep xxx
- 可以使用
-
位于容器内
- 容器的环境变量就是容器中1号进程的环境变量,可以利用命令
cat /proc/1/environ查看,同样,容器中其他进程的环境变量也可以通过cat /proc/{pid}/environ查看
- 容器的环境变量就是容器中1号进程的环境变量,可以利用命令
-
-
基于Spring的Demo
新建mavne项目DubboDemo

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

- 注意此处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
-
在dubbo-provider的pom.xml中引入dubbo-interface
<dependencies> <dependency> <groupId>cn.cyt</groupId> <artifactId>dubbo-interface</artifactId> <version>1.0-SNAPSHOT</version> </dependency> </dependencies> -
编写DemoServiceImpl
public class DemoServiceImpl implements IDemoService { public String helloDemo() { return "Hello,Duboo!"; } } -
在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:注解配置
-
新建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(); // 按任意键退出 } } -
最后看一下dubbo-provider这个module的整体文件结构
![image-20210228112901045]()
在dubbo-consumer中调用IDemoService
-
引入dubbo-interface
-
在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> -
新建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(); // 按任意键退出 } } -
最后看一下dubbo-consumer这个module的整体文件结构
![image-20210228113804524]()
运行
先运行dubbo-provider的Provider.java,再运行dubbo-consumer的Consumer.java,并在dubbo-admin中观察提供者消费者的情况。





基于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
-
在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 -
新建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>
-
在启动类上使用@EnableDubbo开启dubbo服务
@SpringBootApplication @EnableDubbo public class DubboProviderSpringbootApplication { public static void main(String[] args) { SpringApplication.run(DubboProviderSpringbootApplication.class, args); } }
在dubbo-consumer-springboot中调用IDemoService
-
在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。因为届时消费者提供者需要同时启动,相同的话会产生端口冲突。
-
直接在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>
- @Reference用于引入服务,等于xml配置中的
运行
运行步骤同上一个Demo,同样可以在dubbo-admin中查看消费者与提供者信息。















浙公网安备 33010602011771号