Dubbo是一款高性能、轻量级的开源Java RPC框架,它提供了三大核心能力:面向接口的远程方法调用,智能容错和负载均衡,以及服务自动注册和发现。
本博客只说明简单的远程方法调用。
准备工作
官网下载 zookeeper :
3.5 版本下载 apache-zookeeper-3.5.5-bin.tar.gz 压缩包,之前的版本下载不带 bin 的压缩包。
解压之后首先进入 conf 目录把 zoo_sample.cfg 改成 zoo.cfg,并把数据存储目录改成自己的目录,然后进入 bin 目录 cmd 运行 zkServer.cmd 启动 zookeeper
dataDir=../data
quickstart
公共接口工程
- 实体类 Student.java
public class Student implements Serializable {
private static final long serialVersionUID = 1L;
private String sid;
private String sname;
private int age;
public Student(String sid, String sname, int age) {
super();
this.sid = sid;
this.sname = sname;
this.age = age;
}
......
}
- 提供端接口
public interface ProviderService {
List<Student> getStuList(String sname);
}
- 消费端接口
public interface ConsumerService {
List<Student> useStuInfo(String sname);
}
服务提供工程
- pom.xml
<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.xiao</groupId>
<artifactId>dubboDemo-provider</artifactId>
<version>0.0.1-SNAPSHOT</version>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>com.xiao</groupId>
<artifactId>dubboDemo-interface</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.alibaba/dubbo -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo</artifactId>
<version>2.6.5</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.curator/curator-framework -->
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<version>4.1.0</version>
</dependency>
</dependencies>
</project>
- 服务提供接口实现类
public class ProviderServiceImpl implements ProviderService {
public List<Student> getStuList(String sname) {
Student stu1 = new Student("01", "张三", 20);
Student stu2 = new Student("05", "张三", 18);
return Arrays.asList(stu1, stu2);
}
}
- 提供端 dubbo 配置 provider.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"
xmlns="http://www.springframework.org/schema/beans"
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-getStuList"/>
<!-- 注册中心地址 -->
<dubbo:registry address="zookeeper://127.0.0.1:2181"/>
<!-- 用dubbo协议在20880端口暴露服务 -->
<dubbo:protocol name="dubbo" port="20880"/>
<!-- 声明需要暴露的服务 -->
<dubbo:service interface="com.xiao.service.ProviderService" ref="provService"/> <!-- 接口 -->
<bean id="provService" class="com.xiao.service.impl.ProviderServiceImpl"/> <!-- 实现 -->
</beans>
- 测试类
public class MainTest {
@SuppressWarnings("resource")
public static void main(String[] args) throws IOException {
ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("provider.xml");
ac.start();
System.in.read();
}
}
ac.start(); System.in.read(); 确保该服务不被关闭
运行该测试类即可把该服务注册到 zookeeper 注册中心,以供其他接口调用
服务消费工程
- pom 依赖同上
- 服务消费接口实现
@Service
public class ConsumerServiceImpl implements ConsumerService {
@Autowired
ProviderService providerService;
public List<Student> useStuInfo(String sname) {
List<Student> stuList = providerService.getStuList(sname);
System.err.println("------------------获取到 provider查询的学生信息----------------------");
System.err.println(stuList);
return stuList;
}
}
- 消费端 dubbo 配置 consumer.xml
<?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="consumer-service" />
<!-- 注册中心暴露发现服务地址 -->
<dubbo:registry address="zookeeper://127.0.0.1:2181" />
<!-- 生成远程服务代理,应用暴露的 provider 端接口 -->
<dubbo:reference id="proService" interface="com.xiao.service.ProviderService" />
</beans>
- 测试类
public class MainTest {
public static void main(String[] args) {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("consumer.xml");
context.start();
ProviderService proService = (ProviderService)context.getBean("proService"); // 获取远程服务代理
List<Student> stuList = proService.getStuList("张三"); // 执行远程方法
System.out.println("------------------获取到 provider查询的学生信息----------------------");
System.out.println(stuList); // 显示调用结果
}
}
这里的消费端接口和实现其实在本测试中都没有用到,当使用 IoC 注入方式测试时可以用到该接口与实现
先启动服务提供工程的测试类,把服务暴露到注册中心;再启动服务消费端的测试类,即可调用服务提供方的接口
dubbo与springboot整合
服务提供工程
- pom.xml
<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.xiao</groupId>
<artifactId>dubboBoot-provider</artifactId>
<version>0.0.1-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.4.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>com.xiao</groupId>
<artifactId>dubboDemo-interface</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<!-- Dubbo Spring Boot Starter -->
<dependency>
<groupId>com.alibaba.boot</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>0.2.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
- application.properties
server.port=8081
dubbo.application.name=dobbo-boot-provider
dubbo.registry.address=127.0.0.1:2181
dubbo.registry.protocol=zookeeper
dubbo.protocol.name=dubbo
dubbo.protocol.port=20880
- 服务提供类接口实现
import java.util.Arrays;
import java.util.List;
import org.springframework.stereotype.Component;
import com.alibaba.dubbo.config.annotation.Service;
import com.xiao.entity.Student;
import com.xiao.service.ProviderService;
@Service(timeout = 30000)
@Component
public class ProviderServiceImpl implements ProviderService {
public List<Student> getStuList(String sname) {
Student stu1 = new Student("01", "张三", 20);
Student stu2 = new Student("05", "张三", 18);
return Arrays.asList(stu1, stu2);
}
}
注意:该类的 @Service 注解是 dubbo 包里的
- 启动类加入 @EnableDubbo 注解,启动程序,即可把服务暴露到注册中心
服务消费工程
- pom.xml
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.xiao</groupId>
<artifactId>dubboDemo-interface</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<!-- Dubbo Spring Boot Starter -->
<dependency>
<groupId>com.alibaba.boot</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>0.2.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
- application.properties
server.port=8082
dubbo.application.name=dobbo-boot-consumer
dubbo.registry.address=zookeeper://127.0.0.1:2181
- 服务消费类接口实现
@Service
public class ConsumerServiceImpl implements ConsumerService {
@Reference(timeout = 30000)
ProviderService providerService;
public List<Student> useStuInfo(String sname) {
List<Student> stuList = providerService.getStuList(sname);
System.out.println("------------------调用provider方法完成----------------------");
return stuList;
}
}
该类的 @Service 注解是 spring 的,@Reference 是 dubbo 包里的,表示引用的是外部接口
- controller
@RestController
public class ConsumerController {
@Autowired
ConsumerService consumerService;
@RequestMapping("/getStus")
public List<Student> getStus(@RequestParam("sname") String sname) {
System.out.println("---------获取信息的学生姓名:" + sname);
List<Student> stuInfo = consumerService.useStuInfo(sname);
return stuInfo;
}
}
- 同样,在启动类加上 @EnableDubbo 注解,启动,在网页上发送请求,即可获取服务提供类暴露的方法