Dubbo基础使用
概述:本文Dubbo采用全Spring配置方式,透明化介入应用,只需用Spring加载Dubbo的配置即可,注册中心使用zookeeper,编辑器采用idea。
一、安装配置zookeeper
1、在官网http://zookeeper.apache.org 下载zookeeper,我使用的版本是3.4.14;
2、解压zookeeper压缩包至你想安装的路径;
3、ZooKeeper的安装模式分为三种,分别为:单机模式(stand-alone)、集群模式和集群伪分布模式。ZooKeeper 单机模式的安装相对比较简单,如果第一次接触ZooKeeper的话,建议安装ZooKeeper单机模式或者集群伪分布模式。
安装单机模式
(1)到zookeeper安装目录中的bin目录下复制zoo_simple.cfg并粘贴至当前目录下,重命名为zoo.cfg;
(2)修改zoo.cfg配置






(3)cmd命令下进入安装目录下的bin目录,运行zkServer.cmd,如下图所示:


(4)可以在bin目录运行zkcli.cmd查看zookeeper节点信息


二、创建Dubbo项目
1、创建父项目(Maven项目)

2、在父项目中分别创建common(存放接口定义或bean)、provider(服务提供者)、consumer(服务消费者)的module子项目


3、分别修改pom文件
(1)父项目的pom文件,添加Dubbo和zookeeper等依赖
<?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">
<modelVersion>4.0.0</modelVersion>
<groupId>com.mysteel</groupId>
<artifactId>test</artifactId>
<version>1.0-SNAPSHOT</version>
<modules>
<module>common</module>
<module>consumer</module>
<module>provider</module>
</modules>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.3.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-core -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>5.2.3.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-beans -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>5.2.3.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-expression -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-expression</artifactId>
<version>5.2.3.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-aop -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>5.2.3.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.dubbo/dubbo -->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo</artifactId>
<version>2.7.3</version>
</dependency>
<!--增加zookeeper作为注册中心-->
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.3.3</version>
<type>pom</type>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.curator/curator-recipes -->
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
<version>2.12.0</version>
</dependency>
<!--使用curator客户端-->
<dependency>
<groupId>com.netflix.curator</groupId>
<artifactId>curator-framework</artifactId>
<version>1.1.10</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-api -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.24</version>
</dependency>
</dependencies>
</project> (2)分别在provider、consumer中添加common项目的依赖
<dependency>
<groupId>com.mysteel</groupId>
<artifactId>common</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency> 4、在common接口中定义接口、bean(需要实现Serializable接口)
public class Address implements Serializable {
private int id;
private int userId;
private String address;
public Address(int id, int userId, String address) {
this.id = id;
this.userId = userId;
this.address = address;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getUserId() {
return userId;
}
public void setUserId(int userId) {
this.userId = userId;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return "Address{" +
"id=" + id +
", userId=" + userId +
", address=‘" + address + ‘\‘‘ +
‘}‘;
}
}public class Person implements Serializable {
private int userId;
private String name;
private int age;
private List<Address> addresses;
public Person(int userId, String name, int age, List<Address> addresses) {
this.userId = userId;
this.name = name;
this.age = age;
this.addresses = addresses;
}
public int getUserId() {
return userId;
}
public void setUserId(int userId) {
this.userId = userId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public List<Address> getAddresses() {
return addresses;
}
public void setAddresses(List<Address> addresses) {
this.addresses = addresses;
}
@Override
public String toString() {
return "Person{" +
"userId=" + userId +
", name=‘" + name + ‘\‘‘ +
", age=" + age +
", addresses=" + addresses +
‘}‘;
}
}public interface UserService {
Person getUserAddressesByUserId(int userId);
}
5、在provider模块中实现接口,并暴露服务
实现接口
public class UserServiceImpl implements UserService {
public Person getUserAddressesByUserId(int userId) {
Person[] people = new Person[2];
Address address1 = new Address(1,1,"江西省吉安市吉州区XXXX");
Address address2 = new Address(2,1,"福建省厦门市思明区XXXX");
Address address3 = new Address(3,2,"江西省南昌市青山湖区XXXX");
List<Address> addressList1 = new ArrayList<Address>();
addressList1.add(address1);
addressList1.add(address2);
List<Address> addressList2 = new ArrayList<Address>();
addressList2.add(address3);
Person person1 = new Person(1,"张三",22,addressList1);
Person person2 = new Person(2,"李四",22,addressList2);
people[0] = person1;
people[1] = person2;
for (int i = 0;i < people.length;i++){
if (people[i].getUserId() == userId){
return people[i];
}
}
return null;
}
}
用Spring 声明暴露服务
<?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://dubbo.apache.org/schema/dubbo"
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="provider"/>
<!-- 使用zookeeper广播注册中心暴露服务地址 -->
<dubbo:registry address="zookeeper://127.0.0.1:2181" client="curator"/>
<!-- 用dubbo协议在2088端口暴露服务 -->
<dubbo:protocol name="dubbo" port="2088"/>
<!-- 声明需要暴露的服务接口 -->
<dubbo:service interface="com.mysteel.cominterface.UserService" ref="userService"/>
<!-- 和本地bean一样实现服务(暴露接口的实现) -->
<bean id="userService" class="com.mysteel.impl.UserServiceImpl"/>
</beans>
加载Spring配置,启动提供者(需要先启动zookeeper服务)
public class Provider {
public static void main(String[] args) throws IOException {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("classpath:provider.xml");
context.start();
System.in.read();
}
}
6、在consumer模块中订阅服务
通过 Spring 配置引用远程服务
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"
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="consumer"/>
<!-- 使用zookeeper广播注册中心暴露服务地址 -->
<dubbo:registry address="zookeeper://127.0.0.1:2181" client="curator"/>
<!-- 生成远程服务代理,可以和本地bean一样使用userService,声明需要调用的接口 interface填写common中接口的全路径 -->
<dubbo:reference interface="com.mysteel.cominterface.UserService" id="userService"/>
</beans> 加载Spring配置,并调用远程服务
public class Consumer {
public static void main(String[] args) {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("classpath:consumer.xml");
context.start();
//获取远程服务代理
UserService userService = (UserService) context.getBean("userService");
System.out.println(userService.getUserAddressesByUserId(1));
}
}
