深入理解Dubbo-1.初识Dubbo
- 👏作者简介:大家好,我是爱吃芝士的土豆倪,24届校招生Java选手,很高兴认识大家
- 📕系列专栏:Spring源码、JUC源码、Kafka原理、分布式技术原理
- 🔥如果感觉博主的文章还不错的话,请👍三连支持👍一下博主哦
- 🍂博主正在努力完成2023计划中:源码溯源,一探究竟
- 📝联系方式:nhs19990716,加我进群,大家一起学习,一起进步,一起对抗互联网寒冬👀
文章目录
- Dubbo
- 为什么用Dubbo
- Dubbo架构
- Dubbo的使用
- 服务端
- 消费端
- Dubbo Spring Cloud
- 定义服务接口
- 实现服务
- 配置dubbo服务发布
- 构建服务消费者
- Dubbo Spring Boot
- 创建项目结构
- 添加jar包依赖
- 添加服务以及发布
- 编写服务引用代码
Dubbo
为什么用Dubbo
它是一个RPC框架,提供了对远程通信的支持。其本身是一个服务治理框架,能够提供服务的监控(如果我们的服务大规模集群后,我们需要一些服务来监控服务的调用链路,监控每个服务的吞吐量,这样就能够及时做到服务性能提升和响应)、服务注册发现(在服务与服务通信之间,去管理服务的一个组件)、服务的通信、服务容错(通信过程中怎么实现容错)、服务的负载均衡。
类似于京东的 jsf框架。
那为什么每个公司要开发自己的框架呢?是因为即便是开源的技术也好,它能够满足大部分的业务场景,但是对于每个公司来说可能存在一些定制化的需求,或者说做一些开源的支持,所以会有一些架构组去专门开发这样的组件,提供给我们这样使用。
Dubbo 最早是阿里内部分布式服务治理的框架,后面对外开源,然后后面的很多公司都沿着阿里的生态线去发展,在2014年dubbo就停止维护了,在2017年阿里重启了维护,在18年集成到了springcloud团队,集成是为了大家使用springcloud这套标准去提供服务治理这套完整的解决方案,让大家在使用这项技术的时候,成本更低,使用起来更加容易。
所以SpringCloud Alibaba 说的是基于阿里开源的技术,按照springcloud这套标准去进行集成,然后提供的一系列解决方法,包括 nacos、sentinel、rocketmq、dubbo等。
Dubbo架构
其提供了客户端和服务端在分布式情况下的通信,服务启动的时候,把服务地址注册到注册中心上,消费者监听注册中心上的地址的变化,发起调用,每次调用,会有监视的模块,去监控每次调用请求的耗时等等关系。
Dubbo的使用
服务端
dubbo-server-sample
----dubbo-server
public class LoginServiceImpl implements ILoginService{
@Override
public String login(String username, String password) {
//写业务逻辑
if(username.equals("admin")&&password.equals("admin")){
return "SUCCESS";
}
return "FAILED";
}
}
----dubbo-server-api
public interface ILoginService {
String login(String username,String password);
}
如果想让另一个进行也能访问到 login 方法,那么首先需要将 dubbo-server 上的服务发布出去。
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo</artifactId>
<version>2.7.8</version>
</dependency>
配置 application.xml
<dubbo:application name="dubbo-server"/> <!-- 声明服务对外的名字-->
<dubbo:protocol name="dubbo" port="20880"/> <!-- 表示当前要以什么协议发布出去 -->
<dubbo:registry address="N/A"/> <!-- 配置注册中心 当前配置为不需要注册到 注册中心-->
<dubbo:service interface="com.gupaoedu.dubbo.server.ILoginService" ref="loginService"/>
<bean id="loginService" class="com.gupaoedu.dubbo.server.LoginServiceImpl"/>
<!-- dubbo的发布,表示要将那个服务发布出去-->
启动
import org.apache.dubbo.container.Main;
public class App {
public static void main( String[] args ){
Main.main(args);
}
}
发布服务之后,会提供一个url地址
dubbo://192.168.1.104:20880/com.gupaoedu.dubbo.server.ILoginService
消费端
dubbo-client-sample
<dubbo:application name="dubbo-server"/>
<!--不需要注册到服务注册中心-->
<dubbo:registry address="N/A"/>
<dubbo:reference id="loginService"
interface="com.gupaoedu.dubbo.server.ILoginService"
url="dubbo://192.168.1.104:20880/com.gupaoedu.dubbo.server.ILoginService"/>
// 引入dubbo-server-api
public static void main( String[] args )
{
ILoginService loginService=null;
ApplicationContext context=new
ClassPathXmlApplicationContext
("classpath:META-INF/spring/application.xml");
loginService=context.getBean(ILoginService.class);
System.out.println(loginService.login("admin","admin"));
}
此时就能够完成一次通信了。
虽然上述案例跑通了,但是可以看到,必须在 dubbo:reference 里配置 了 url才能完成通信,实际上根据前面说的Dubbo的架构图来看,其生产者 和 消费者都是通过注册中心通信的。
<dubbo:registry address="zookeeper://192.168.216.128:1281" timeout="10000"/>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-dependencies-zookeeper</artifactId>
<version>2.7.8</version>
</dependency>
当生产者消费者都配置了注册中心的时候,此时消费者的dubbo:reference 就不需要配置url了,就能够完成通信了。
Dubbo Spring Cloud
创建一个项目
创建一个spring-cloud-dubbo-example的maven工程
分别添加三个模块
- spring-cloud-dubbo-sample-api
- spring-cloud-dubbo-sample-provider
- spring-cloud-dubbo-sample-consumer
其中后面两个模块都是spring boot的应用。
修改 spring-cloud-dubbo-sample-provider 这个模块中。
- 将dependencyManagement部分的依赖移动到parent pom.xml
- 修改spring-cloud-dubbo-sample-provider中的pom.xml,增加parent模块的依赖
<parent>
<groupId>com.gupaoedu.dubbo</groupId>
<artifactId>spring-cloud-dubbo-example</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
- 添加maven依赖
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-dubbo</artifactId>
</dependency>
<dependency>
<groupId>com.gupaoedu.dubbo</groupId>
<version>1.0-SNAPSHOT</version>
<artifactId>spring-cloud-dubbo-sample-api</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
定义服务接口
在spring-boot-dubbo-sample-api模块中,定义接口
public interface IHelloService {
String sayHello();
}
实现服务
在spring-boot-dubbo-sample-provider中,实现IHelloService接口
public class HelloServiceImpl implements IHelloService{
@Override
public String sayHello() {
return "Hello GuPao";
}
}
添加 @EnableDiscoveryClient 注解
@EnableDiscoveryClient
@SpringBootApplication
public class SpringCloudDubboSampleProviderApplication {
public static void main(String[] args) {
SpringApplication.run(SpringCloudDubboSampleProviderApplication.class,args);
}
}
配置dubbo服务发布
- 在服务实现类中添加 @Service 注解
@Service
public class HelloServiceImpl implements IHelloService{
@Override
public String sayHello() {
return "Hello GuPao";
}
}
- 配置dubbo提供方信息
# dubbo 服务扫描基础包路径
dubbo.scan.base-packages=com.gupaoedu.dubbo.springclouddubbosampleprovider
dubbo.protocol.id=dubbo
# Dubbo 服务暴露的协议配置,其中子属性 name 为协议名称,port 为协议端口( -1 表示自增端
口,从 20880 开始)
dubbo.protocol.name=dubbo
# 使用的是dubbo协议
dubbo.protocol.port=-1
spring.cloud.nacos.discovery.server-addr=192.168.216.128:8848
dubbo.scan.base-packages : 指定 Dubbo 服务实现类的扫描基准包
dubbo.protocol : Dubbo 服务暴露的协议配置,其中子属性 name 为协议名称, port 为协议端口( -1 表示自增端口,从 20880 开始)
spring.cloud.nacos.discovery : Nacos 服务发现与注册配置,其中子属性 server-addr指定 Nacos 服务器主机和端口
构建服务消费者
- 添加jar包依赖
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-dubbo</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-actuator</artifactId>
</dependency>
<dependency>
<groupId>com.gupaoedu.dubbo</groupId>
<version>1.0-SNAPSHOT</version>
<artifactId>spring-cloud-dubbo-sample-api</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
- 添加配置文件
spring.application.name=spring-cloud-dubbo-sample-consumer
dubbo.application.name=spring-cloud-dubbo-sample-consumer
dubbo.cloud.subscribed-services=spring-cloud-dubbo-sample-provider
spring.cloud.nacos.discovery.server-addr=192.168.216.128:8848
除应用名称 spring.application.name 存在差异外, spring-cloud-dubbo-client-sample 新增了属性 dubbo.cloud.subscribed-services 的设置。并且该值为服务提供方应用 “springcloud-dubbo-sample-provider”。它的主要作用是服务消费方订阅服务提供方的应用名称的列表,若需订阅多应用,使用 “,” 分割。
不推荐使用默认值为 “*”,它将订阅所有应用。
- 编写测试代码
@RestController
@EnableDiscoveryClient
@SpringBootApplication
public class SpringCloudDubboSampleConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(SpringCloudDubboSampleConsumerApplication.class,args);
}
@Reference
IHelloService helloService;
@GetMapping("/say")
public String say(){
return helloService.sayHello();
}
}
Dubbo Spring Boot
基于spring boot集成Dubbo方式
dubbo集成到spring boot中有一个好处,就是它可以继承spring boot本身的特性
- 自动装配(注解驱动、自动装配)
- production-ready(安全机制、健康检测、外部化配置)
创建项目结构
创建基础的项目结构
spring-boot-dubbo-example [maven]
- spring-boot-dubbo-sample-api [maven]
- spring-boot-dubbo-sample-provider [spring boot]
- spring-boot-dubbo-sample-consumerp [spring-boot]
添加jar包依赖
从2.7开始,dubbo的版本和dubbo-spring-boot的版本是保持一致的,所以大家不用再去担心版本的问题。
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>2.7.7</version>
</dependency>
<dependency>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-client</artifactId>
<version>1.2.1</version>
</dependency>
添加服务以及发布
@DubboService
public class SayHelloServiceImpl implements ISayHelloService{
@Override
public String sayHello() {
return "Hello GuPaoEdu.com";
}
}
spring.application.name=spring-boot-dubbo-sample-provider
dubbo.registry.address=nacos://192.168.216.128:8848
dubbo.scan.basepackages=com.gupaoedu.springboot.dubbo.springbootdubbosampleprovider.service
dubbo.protocol.name=dubbo
dubbo.protocol.port=-1
编写服务引用代码
添加jar包依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.gupaoedu.com</groupId>
<version>1.0-SNAPSHOT</version>
<artifactId>spring-boot-dubbo-sample-api</artifactId>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>2.7.7</version>
</dependency>
<dependency>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-client</artifactId>
<version>1.2.1</version>
</dependency>
添加web测试类
@DubboReference
ISayHelloService sayHelloService;
@GetMapping("/get")
public String get(){
return sayHelloService.sayHello();
}
dubbo.registry.address=nacos://192.168.216.128:8848