一、简单的dubbo服务调用
提供者:
1.服务名称
2.注册中心
3.通信规则,通信协议-通信端口
4.暴露服务与服务实现
5.启动服务提供者应用
消费者:
1.服务名称
2.注册中心
3.声明需要调用的远程服务的接口
4.服务调用
zk注册中心:
Dubbo 支持 zkclient 和 curator 两种 Zookeeper 客户端实现。
1.从 2.2.0 版本开始缺省为 zkclient 实现,以提升 zookeeper 客户端的健状性。zkclient 是 Datameer 开源的一个 Zookeeper 客户端实现。
2.从 2.3.0 版本开始支持可选 curator 实现。Curator 是 Netflix 开源的一个 Zookeeper 客户端实现。
二、代码
1.服务提供者代码–工程结构
1.1 导入pom依赖,这里使用的是2.6.2,zk使用curator
<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.cjy.dubbo.demo</groupId>
<artifactId>t-provider</artifactId>
<version>0.0.1-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo</artifactId>
<version>2.6.2</version>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<version>2.12.0</version>
</dependency>
</dependencies>
</project>
1.2 实体类-dubbo通过rpc远程调用服务传输数据,所以必须实现序列化接口
public class Student implements Serializable{
private Integer id;
private String name;
public Student(Integer id, String name) {
super();
this.id = id;
this.name = name;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Student [id=" + id + ", name=" + name + "]";
}
}
1.3 服务实现
//对外提供的服务
public interface StudentService {
public List<Student> getAllStudent();
public Student getStudentById(Integer id);
}
//由springioc来管理
@Service
public class StudentServiceImpl implements StudentService{
@Autowired
StudentDao studentDao;
public List<Student> getAllStudent() {
// TODO Auto-generated method stub
return studentDao.getAllStudent();
}
public Student getStudentById(Integer id) {
// TODO Auto-generated method stub
return studentDao.getStudentById(id);
}
}
//假设数据库操作层
public interface StudentDao {
public List<Student> getAllStudent();
public Student getStudentById(Integer id);
}
@Component
public class StudentDaoImpl implements StudentDao{
public List<Student> getAllStudent() {
List<Student> list = new ArrayList<Student>();
list.add(new Student(1,"孙悟空"));
list.add(new Student(2,"唐僧"));
list.add(new Student(3,"猪八戒"));
list.add(new Student(4,"沙悟净"));
return list;
}
public Student getStudentById(Integer id) {
Map<Integer,Student> map = new HashMap<Integer,Student>();
map.put(1, new Student(1,"孙悟空"));
map.put(2,new Student(2,"唐僧"));
map.put(3, new Student(1,"孙悟空"));
return map.get(id);
}
}
1.4 配置xml文件将服务注册进zk
<?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"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd
http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
<!--1.扫包,ioc注入 -->
<context:component-scan base-package="com.cjy.dubbo"></context:component-scan>
<!--2.服务名称 -->
<dubbo:application name="t-studentserver" ></dubbo:application>
<!--3.注册中心 -->
<dubbo:registry protocol="zookeeper" address="49.51.233.xxx" port="2181"></dubbo:registry>
<!--4.协议 -->
<dubbo:protocol name="dubbo" port="20880"></dubbo:protocol>
<!--5.服务 ref:必须指定,这里调用的ioc中的实现,默认类名首字母小写,所以不用再手动实现 -->
<dubbo:service interface="com.cjy.dubbo.service.StudentService"
ref="studentServiceImpl"/>
<!--这里由于是springioc来管理了,所以不用再自己实现bean
<bean id="studentServiceImpl" class="com.cjy.dubbo.service.impl.StudentServiceImpl"></bean> -->
</beans>
1.5 启动服务
import java.io.IOException;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.alibaba.dubbo.container.Main;
public class MainApplication {
public static void main(String[] args) throws IOException{
//dubbo启动方式-- 注意这里使用的是dubbo中的类,xml文件默认必须是:/META-INF/spring/spring-dubbo.xml 这个格式才可以
Main.main(args);
//2.spring加载启动方式
// ClassPathXmlApplicationContext ioc = new ClassPathXmlApplicationContext("/META-INF/spring/spring-dubbo.xml");
// ioc.start();
// System.in.read();
}
}
//3. 启动成功:
//由第一种方式启动成功后,控制台会打印输出如下:
//[2018-12-15 12:42:51] Dubbo service server started!
//spring加载配置文件的启动方式,则不会输出,只要不报错就启动成功
1.6 注册中心查看
2.消费者实现
2.1工程结构图
2.2 pom依赖导入
<dependencies>
<!--需要导入提供者工程,使用其实体类,与服务提供接口类,这部分公共部分可以抽取出来单独为消费者与提供者来使用 -->
<dependency>
<groupId>com.cjy.dubbo.demo</groupId>
<artifactId>t-provider</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo</artifactId>
<version>2.6.2</version>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<version>2.12.0</version>
</dependency>
</dependencies>
2.3 服务调用
//本地服务接口
public interface DemoService {
public List<Student> getAllStudent() ;
public Student getStudentById(Integer id);
}
//本地服务实现,由ioc来管理--其实际调用的是提供者服务。
@Service
public class DemoServiceImpl implements DemoService{
//注入远程服务调用,实际调用的是服务提供者里面的服务
@Autowired
StudentService studentService;
public List<Student> getAllStudent() {
return studentService.getAllStudent();
}
public Student getStudentById(Integer id) {
return studentService.getStudentById(id);
}
}
2.4 消费者配置文件
<!--1.扫包,ioc注入 -->
<context:component-scan base-package="com.cjy.dubbo"></context:component-scan>
<!--2.消费者名称 -->
<dubbo:application name="t-consumer"></dubbo:application>
<!--3.注册中心 -->
<dubbo:registry address="zookeeper://49.51.233.xxx:2181"></dubbo:registry>
<!--4.服务调用,声明需要调用的远程服务的接口;生成远程服务代理 -->
<dubbo:reference interface="com.cjy.dubbo.service.StudentService" id="studentService"></dubbo:reference>
2.5 服务调用
public class MainTest {
public static void main(String[] args) throws IOException {
//1.加载配置文件
ApplicationContext atx = new ClassPathXmlApplicationContext("spirng-consumer.xml");
//2.获取本地服务接口--其底层实际调用提供者
DemoService bean = atx.getBean(DemoService.class);
//3.服务调用
List<Student> allStudent = bean.getAllStudent();
for (Student student : allStudent) {
System.out.println(student);
}
System.out.println("调用getStudentById");
Student studentById = bean.getStudentById(2);
System.out.println(studentById);
System.in.read();
}
}
/**
Student [id=1, name=孙悟空]
Student [id=2, name=唐僧]
Student [id=3, name=猪八戒]
Student [id=4, name=沙悟净]
调用getStudentById
Student [id=2, name=唐僧]
**/
总结:
由上述示例可以看出其提供者与消费者都需要实体类,服务接口,提供者用于实现,消费者用于调用,所以这部分代码可以单独抽取出来供消费者、提供者来调用。产生这样的原因主要是由于rpc调用过程。
三、模块提取示例
1.公共模块抽取–结构图
1.2
//实体类-用于数据传输
public class Student implements Serializable{
private Integer id;
private String name;
public Student(Integer id, String name) {
super();
this.id = id;
this.name = name;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Student [id=" + id + ", name=" + name + "]";
}
}
//服务接口-由提供者实现,消费者调用
public interface StudentService {
public List<Student> getAllStudent();
public Student getStudentById(Integer id);
}
2.修改提供者工程–公共部分可删除
2.1 导入公共模块
<!--依赖公共模块 -->
<dependency>
<groupId>com.cjy.dubbo.demo</groupId>
<artifactId>t-student-interface</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
2.2 修改服务接口与实体由,改由调用公共模块中的
2.3 注意配置文件中的服务接口,调用公共模块中的服务接口
3.修改消费者工程
3.1修改pom依赖-由依赖提供者改为依赖公共模块
<!--依赖公共模块 -->
<dependency>
<groupId>com.cjy.dubbo.demo</groupId>
<artifactId>t-student-interface</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
3.2 查看服务接口与实体类调用改为公共模块中的即可
四、注解版服务提供与消费
xml配置方式:指定其具体服务。
注解配置方式:扫描指定包下的,特定注解。
1.服务提供-注解
@Service //spring 注解
@com.alibaba.dubbo.config.annotation.Service //dubbo注解
public class StudentServiceImpl implements StudentService{
@Autowired
StudentDao studentDao;
public List<Student> getAllStudent() {
// TODO Auto-generated method stub
return studentDao.getAllStudent();
}
public Student getStudentById(Integer id) {
// TODO Auto-generated method stub
return studentDao.getStudentById(id);
}
}
``
1.2 修改xml使注解生效
```xml
<!--1.扫包,ioc注入 -->
<context:component-scan base-package="com.cjy.dubbo"></context:component-scan>
<!--2.服务 -->
<dubbo:application name="t-studentserver" ></dubbo:application>
<!--2.注册中心 -->
<dubbo:registry protocol="zookeeper" address="49.51.233.xxx" port="2181"></dubbo:registry>
<!--3.协议 -->
<dubbo:protocol name="dubbo" port="20880"></dubbo:protocol>
<!--4.服务 ref:必须指定,这里调用的ioc中的实现,默认类名首字母小写 -->
<!--4.1 服务提供方式:直接指定bean的方式-- -->
<!-- <dubbo:service interface="com.cjy.dubbo.service.StudentService"
ref="studentServiceImpl" id="studentService"/> -->
<!--4.2 注解提供方式: 直接扫描此包下的服务注解 -->
<dubbo:annotation package="com.cjy.dubbo.service.impl"/>
<!-- <bean id="studentServiceImpl" class="com.cjy.dubbo.service.impl.StudentServiceImpl"></bean> -->
- 消费注解版
2.1 修改服务调用方式@Service
public class DemoServiceImpl implements DemoService{
// @Autowired //由xml配置来完成
@Reference //dubbo注解
StudentService studentService;
public List<Student> getAllStudent() {
return studentService.getAllStudent();
}
public Student getStudentById(Integer id) {
return studentService.getStudentById(id);
}
}
2.2 修改xml配置文件
```xml
<!--1.扫包,ioc注入 -->
<context:component-scan base-package="com.cjy.dubbo"></context:component-scan>
<!--2.消费者名称 -->
<dubbo:application name="t-consumer"></dubbo:application>
<!--3.注册中心 -->
<dubbo:registry address="zookeeper://49.51.233.xxx:2181"></dubbo:registry>
<!--4.服务调用 -->
<!--4.1 xml配置版服务调用 -->
<!-- <dubbo:reference interface="com.cjy.dubbo.service.StudentService" id="studentService"></dubbo:reference> -->
<!-- 4.2.注解版服务调用==扫描 @Reference -->
<dubbo:annotation package="com.cjy.dubbo.impl"/>
demo链接:https://pan.baidu.com/s/1rP6N31jxwOcS9LiphDzlXw
提取码:nxgx