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)); } }