dubbo怎么实现rpc远程调用

dubbo怎么实现rpc远程调用,第1张

在消费者初始化的时候,会生成一个消费者代理注册到容器中,该代理回调中持有一个MockClusterInvoker实例,消费调用服务接口时它的invoke会被调用,此时会构建一个RpcInvocation对象,把服务接口的method对象和参数放到RpcInvocation对象中,作为MockClusterInvokerinvoke方法的参数,在这个invoke方法中,判断请求是否需要mock,是否配置了mock属性,是强制mock还是失败后mock,关于mock这里先不详细展开,这里只看下核心流程。 

MockClusterInvokerinvoke会调用FailfastClusterInvokerinvoke,大系统中为了服务高可用同一个服务一般会有多个应用服务器提供,要先挑选一个提供者提供服务。在服务接口消费者初始化时,接口方法和提供者Invoker对应关系保存在RegistryDirectory的methodInvokerMap中,通过调用的方法名称(或方法名称+第一个参数)改方法对应的提供者invoker列表,如注册中心设置了路由规则,对这些invoker根据路由规则进行过滤。 

comalibabadubboregistryintegrationRegistryDirectorydoList(Invocation) 

 

comalibabadubborpcclusterdirectoryAbstractDirectorylist(Invocation) 

 

读取到所有符合条件的服务提供者invoker之后,由LoadBalance组件执行负载均衡,从中挑选一个invoker进行调用,框架内置支持的负载均衡算法包括random(随机)、roundrobin(R-R循环)、leastactive(最不活跃)、consistenthash(一致性hash),应用可配置,默认random。 

methodInvokerMap保存的是持有DubboInvoker(dubbo协议)实例的InvokerDelegete对象,是Invoker-Filter链的头部,先激活Filter连然后最终调到DubboInvokerinvoke(RpcInvocation),此时远程调用分三种类型: 

1 单向调用,无需获取关注调用结果的,无需等待接口返回结果,注意调用结果不要单纯跟返回值混淆了,异常也是调用结果。 

2 异步调用,需要关注返回结果,但是不会同步等待接口调用结束,会异步的获取返回返回结果,这种情况给调用者返回一个Future,但是不同步等待Futureget返回调用结果 

3 同步调用,需要同步等待服务调用结束获取调用结果,给调用者返回一个Future并且Futureget等待结果,此时接口调用线程会挂起等待响应。 

 

我们大部分使用场景都是同步调用,所以主要看一下同步调用。如果使用者配置了多个connections按顺序选择一个ExchangeClient和服务器通信,同步调用时调用HeaderExchangeClientrequest->HeaderExchangeChannelrequest。

comalibabadubboremotingexchangesupportheaderHeaderExchangeChannelrequest(Object, int) 

 

这里的request参数是RpcInvocation对象,包含调用的方法、参数等信息,timeout参数是接口超时时间,把这些信息封装在Request对象中,调用channelsend,这个channel对象就是和服务端打交道的NettyClient实例,NettyClientsend调用NettyChannelsend。

comalibabadubboremotingtransportnettyNettyChannelsend(Object, boolean) 

 

这里的sent参数决定是否等待请求消息发出,sent=true 等待消息发出,消息发送失败将抛出异常,sent=false 不等待消息发出,将消息放入IO队列,即刻返回。默认情况下都是false。NettyChannel中有channel属性,这个channel是Netty框架中的组件,负责客户端和服务端链路上的消息传递,channelwrite把请求消息写入,这里的message是上面封装的Request对象。这里的IO模型是非阻塞的,线程不用同步等待所有消息写完,而是直接返回。调用Netty框架的IO事件之后会触发Netty框架的IO事件处理链。

<dubbo:service/> 服务配置,用于暴露一个服务,定义服务的元信息,一个服务可以用多个协议暴露,一个服务也可以注册到多个注册中心。

eg、<dubbo:service ref="demoService" interface="comxxxxxxproviderDemoService" />

<dubbo:reference/> 引用服务配置,用于创建一个远程服务代理,一个引用可以指向多个注册中心。

eg、<dubbo:reference id="demoService" interface="comxxxxxxproviderDemoService" />

