文章目录
1.1 什么是 Duboo?
Apache Dubbo (incubating) |ˈdʌbəʊ| 是一款高性能、轻量级的开源Java RPC 框架,它提供了三大核心能力:面向接口的远程方法调用,智能容错和负载均衡,以及服务自动注册和发现。简单来说 Dubbo 是一个分布式服务框架,致力于提供高性能和透明化的RPC远程服务调用方案,以及SOA服务治理方案。
1.2 Dubbo 架构
上述节点简单说明:
- Provider 暴露服务的服务提供方
- Consumer 调用远程服务的服务消费方
- Registry 服务注册与发现的注册中心
- Monitor 统计服务的调用次数和调用时间的监控中心
- Container 服务运行容器
调用关系说明:
- 服务容器负责启动,加载,运行服务提供者。
- 服务提供者在启动时,向注册中心注册自己提供的服务。
- 服务消费者在启动时,向注册中心订阅自己所需的服务。
- 注册中心返回服务提供者地址列表给消费者,如果有变更,注册中心将基于长连接推送变更数据给消费者。
- 服务消费者,从提供者地址列表中,基于软负载均衡算法,选一台提供者进行调用,如果调用失败,再选另一台调用。
- 服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心。
1.3 什么是 RPC?
RPC(Remote Procedure Call Protocol)远程过程调用协议。一个通俗的描述是:客户端在不知道调用细节的情况下,调用存在于远程计算机上的某个对象,就像调用本地应用程序中的对象一样。比较正式的描述是:一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议。
1.4 环境搭建
1.4.1 zookeeper搭建
我这里选择的是Docker Desktop
上面进行搭建zookeeper
,因为只是做个Demo,所以选择最简单的搭建方式。
想在Windows上搭建的可以参考:windows环境下安装zookeeper教程详解(单机版)
想在Linux上搭建的可以参考:linux安装zookeeper及使用
执行下面的Docker命令
docker run --privileged=true -d --name zookeeper --publish 2181:2181 -d zookeeper:latest
等待安装完成后,执行下面的命令,进入zookeeper容器内部
docker exec -it container-id /bin/bash
进入容器后,输入一下命令进行校验
bin/zkCli.sh -server 127.0.0.1:2181
1.4.2 项目结构
-
dubbo-demo:父项目
- interfaces:提供接口的子项目
- provider:服务的提供者
- consumer:服务的消费者
-
JDK11
1.4.3 interfaces项目
主要用于提供接口
pom.xml
<properties>
<java.version>11</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<spring-boot.version>2.3.7.RELEASE</spring-boot.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
Student.java
@Getter
@Setter
@Builder
@ToString
@EqualsAndHashCode
public class Student implements Serializable {
private Integer id;
private String studentName;
private String classRoom;
private String phoneNumber;
}
StudentService.java
package com.wifi.dubbo.interfaces.service;
import com.wifi.dubbo.interfaces.dto.Student;
public interface StudentService {
Student getStudentInfo(Integer id);
}
1.4.4 provider项目
实现接口,提供服务
pom.xml
<properties>
<java.version>11</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<spring-boot.version>2.3.7.RELEASE</spring-boot.version>
<spring-cloud-alibaba.version>2.2.2.RELEASE</spring-cloud-alibaba.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>2.7.8</version>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-dependencies-zookeeper</artifactId>
<version>2.7.8</version>
<type>pom</type>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.wifi.dubbo</groupId>
<artifactId>interfaces</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>${spring-cloud-alibaba.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
遇到的问题:
-
启动有警告
-
通过提示可以得知是:
logback-classic
和slf4-log4j12
冲突了 -
查看maven依赖
-
找到是
dubbo-dependencies-zookeeper
包中引入的slf4j-log4j12
-
从dependency中exclusions掉
<dependency> <groupId>org.apache.dubbo</groupId> <artifactId>dubbo-dependencies-zookeeper</artifactId> <version>2.7.8</version> <type>pom</type> <exclusions> <exclusion> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> </exclusion> </exclusions> </dependency>
-
StudentServiceImpl.java
package com.wifi.dubbo.provider.serviceImpl;
import com.wifi.dubbo.interfaces.dto.Student;
import com.wifi.dubbo.interfaces.service.StudentService;
import org.apache.dubbo.config.annotation.DubboService;
@DubboService
public class StudentServiceImpl implements StudentService {
@Override
public Student getStudentInfo(Integer id) {
return Student.builder()
.id(id)
.studentName("wifi")
.classRoom("Room one")
.phoneNumber("123456")
.build();
}
}
Alibaba和Apache的@Service都不建议使用了,这里换成Apache的@DubboService
application.properties
# 应用名称
spring.application.name=provider
#如果指定了spring应用名称,可以缺省dubbo的应用名称,这2个至少要配置1个。缺省dubbo的应用名称时默认值是spring的应用名称
#dubbo.application.name=user-service
# dubbo 协议
dubbo.protocol.id=dubbo
dubbo.protocol.name=dubbo
# dubbo 协议端口( -1 表示自增端口,从 20880 开始)
dubbo.protocol.port=-1
# Dubbo 消费端订阅服务端的应用名,多个服务提供者用逗号分隔
# 这里订阅"自己",会被忽略掉,请根据实际情况添加
#dubbo.cloud.subscribed-services=provider
# dubbo 服务扫描基准包
dubbo.scan.base-packages=com.wifi.dubbo.provider
# 应用服务 WEB 访问端口
server.port=8181
#注册中心地址
dubbo.registry.address=zookeeper://127.0.0.1:2181
#端口号可以写在address中,也可以单独写。实质是从address中获取的port是null,后面设置的port覆盖了null
#dubbo.registry.port=2181
#指定注册到zk上超时时间,ms
dubbo.registry.timeout=10000
1.4.5 consumer项目
pom.xml
<properties>
<java.version>11</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<spring-boot.version>2.3.7.RELEASE</spring-boot.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>2.7.8</version>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-dependencies-zookeeper</artifactId>
<version>2.7.8</version>
<type>pom</type>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.wifi.dubbo</groupId>
<artifactId>interfaces</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
这里引入的依赖与Provider是一样的
StudentConsumerServiceImpl.java
@Service
public class StudentConsumerServiceImpl {
@DubboReference
private StudentService studentService;
public Student getStudentInfo() {
return studentService.getStudentInfo(1);
}
}
- Alibaba和Apache的@Reference也不建议使用了,所以用Apache的@DubboReference
- 用Spring的@Service,将StudentConsumerServiceImpl注入到Bean容器中
application.properties
# 应用名称
spring.application.name=consumer
# 应用服务 WEB 访问端口
server.port=8282
#注册中心地址
dubbo.registry.address=zookeeper://127.0.0.1:2181
#dubbo.registry.port=2181
#协议、端口
dubbo.protocol.name=dubbo
dubbo.protocol.port=20880
#连接zk的超时时间,ms
dubbo.registry.timeout=10000
#启动应用时是否检查注册中心上有没有依赖的服务,默认true
#dubbo.consumer.check=false
1.4.6 测试
-
启动
Provider
项目 -
在
consumer
中写个测试package com.wifi.dubbo.consumer.service; import com.wifi.dubbo.interfaces.dto.Student; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import static org.junit.jupiter.api.Assertions.assertEquals; @SpringBootTest class StudentConsumerServiceImplTest { @Autowired private StudentConsumerServiceImpl studentConsumerService; @Test public void should_return_student_dto_when_getStudentInfo_given_id_is_1() { Student expectStudentResult = Student.builder() .id(1) .studentName("wifi") .classRoom("Room one") .phoneNumber("123456") .build(); Student actualStudentResult = studentConsumerService.getStudentInfo(); assertEquals(expectStudentResult, actualStudentResult); } }
-
结果
1.5 小结
因为只是想要体验/了解一下搭建SpringBoot + Dubbo 的过程,所以没有包含其他深入的知识点。
源代码地址
1.6 参考
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/77878.html