远程过程调用失败_Dubbo 本地调用
本地调用介绍
当一个应用既是一个服务的提供者,同时也是这个服务的消费者的时候,可以直接对本机提供的服务发起本地调用。从 2.2.0
版本开始,Dubbo 默认在本地以 injvm 的方式暴露服务,这样的话,在同一个进程里对这个服务的调用会优先走本地调用。
与本地对象上方法调用不同的是,Dubbo 本地调用会经过 Filter 链,其中包括了 Consumer 端的 Filter 链以及 Provider 端的 Filter 链。通过这样的机制,本地消费者和其他消费者都是统一对待,统一监控,服务统一进行治理。
同时,相比于远程调用来说,Dubbo 本地调用性能较优,省去了请求、响应的编解码及网络传输的过程。
要使用 Dubbo 本地调用不需做特殊配置,按正常 Dubbo 服务暴露服务即可。任一服务在暴露远程服务的同时,也会同时以 injvm 的协议暴露本地服务。injvm 是一个伪协议,不会像其他协议那样对外开启端口,只用于本地调用的目的。
以下面的 XML 配置为例:
<dubbo:registry address="zookeeper://127.0.0.1:2181"/>
<dubbo:protocol name="dubbo" port="20800"/><bean id="demoServiceTarget" class="org.apache.dubbo.samples.local.impl.DemoServiceImpl"/><dubbo:service interface="org.apache.dubbo.samples.local.api.DemoService" ref="demoServiceTarget"/>
<dubbo:reference id="demoService" interface="org.apache.dubbo.samples.local.api.DemoService"/>
这里同时配置了同一服务 DemoService 的提供者以及消费者。在这种情况下,该应用中的 DemoService的消费方会优先使用 injvm 协议进行本地调用。上述的例子可以在 dubbo-samples 工程中找到源码:https://github.com/apache/dubbo-samples/blob/master/dubbo-samples-local
细粒度控制本地调用
本地调用是可以显示关闭的,通过这种方式,服务提供者可以做到对远端服务消费者和本地消费者一视同仁。具体做法是通过 scope="remote" 来关闭 injvm 协议的暴露,这样,即使是本地调用者,也需要从注册中心上获取服务地址列表,然后才能发起调用,而这个时候的调用过程,与远端的服务消费者的过程是一致的。
<bean id="target" class="org.apache.dubbo.samples.local.impl.DemoServiceImpl"/>
<!-- 服务提供者指定 scope="remote" -->
<dubbo:service interface="org.apache.dubbo.samples.local.api.DemoService" ref="target" scope="remote"/>
<dubbo:reference id="demoService" interface="org.apache.dubbo.samples.local.api.DemoService"/>
同样的,服务消费者也支持通过 scope 来限定发起调用优先走本地,还是只走远程。比如,可以通过以下的方式强制消费端通过远程调用的方式来发起 dubbo 调用:
<!-- 服务消费者指定 scope="remote" -->
<dubbo:reference id="demoService" interface="org.apache.dubbo.samples.local.api.DemoService" scope="remote"/>
如果同时服务提供方限定了 scope="local" 的话,
<!-- 服务提供者指定 scope="remote" -->
<dubbo:service interface="org.apache.dubbo.samples.local.api.DemoService" ref="target" scope="remote"/>
<!-- 服务消费者指定 scope="local" -->
<dubbo:reference id="demoService" interface="org.apache.dubbo.samples.local.api.DemoService" scope="local"/>
那么该程序中的 dubbo 调用将会失败,原因是服务提供方只暴露了远程服务到注册中心上,并没有暴露 injvm 协议的服务,而出于同一个进程中的服务消费者查找不到 injvm 协议的服务,也不会去远程的注册中心上订阅服务地址。同样的,当服务提供者限定 scope="local" 而服务消费者限定 scope="remote" 也会因为相同的原因导致调用失败。出错信息如下:
[20/03/19 05:03:18:018 CST] main INFO config.AbstractConfig: [DUBBO] Using injvm service org.apache.dubbo.samples.local.api.DemoService, dubbo version: 2.7.1, current host: 169.254.146.168
Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'demoService': FactoryBean threw exception on object creation; nested exception is java.lang.IllegalStateException: Failed to check the status of the service org.apache.dubbo.samples.local.api.DemoService. No provider available for the service org.apache.dubbo.samples.local.api.DemoService from the url injvm://127.0.0.1/org.apache.dubbo.samples.local.api.DemoService?application=demo-provider&default.lazy=false&default.sticky=false&dubbo=2.0.2&interface=org.apache.dubbo.samples.local.api.DemoService&lazy=false&methods=sayHello&pid=76198®ister.ip=169.254.146.168&release=2.7.1-SNAPSHOT&scope=local&side=consumer&sticky=false×tamp=1553072598838 to the consumer 169.254.146.168 use dubbo version 2.7.1
何时无法使用本地调用
默认情况下,本地调用是自动开启的,不需要做额外的配置。只有当需要关闭的时候,才需要通过 scope的配置来显式的关闭。
但是,特别需要指出的是,在下面的几种情况下,本地调用是无法使用的:
第一,泛化调用的时候无法使用本地调用。
第二,消费者明确指定 URL 发起直连调用。当然,如果消费者指定的是 injvm 的 URL,最终的调用也是走本地调用的,比如:
<dubbo:reference id="demoService" interface="org.apache.dubbo.samples.local.api.DemoService" url="injvm://127.0.0.1/org.apache.dubbo.samples.local.api.DemoService"/>
强制打开本地调用
除了通过 scope 来控制本地调用的行为之外,也可以通过 injvm 这个配置来强制打开或者禁用本地调用。
<dubbo:consumer injvm="false" .../>
<dubbo:provider injvm="true" .../>
但是通过 injvm 来配置本地调用的方式已经被废弃。通过 scope 的方式来控制是官方推荐的。
总结
本文介绍了本地调用的概念以及带来的好处,并进一步的揭示了 dubbo 本地调用实际上是在当前进程中暴露了 injvm 的协议,而该协议并不会对外暴露端口,然后讨论了如何通过 scope 来细粒度的控制本地调用的行为,并强调了通过 invjm 来配置的方式已经被废弃,在未来版本中可能会被删除。
远程过程调用失败_Dubbo 本地调用相关推荐
- Ajax 调用webservice 解决跨域请求和发布到服务器后本地调用成功外网失败的问题...
webservice 代码 1 /// <summary> 2 /// MESService 的摘要说明 3 /// </summary> 4 [WebService(Name ...
- 远程过程调用失败_Java开发大型互联网RPC远程调用服务实现之问题处理方案
引言 RPC(Remote Procedure Call Protocol)--远程过程调用协议,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议.RPC协议假定某些传输协议 ...
- 电脑计算机打不开显示远程过程,win10系统打不开图片提示“远程过程调用失败”的解决方法...
很多小伙伴都遇到过win10系统打不开图片提示"远程过程调用失败"的情况,想必大家都遇到过win10系统打不开图片提示"远程过程调用失败"的情况吧,那么应该怎么 ...
- 电脑计算机打不开显示远程过程,Win10打不开图片提示“远程过程调用失败”的解决方案...
Windows10系统打不开图片提示"远程过程调用失败"怎么办?这是近来不少用户在使用Win10过程中经常会碰到的问题,这个问题会给我们带来不少困扰,该怎么办呢?下面,系统城小编整 ...
- Aria2 RPC接口协议和Java的本地调用实现
如果你还没有启动aria2 : 安装和配置 目录 Aria2 RPC接口协议 Java实现 依赖 核心类 调用 Aria2 RPC接口协议 官方文档 方法列表 下载参数 本文中我们使用默认的本地调用, ...
- SQL Server服务远程过程调用失败解决
一.远程过程调用失败 今天,登录本地SQL数据库后提示:sql server 无法连接到local 打开配置管理器后发现sql服务提示 打开控制面板,找到卸载程序,把"Microsoft S ...
- 【小技术】数据库显示“远程过程调用失败”怎么办?
[背景] 这两天因为SQL Server突然不能用了,然后自己"折腾"了一下午还是没能够成功救回来,也没有将SQL完全卸载干净,所以没有办法重新安装SQLServer,但是又急着用 ...
- 海康萤石摄像头SDK Java(一)java本地调用摄像头
本文仅仅实现java 本地调用海康摄像头,后续的视频码解析正在研究. 默认环境: 1.从官网下载好对应OS的SDK. 2.连通摄像头. 3.搭建Java项目,集成sdk中的java demo. 先看效 ...
- Newtonsoft.Json.dll 本地调用正常,服务器调用不正常
Newtonsoft.Json.dll 本地调用正常,服务器调用不正常的问题 请将System.Runtime.Serialization.dll 传到服务器项目bin文件夹中即可 转载于:https ...
最新文章
- vue 给iframe设置src_vue项目iframe的传值问题
- Windows 技术篇-Internet Explorer浏览器启用方法,windows找不到ie浏览器解决办法
- python 批量创建线程_【Python】批量创建线程
- 在Ruby中使用&运算符(new_array- arr&old_Array)创建数组实例
- 红帽linux lnmp搭建,RedHat/CentOs系统搭建lnmp环境
- linux中查看某个进程打开的文件数
- Python Day25
- java栈属于哪个代,Java 代码执行原理
- Debug gradle task
- matlab配置vlfeat工具箱
- 电子海图的航线多尺度生成方法
- fw300r 虚拟服务器,迅捷FW300R无线宽带路由器怎么开启UPnP
- db2从文件读到数据库
- 按键精灵 获取某网站服务器时间,按键精灵如何获得网络时间的毫秒
- python 自动打包pyd
- lintcode 输出赛程表
- Excel隔行插入空白行小技巧
- Amazon为 EC2 Auto Scaling 增加目标跟踪支持
- 总结:word2007中插入页眉页脚和页码
- Html与Css样式