<dubbo:protocol/> 协议配置,用于配置提供服务的协议信息,协议由提供方指定,消费方被动接受。

eg、<dubbo:protocol name="dubbo" port="20880" />

<dubbo:application/> 应用配置,用于配置当前应用信息,不管该应用是提供者还是消费者。

eg、<dubbo:application name="provider" />

<dubbo:module/> 模块配置,用于配置当前模块信息,可选。

<dubbo:registry/> 注册中心配置,用于配置连接注册中心相关信息。

eg、<dubbo:registry address=" zookeeper://1921682249:2181 " />

<dubbo:monitor/> 监控中心配置,用于配置连接监控中心相关信息,可选。

<dubbo:provider/> 提供方的缺省值,当ProtocolConfig和ServiceConfig某属性没有配置时,采用此缺省值,可选。

<dubbo:consumer/> 消费方缺省配置,当ReferenceConfig某属性没有配置时,采用此缺省值,可选。

<dubbo:method/> 方法配置,用于ServiceConfig和ReferenceConfig指定方法级的配置信息。

<dubbo:argument/> 用于指定方法参数配置。

Invoker URL ServiceBean

URL 之于 Dubbo,犹如水之于鱼,非常重要。

在 Dubbo 中,Invoker 是一个非常重要的模型。在服务提供端,以及服务引用端均会出现 Invoker。Dubbo 官方文档中对 Invoker 进行了说明,这里引用一下。

Invoker 是实体域,它是 Dubbo 的核心模型,其它模型都向它靠扰,或转换成它,它代表一个可执行体,可向它发起 invoke 调用,它有可能是一个本地的实现,也可能是一个远程的实现,也可能一个集群实现。

1概览

>

1,dubbo是什么

dubbo是阿里巴巴开源的,基于JAVA的 RPC (Remote Procedure Call)分布式服务框架。现已成为Apache基金孵化项目

2,为什么要使用dubbo

dubbo内部使用了Netty,zookeeper,保证了应用的高可用性和高性能。使用dubbo可以将核心业务抽取出来,最为独立的服务,并逐渐发展成稳定的服务中心。这样就可以复用灵活拓展,满足前端多变的市场需求,最重要的一点是,分布式架构能够承受更大规模的并发量

3、Dubbo 和 Spring Cloud 有什么区别?

两者没有关联,非要说区别。1,通信方式不同:dubbo使用的是RPC通信,Spring Cloud使用的是>

