RPC&Dubbo基础介绍

RPC

什么是RPC

RPC–远程过程调用。也就是说两台服务器A,B,一个应用部署在A服务器上,想要调用B服务器上应用提供的函数/方法,由于不在一个内存空间,不能直接调用,需要通过网络来表达调用的语义和传达调用的数据。RPC 是一个请求响应模型。客户端发起请求,服务器返回响应。

RPC是一种技术思想而不是一种规范或者协议。有许多基于这种技术思想的RPC框架,例如,dubbo、Google gRPC、spring cloud等

RPC框架–可以让程序员来调用远程进程上的代码一套工具。有了RPC框架,程序员就轻松很多了,终于可以逃离多线程、Socket、I/O的苦海了。RPC框架最重要的一个功能就是实现一个RPC的协议。

为什么出现RPC

在这里插入图片描述

RPC过程

1、通信问题–通过建立TCP的链接。链接可以根据需要建立长连接或者短连接
2、解决寻址问题–A服务器上的应用怎么告诉底层的RPC框架,如何连接到B服务器以及特定的端口、方法的名称是什么
3、传输—参数值序列化成二进制的形式,通过寻址和传输将二进制发送到被调用的服务器
4、调用—发序列化,找到对应的方法(寻址)进行调用,返回值
5、返回–通过序列化和反序列化的方式将返回值发送到发起调用的服务器
在这里插入图片描述

Dubbo

为什么要有dubbo

随着互联网的发展,我们发现,应用与应用之间的关系已经十分的复杂了,就会出现以下几个问题(以下摘录于官网):

① 当服务越来越多时,服务 URL 配置管理变得非常困难,F5 硬件负载均衡器的单点压力也越来越大。
② 当进一步发展,服务间依赖关系变得错踪复杂,甚至分不清哪个应用要在哪个应用之前启动,架构师都不能完整的描述应用的架构关系。
③ 接着,服务的调用量越来越大,服务的容量问题就暴露出来,这个服务需要多少机器支撑?什么时候该加机器?
在这里插入图片描述

Dubbo基础架构

Dubbo架构-角色

在这里插入图片描述

节点 角色说明
Provider 暴露服务的服务提供方
Consumer 暴露服务的服务提供方
Registry 服务注册与发现的注册中心
Monitor 统计服务的调用次数和调用时间的监控中心
Container 服务运行容器

Dubbo调用关系说明

Dubbo的调用关系如上图所示,以注册中心Registry为中心,Provider即服务提供者,将服务export出来注册(1、register)存储到Registry,Consumer即客户端调用者,从Registry订阅所关心的服务(2、subscribe),首次订阅时拉取订阅服务所有的地址列表(服务提供者注册到Registry上的信息),当订阅服务有更新(地址变更或有新的地址注册加入),Consumer收到注册中心的服务更新通知(3、notify),以上是服务端export的过程。

客户端发起RPC调用时,首先从服务地址列表里refer()指定的服务,这其中有服务寻址和从集群中筛选最终指向一个服务的过程,这就是import的过程。得到某个服务指向,则发起远程调用(4、invoke)。

Export和Import说明

Dubbo服务端接口export(导出)是将接口信息注册到注册中心Registry的过程。而客户端import(导入)远程接口是通过从注册中心Registry订阅远程服务接口,收到通知后拉取到本地的过程。
注册和订阅的过程,不需要修改服务端本地的类和方法,只需保证客户端和服务端共同引用一个包含接口的jar包。服务端和客户端分别编写简单的dubbo接口配置xml文件(或注解的方式),容器启动时就自动注册和订阅了。

Dubbo架构-分层

在这里插入图片描述

图例说明:

  • 图中左边淡蓝背景的为服务消费方使用的接口,右边淡绿色背景的为服务提供方使用的接口,位于中轴线上的为双方都用到的接口。
  • 图中从下至上分为十层,各层均为单向依赖,右边的黑色箭头代表层之间的依赖关系,每一层都可以剥离上层被复用,其中,Service 和
    Config 层为 API,其它各层均为 SPI。
  • 图中绿色小块的为扩展接口,蓝色小块为实现类,图中只显示用于关联各层的实现类。
  • 图中蓝色虚线为初始化过程,即启动时组装链,红色实线为方法调用过程,即运行时调时链,紫色三角箭头为继承,可以把子类看作父类的同一个节点,线上的文字为调用的方法。

客户端调用的过程

看上图Config层的橙色小圆点,红色实线剪头为调用链。客户端invoke远程API(Interface),实际是调用了Proxy层的RpcProxy,proxy又调用集群组件Cluster,从集群中筛选出一个Invoker作为调用者发起调用。

我们看到,在Cluster层中筛选的过程调用了Directory(实现类为RegistryDirectory)、Router、LoadBalance,分别通过Directory实现了服务的高可用,通过Router实现了智能路由功能,通过LoadBalance实现了负载均衡。

从集群模块中筛选出一个Invoker后执行invoke()方法执行方法调用,到了Protocol协议层,经过Filter组件做拦截过滤处理,如用户名、密码验证等可在此处理。过滤通过后,调用Protocol实现类如DubboProtocol或HessianProtocol等的invoke()方法。

具体的协议实现类(如DubboProtocol)会请求ExchangeClient组件,它封装了具体的数据通讯细节,是底层数据通信的代理层。因此它自然会调用底层的通信组件(默认是Netty)实现Client建立连接、Server绑定端口和数据传输(request、return)的功能。

数据传输前需要数据序列化,服务端接收到数据需要反序列化,这些都靠序列化组件实现。Codec是序列化组件的代理层,具体序列化协议,默认是Hessian,还可选择Kryo,Thrift(被Dubbo改造,与原Thrift不兼容),dubbo, hessian2, java, json等,具体参见Dubbo用户手册。

服务端调用

服务端接收到客户端的请求后,反序列化数据,通过DubboHandler协议处理请求,找到注册的本地Exporter,触发invoke(),经过过滤器处理后,调用Invoker代理层,触发真正的本地接口调用,返回数据序列化后发送给客户端。

以上内容以RPC模型为基础,分析总结了Dubbo实现RPC的大体流程,后续我还会分别针对某些组件展开讨论Dubbo的设计实现。

Dubbo实战demo

Dubbo服务提供(provider)

接口定义

public interface ProviderService {
   
    String SayHello(String word);
}

接口实现

public class ProviderServiceImpl implements ProviderService {
   
    public String SayHello(String word) {
   
       return word;
    }
}

依赖包

provider依赖包

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值