Dubbo基础理解

举报
dfsafdfas 发表于 2021/02/04 23:29:30 2021/02/04
【摘要】 Dubbo原理什么是RPCDubbo框架基本使用基本底层原理什么是RPC维基百科定义:远程过程调用(英语:Remote Procedure Call,缩写为 RPC)是一个计算机通信协议。该协议允许运行于一台计算机的程序调用另一个地址空间(通常为一个开放网络的一台计算机)的子程序,而程序员就像调用本地程序一样,无需额外地为这个交互作用编程(无需关注细节)。RPC是一种服务器-客户端(Clie...


什么是RPC

维基百科定义:

远程过程调用(英语:Remote Procedure Call,缩写为 RPC)是一个计算机通信协议。该协议允许运行于一台计算机的程序调用另一个地址空间(通常为一个开放网络的一台计算机)的子程序,而程序员就像调用本地程序一样,无需额外地为这个交互作用编程(无需关注细节)。RPC是一种服务器-客户端(Client/Server)模式,经典实现是一个通过发送请求-接受回应进行信息交互的系统。如果涉及的软件采用面向对象编程,那么远程过程调用亦可称作远程调用或远程方法调用。

RPC协议:只是定义数据传输格式和传输方式,是一种应用层协议。
传输方式:有基于HTTP传输数据的RPC Over HTTP,也有基于TCP的RPC Over TCP等。
数据格式:双方协商定义,一般包括以下几点:
1、类名
2、方法名
3、参数类型(用来确定具体执行的方法,有方法重载)
4、参数值
RPC远程调用

Dubbo框架

dubbo是一种高性能、轻量级的开源Java RPC框架(最新官网称为服务框架),支持多种协议,默认使用dubbo协议,也可以使用HTTP协议等。

  1. 使用dubbo协议时,传输方式使用Netty;
  2. 使用HTTP协议时,传输方式使用Tomcat;

基本使用

Dubbo实现主要包括:服务提供者(provide)、服务消费者(Comsumer)、注册中心、监控中心组成
服务提供者
1、定义服务接口、提供接口实现类

// 接口(对外暴露的服务)
public interface DemoService {
    String sayHello(String name);
}
// 接口实现类
public class DemoServiceImpl implements DemoService {
    public String sayHello(String name) {
        return "Hello " + name;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

2、配置对外暴露服务(dubbo-demo-provide.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="demo-provide"  />
 
    <!-- 使用zookeeper作为注册中心,暴露服务 -->
    <dubbo:registry address="zookeeper://127.0.0.1:2181" />
 
    <!-- 使用dubbo协议(可使用多种协议如:HTTP、rest),暴露端口为20880 server=Netty 指定传输方式-->
    <!-- 针对整个应用,也可以针对服务指定协议 -->
    <dubbo:protocol name="dubbo" port="20880" />
 
    <!-- 声明需要暴露的服务接口 interface:接口名字(也是服务名字) ref:接口对应的实现类 -->
    <dubbo:service interface="org.apache.dubbo.demo.DemoService" ref="demoService" />
 
    <!-- 和本地bean一样实现服务,一般bean不在这配置,使用注解注入spring容器 -->
    <bean id="demoService" class="org.apache.dubbo.demo.provider.DemoServiceImpl" />
</beans>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

3、provide启动类

@SpringBootApplication
public class ProviderApplication {
    public static void main(String[] args) {
        SpringApplication.run(ProviderApplication.class, args);
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

服务消费者
1、消费者配置(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="demo-consumer"  />
 
    <!-- 使用mzookeeper注册中心发现暴露的服务地址 -->
    <dubbo:registry address="zookeeper://127.0.0.1:2181" />
 
    <!-- 生成远程服务代理,引入名字为org.apache.dubbo.demo.DemoService的服务,对应到本地的名字为demoService-->
    <!-- 在Spring容器中可以通过demoService拿到这个服务-->
    <dubbo:reference id="demoService" interface="org.apache.dubbo.demo.DemoService" />
</beans>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

2、Consumer 启动类

@SpringBootApplication
public class ConsumerApplication{
    public static void main(String[] args) throws Exception {
       SpringApplication.run(ConsumerApplication.class, args);
        DemoService demoService = (DemoService)context.getBean("demoService"); // 获取远程服务代理
        String hello = demoService.sayHello("world"); // 执行远程方法
        System.out.println( hello ); // 显示调用结果
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

基本底层原理

基本原理

Dubbo流程(粗略思路)
1、服务提供者提供接口、接口实现类(通过版本号区分多个实现类),对外暴露服务,通过共享注册中心注册服务(一般用zookeeper/redis)。
为什么要使用共享注册中心
由于服务消费者和服务提供者是分别启动两个JVM(两个进程),所以需要使用共享注册中心。注册服务形式-服务名:List
2、启动Tomcat容器或Netty服务器
需要HTTP/Netty客户端,用来接收请求,需要HTTP/Netty服务端用来处理请求。
3、服务消费者读取用户配置(共享注册中心注册的服务)
服务路径每次从共享注册中心获取,消耗网络性能,所以先获取存放至本地注册中心缓存,数据保持同步。
数据保持同步:
4、定义数据传输类型(Invocation对象,序列化)
构造Invocation对象:指定参数列表、方法、参数、地址、接口
5、dubbo生成接口代理类放入spring容器,指定调用服务,发送请求
指定服务:考虑支持集群,在代理类中,从注册中心获取到的服务路径List有多个,使用负载均衡指定最终访问的服务。
为什么使用zookeeper/Redis作为共享注册中心?
在集群情况下会存在多个服务器,新增服务器注册中心需要添加服务路径,服务器挂了需要剔除服务路径,集群发生变化时zookeeper可以通过监听机制(Redis利用消费订阅机制)保证数据同步。
6、服务提供者接收处理请求

其他部分细节

  • 多版本实现:对于多个实现类,服务提供者通过版本号区分(拼在服务名后),Dubbo中实现类使用@Service(version = “callback”)标识。
  • 支持多个协议以及协议切换:可以使用工厂模式根据配置协议名使用指定协议。
  • 新增协议:使用SPI机制。
  • 集群集群变更:利用心跳机制监控集群,zookeeper可通过临时节点(Redis可通过过期时间节点)来实现心跳,这也是为什么注册中心使用zookeeper/Redis而不使用MySQL等的原因之二。
  • 容错:服务调用失败可能是服务端调用失败也有可能是网络原因,Dubbo代理对象中捕获异常,做相关的容错处理。
  • Mock:服务未实现完,没必要进行网络请求,在发送之前可以做mock逻辑。
【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

举报
请填写举报理由
0/200