dubbo 是一个远程调用服务的分布式框架,可以实现远程通讯、动态配置、地址路由等等功能。比如在入门demo里的暴露服务,使得远程调用的协议可以使用dobbo协议( dubbo://xxxx )或者其它协议,可以配置zookeeper集群地址,实现软负载均衡并配置均衡方式等。在不搭配注册中心的时候,它也是可以实现服务端和调用端的通信的,这种方式是点对点通信的,所谓“没有中间商”。但是如果配置服务发布和调用端过多特别是集群的方式提供服务的时候,就会暴露许多的问题:增加节点需要修改配置文件、服务端机器宕机后不能被感知等。它可以通过集成注册中心,来动态地治理服务发布和服务调用。相当于把服务注册和发布推送的功能分摊给了(zookeeper)注册中心。

Dubbo实现服务调用是通过RPC的方式,即客户端和服务端共用一个接口(将接口打成一个jar包,在客户端和服务端引入这个jar包),客户端面向接口写调用,服务端面向接口写实现,中间的网络通信交给框架去实现。

咱们来看下Spring 配置声明暴露服务,providerxml文件

再来看服务消费者,consumerxml文件

这就是典型的点对点的服务调用。当然我们为了高可用,可以在consumerxml中配置多个服务提供者,并配置响应的负载均衡策略。

配置多个服务调用者在comsumerxml的dubbo:reference标签的url属性中加入多个地址,中间用分号隔开即可;配置负载均衡策略在comsumerxml的dubbo:reference标签中增加loadbalance属性即可,值可以为如下四种类型:

那么目前的架构有什么问题呢?

1当服务提供者增加节点时,需要修改配置文件。

2当其中一个服务提供者宕机时,服务消费者不能及时感知到,还会往宕机的服务发送请求。

这个时候就需要引入注册中心了,Dubbo目前支持4种注册中心(multicast、zookeeper、redis、simple)推荐使用Zookeeper注册中心,要使用注册中心,只需要将providerxml和consumerxml更改为如下:

如果zookeeper是一个集群,则多个地址之间用逗号分隔即可

把consumerxml中配置的直连的方式去掉

注册信息在zookeeper中如何保存?

启动上面服务后,我们观察zookeeper的根节点多了一个dubbo节点及其他,图示如下

最后一个节点中服务的地址,为什么把最后一个节点标成绿色?因为最后一个节点是临时节点,而其他节点是持久节点,这样,当服务宕机时,这个节点就会自动消失,不再提供服务,服务消费者也不会再请求。如果部署多个DemoService,则providers下面会有好几个节点,一个节点保存一个DemoService的服务地址。

其实一个zookeeper集群能被多个应用公用,因为不同的框架会在zookeeper上建不同的节点,互不影响。如dubbo会创建一个/dubbo节点,storm会创建一个/storm节点。

zookeeper 介绍:

zookeeper是 Apacahe Hadoop 的子项目,是一个树型的目录服务,支持变更推送,适合作为 Dubbo 服务的注册中心,工业强度较高,可用于生产环境,并推荐使用。

流程说明:

支持以下功能:

补充:

dubbo的协议使用什么序列化框架?

dubbo有多种协议,不同的协议默认使用不同的序列化框架。比如dubbo协议默认使用 Hessian2 序列化(说明:Hessian2 是阿里在 Hessian 基础上进行的二次开发,起名为Hessian2)。rmi协议默认为 java 原生序列化,>

关于dubbo的使用场景,这个要从系统的演变开始将起,既然dubbo的使用很多是在电商系统中,那么就从电商系统的演变开始讲起。一个简单的电商网站说起,它可能包含如下的几个模块和功能,如首页、detail页、list页、下单页、支付页以及后台管理等页面和功能。单一的系统架构,使得在开发过程中,占用的资源越来越多,而且随着流量的增加使得维护起来越来越难以维护。于是就产生了垂直应用架构,垂直应用架构解决了单一应用架构所面临的扩容问题,流量能够分散到各个子系统当中,且系统的体积可控,一定程度上降低了开发人员之间协同以及维护的成本,提升了开发效率。但是在垂直架构中相同逻辑代码需要不断的复制,不能复用。所以分布式系统就这样应运而生了。公共的逻辑业务提取出来形成服务,对外提供。这样对于维护和升级都只需要切分成一个一个的小系统去维护,也可以让前端业务系统与底层数据访问分离,团队分工更为明确。分布式系统所依赖的基础设施包括服务框架、消息中间件、数据访问中间件、配置中心、分布式缓存系统、持久化存储(关系数据库、nosql数据库)、搜索引擎、CDN网络、负载均衡系统、运维自动化系统、硬件虚拟化及镜像管理系统、分布式文件系统、日志收集系统、监控系统、离线计算、实时计算、数据仓库等等。随着服务化的进一步发展,服务越来越多,服务之间的调用和依赖关系也越来越复杂,诞生了面向服务的架构体系(SOA),也因此衍生出了一系列相应的技术,如对服务提供、服务调用、连接处理、通信协议、序列化方式、服务发现、服务路由、日志输出等行为进行封装的服务框架。就这样为分布式系统的服务治理框架就出现了,dubbo也就这样产生了。dubbo在整个分布式系统的架构中,按照分层的架构来架构,使得各个层级之间最大限度的松耦合

近期由于搭建公司整套测试环境中使用Docker 容器化部署Dubbo一直出现找不到服务提供者

经过两天断断续续的摸索以及资料(说到这理要落泪了)的查询该问题得意解决这就是本次要扯的内容。

本次 dubbo 服务 是以docker-compose进行服务编排部署,服务者与消费者也在同一个Java 工程目录下

当我们服务者工程开启的时候会在Nacos中服务列表中产生新的一项接口其内容是这样的,根据下方的可以很清楚的看到IP及端口是不是有点似曾相识的感觉呢,特别是20880端口!

又经历了一资料的查询之后,我发现20800端口并没有被我映射出来。于是我把服务提供者配置文件改这样:

消费者配置文件改成这样

终于在我本地以及不同的服务器之间可以正常运行了!

其实如果不在测试环境上遇到这些问题以后在生产环境上也同样会遇到,我们能做的就是在问题到来之前做一定的知识储备避免一些常见的坑。

        大家在平时开发和测试阶段定位一些bug的时候,需要调用本地启动的dubbo服务debug。如果与服务器、其他同事共用一个注册中心的话,就会调用到别人的服务或者自己本地的服务被别人调用到,造成一些调用失败或者其他异常。

       解决如上问题有大致几种解决方案:

       1、dubbo直连;

       2、dubbo group 服务分组;

       3、dubbo version 版本过渡;

        在开发以及测试环境下,经常需要绕过注册中心,只测试指定服务的提供者,这时候可  以使用点对点直连的方式。点对点直连方式,将以服务接口为单位,忽略注册中心的提供者表。A接口配置点对点,不影响B接口从注册中心获取列表。

      消费者应用,在注入的提供者api上添加 @Reference(version = "100", url = "dubbo://ip:port") 即可!

      此时,如果提供者不希望本地的服务被别人调用到,设置:dubboregistryregister=false,默认值是true。该属性含义: 是否向此注册中心注册服务,如果设为false,将只订阅,不注册。

        通过服务分组实现环境隔离,不用绕过注册中心,大家可以共用一个注册中心。服务注册分组,使跨组的服务不会相互影响,也无法相互调用,适用于环境隔离。

      场景:服务A希望调用到本地的服务B(此时,B服务正常的调用远程服务C),而不是远程服务B。

      本地服务B的配置设置如下:                                                                                                          //应用全局配置                                                                              dubboprovidergroup=local-group   //设置本地B所提供的dubbo服务均在local-group分组下如图:

       //针对某个Api进行配置

      也可以针对某个api单独做分组,例如:@Service(version = "100",group = "local-group")服务A:在注入的B dubbo服务的api上加 @Reference(version = "100", group = "local-group")  即可。

      服务分组的几个属性解释:

1、dubboregistrygroup=local-group 

          该值自行定义,确保唯一即可,该属性含义:服务注册分组,跨组的服务不会相互影响,也无法相互调用,适用于环境隔离。 该配置不推荐配置,配置之后服务在dubbo admin上默认无法查看,也调用不到该服 务。不同环境,通过zookeeper做数据隔离。

            

      2、dubboprovidergroup=local-group  

       该属性含义:服务分组,当一个接口有多个实现,可以用分组区分。该配置使当前服务所有的提供者都在local-group下。也可以只针对某个api做配置@Service(version ="100",group ="local-group");推荐后者!

     3、dubboconsumergroup=local-group 

           该配置使当前服务只消费local-group分组下的提供者,建议只针对某个api进行配置即可,例如: @Reference(version ="100", group ="local-group")

            当一个接口的实现,出现不兼容升级时,可以用版本号过渡,版本号不同的服务相互间不引用。dubboproviderversion=10 //服务版本, 建议使用两位数字版本,如:10 ,通常在接口不兼容时版本号才需要升级。

 dubboconsumerversion=10 //消费10版本的提供者

 可全局配置,亦可配置到某个api服务上,此时优先级大于全局配置。

 提供者服务示例:@Service(version ="your version")

 消费者api服务示例: @Reference(version ="your version")

dubbx虽然是基于jboss的resteasy实现restfull,但是对resteasy原生的配置却不支持(可能是考虑到dubbo本事的设计模式及实现难度,但是和大部分framework的设计风格背道而驰),ExceptionMapper , Filter 和 Interceptor 需要配置在 <dubbo:protocol extension="x,x"/> ,参考

一Filter

Filter主要用于访问和设置>

以上就是关于dubbo怎么实现rpc远程调用全部的内容,包括:dubbo怎么实现rpc远程调用、dubbo服务暴露、dubbo笔记等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/web/9424975.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-04-28
下一篇2023-04-28

发表评论

登录后才能评论

评论列表(0条)

    保存