上一篇我们总结了分布式架构Dubbo+ZooKeeper的工作机制,今天我们来总结一些干货,其中我踩了很多坑都会在这篇里总结出来,以下SpringBoot+Dubbo+ZooKeeper的整合亲测可用,我会将这个Demo放到Github上,欢迎大家来提issue。
构建ZooKeeper环境
前面提到ZooKeeper是服务的注册中心,调用者需要在注册中心订阅服务提供者的信息,并在调用时根据注册中心提供的地址列表根据负载均衡机制进行,因此首先我们需要将ZooKeeper的环境部署出来,这边我们依然使用Docker的形式部署,值得一提的是,我在此总结的是非集群环境下的,如果有集群测试需求的同学可以等我后面的总结。
首先在docker hub中查找Zookeeper镜像。
docker search zookeeper
我们直接拉取最新版本的ZooKeeper部署。
docker pull zookeeper
然后查看镜像id并进行部署操作。
docker images
docker run --name zk -p 2181:2181 --restart always -d 镜像id
这样注册中心的环境就部署好了,由于我们使用的是单机测试,因此开放容器的2181端口即可。
创建SpringBoot项目
服务提供端(Provider)
我们首先创建一个空项目,然后在空项目中创建两个SpringBoot工程,然后引入web相关的依赖,以下的依赖经过测试均可使用。
<!-- dubbo的starter引入 -->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>2.7.3</version>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- 引入dubbo -->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo</artifactId>
<version>2.7.3</version>
</dependency>
<!-- 对zookeeper的底层api的一些封装 -->
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<version>4.0.1</version>
</dependency>
<!-- 封装了一些高级特性,如:Cache事件监听、选举、分布式锁、分布式Barrier -->
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
<version>2.8.0</version>
</dependency>
<!-- 引入zookeeper -->
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.4.13</version>
<type>pom</type>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- zookeeper连接客户端 -->
<dependency>
<groupId>com.101tec</groupId>
<artifactId>zkclient</artifactId>
<version>0.10</version>
</dependency>
接着我们需要在application.properties文件中配置dubbo的相关信息。
# Dubbo provider configuration
dubbo.application.name=provider-ticket
dubbo.registry.protocol=zookeeper
dubbo.registry.address=zookeeper://服务器地址:2181
dubbo.protocol.name=dubbo
dubbo.protocol.port=20880
# 扫描注解包通过该设置将服务注册到zookeeper
dubbo.scan.base-packages=com.ross.ticket.service.impl
其中我们需要将service的实现类即服务提供者发布到zookeeper中去,通过注册中心通知需要调用者该服务处在什么位置,下面我们来编写service。
package com.ross.ticket.service;
public interface TicketService {
public String getTicket();
}
package com.ross.ticket.service.impl;
import com.ross.ticket.service.TicketService;
import org.apache.dubbo.config.annotation.Service;
import org.springframework.stereotype.Component;
@Component
@Service//将服务发布出去,尤其要注意这边的@Service注解使用的是Dubbo的注解
public class TicketServiceImpl implements TicketService {
@Override
public String getTicket() {
return "《厉害了,我的国!》";
}
}
在服务提供端编写完成后,我们已经做到了将TicketService发布到注册中心zookeeper上,我们启动服务端的启动类,并且到ZooKeeper上查看是否已经将服务发布上。
我们通过docker命令进入部署好的zookeeper容器中进行查看。
docker exec -it 容器id bash
这时候会显示这样的效果,表示我们已经进入到容器中。
root@01cc7e5909e8:/apache-zookeeper-3.5.6-bin#
然后我们进入到bin目录下:
cd bin/
ls
查看bin目录下的执行脚本,选择执行zkCli.sh客户端脚本。
./zkCli.sh
会看到如下的效果:
我们使用如下的命令查看服务提供端是否已经注册上:
ls /dubbo
出现如下的信息表示服务已经注册成功:
[com.ross.ticket.service.TicketService]
至此,服务提供方已经开发完毕。
服务消费者(Consumer)
服务消费者通过Dubbo进行远程调用,配置如下,引入上面服务提供方相同的依赖,然后进行application.properties文件配置。
# Dubbo provider configuration
dubbo.application.name=consumer-user
dubbo.registry.protocol=zookeeper
dubbo.registry.address=zookeeper://129.204.207.233:2181
dubbo.protocol.name=dubbo
dubbo.protocol.port=20880
这边服务消费者无须将自身的服务发布出去,因为它自己就是消费者。
紧接着,需要在服务消费方建立和服务提供方相同的目录结构,并且创建service接口(无须实现类),具体目录结构如下。
并将相同的服务提供方接口写入。
package com.ross.ticket.service;
public interface TicketService {
public String getTicket();
}
然后在服务消费者的service实现类中进行调用。
package com.ross.user.service.impl;
import com.ross.ticket.service.TicketService;
import com.ross.user.service.UserService;
import org.apache.dubbo.config.annotation.Reference;
import org.springframework.stereotype.Service;
@Service("userService")
public class UserServiceImpl implements UserService {
@Reference//此处的@Reference注解会帮助我们根据注册中心提供的服务提供方地址进行调用
TicketService ticketService;
@Override
public void hello() {
String ticket = ticketService.getTicket();
System.out.println("买到"+ticket+"的票了");
}
}
我们调用UserService进行测试。
package com.ross.user;
import com.ross.user.service.UserService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class ConsumerUserApplicationTests {
@Autowired
private UserService userService;
@Test
void contextLoads() {
userService.hello();
}
}
结果:
买到《厉害了,我的国!》的票了
总结
以上是SpringBoot+Dubbo+ZooKeeper的整合测试,有疑问的同学可以到我的github中查看demo:https://github.com/jqdelove/SpringBoot-Dubbo-ZooKeeper