快来!我从源码中学习到了一招Dubbo的骚操作! (上)

简介: 快来!我从源码中学习到了一招Dubbo的骚操作! (上)

荒腔走板


大家好,我是 why,欢迎来到我连续周更优质原创文章的第 55 篇。


老规矩,先来一个简短的荒腔走板,给冰冷的技术文注入一丝色彩。


魔幻的 2020 年的上半年过去了,很多人都在朋友圈和上半年说再见,我也不例外。


上面这张照片,就是我在朋友圈发的一张图片。



这张照片是我在公司去年年会的时候拍的,出处来自电影《飞驰人生》。


电影里面有人问张弛:你五年连续获得冠军的必胜绝招是什么?


张驰满怀深情的回答:必胜绝招只有两个字—奉献。就是把你的全部,奉献给你所热爱的一切。


什么是热爱?


可以用电影里面的一句台词来回答:



“巴音布鲁克,1462道弯,109公里,耍小聪明,赢得了100米,赢不了100公里。我每天在脑海里开20遍,5年,3万6千遍,我能记住每一个弯道。”


张弛在电影里面是一个卑微的角色,他卖炒饭、卖唱、偷车架、端着饭碗喝红酒......做了很多很多卑微的事情。


但是,他的心里一直记得巴音布鲁克,一直记得那 1462 个弯道。即使卑微到尘土,他最终还是拼了命的回到了赛道。


这就是热爱。


热爱,从来不是一件简单的事情。


这句话也让我想起了路遥先生在《早晨从中午开始》中的一句话:


只有初恋般的热情和宗教般的意志,人才有可能成就某种事业。


这也是热爱,对毕生所最追求之热爱。


我是一个普普通通的程序猿,但是我喜欢这个行业;我是一个平凡无奇的打工仔,但是我热爱我的生活。


你呢?你热爱着什么?又付出了多少?


2020 年的上半年,我每一天都在努力。


2020 年的下半年,愿你我共同成长。


好了,说回文章。


先说背景


前段时间有个读者问我,他说他们的 RPC 框架用的是 Dubbo,当对接一个新服务的接口时就需要开通对应的网络关系。


比如我是 A 服务,第一次对接 B 服务的 Dubbo 接口,那么我需要开通 A 服务到 B 服务的对应的 Dubbo 端口的网络访问权限。


但是有的时候总是有人忘记开通网络权限,导致业务展开的时候服务调用报错。已经吃过几次这样的亏了。


目前他们想到的解决方案是 A 服务启动后就调用 B 服务提供的一个专门用于测试能否调通的接口。如果不通,配合监控手段,这样就能主动发现问题了。


这是一个兜底方案,防止开发人员忘记或者不知道需要开通网络权限的情况。


这个解决方案的问题是每个服务都需要专门写一个接口,以供其他服务来调用。


每一个服务都要写,对系统的侵入性太大了。


有没有什么好的解决方案呢?


大家想想呢,这种问题其实还是挺普遍的。有点类似于心跳功能,虽然只需要跳一次。


Dubbo 服务启动成功后,你怎么主动判断需要用到的接口,都是可以访问到的?


了解到这问题后,我就回复了两段内容。


第一段是:Dubbo 启动时检查了解一下?回声测试了解一下?


第二段是:这样做除了每个服务都需要专门写一个接口外,还需要考虑一个情况。B 服务集群部署,比如有三个节点,负载均衡之后只会选择一个其中一个。如果恰好这个服务是开通了网络关系,但是另外两个都忘记了呢?怎么做?


文本就主要围绕这两个问题展开,重点是对回声测试的实现原理的剖析,看完之后你会由衷的感叹一句:这代码,使用了障眼法呀,是真的“骚”啊。



需要说明一下的是,本文中涉及到的源码均为目前最新的 Dubbo 2.7.7 版本。


启动时检查


在说回声测试之前,我得先简单的提一下 Dubbo 的启动时检查。


上面提到的这个问题,Dubbo 肯定也是考虑到了的,启动的时候就应该去检查依赖的服务是否可用。


我们看一下官网上怎么说的:


http://dubbo.apache.org/zh-cn/docs/user/demos/preflight-check.html


意思就是这个 check 你可以用但是有的场景下它支持的不是太好。


我一般是不用,会设置为 false。


那么这个参数怎么配置,可以在哪配置呢?



还是去看官网啊,写的很清楚的:


这是一种解决方案,但不是本文重点,所以这一节只是做介绍,实现原理不进行展开,有兴趣的朋友可以自己去翻翻源码。


啥是回声测试?


就算你们的 PRC 框架用的是 Dubbo,可能你根本就不知道回声测试这回事。


很正常,关于这部分的介绍官网上都写的极简,所有加一块,就只有这些内容:

http://dubbo.apache.org/zh-cn/docs/user/demos/echo-service.html


虽然你没有关心过回声测试,但是你的每一个 Dubbo 接口都支持回声测试。


这点我们从官网上的描述也可以看出来的:



所有服务自动实现 EchoService 接口,只需将任意服务引用强制转型为 EchoService,即可使用。


润物无声,牛不牛皮,惊不惊讶?



先整一个简单、直观的示例。


下面是一个 Dubbo 的接口(provider 端)和其实现类:


在 consumer 端进行调用,并输出调用结果如下:


第 26 行调用 sayHello 方法没啥说的,常规操作。


妙就妙在 28 和 29 行。


把 demoService 强转成了 EchoService,然后这个方法还有一个 $echo 方法。


这个方法的入参和出参都是 Object 类型:



在上面的案例中,输入“echo,why技术”,返回也是“echo,why技术”。


所以,EchoService 接口的 $echo 官方叫法是:回声测试。


很形象,是不是?


用法是非常简单了。总体来看就是如果你只需要看看 Dubbo 服务能否调通,但你又不想用启动时检查的方式,你也不需要为每个服务都专门提供一个诸如 sayHello 这样的接口。


调用方只需要把其中的一个服务引用强转为 EchoService 就可以了。

EchoService 就是一个接口:



框架已经给我们提供了这样的功能,接下来,带大家看看它的实现原理。 EchoService实现原理-大胆假设


用法是很简单的,就是把 demoService 这个服务引用强转为 EchoService:


EchoService demoService = (EchoService) this.demoService;
String echo = (String) demoService.$echo("echo,why技术");


只看上面这两行代码,其实大家应该就可以猜出一个大概。


首先第一行是一个类型强转,那么说明 demoService 这个代理类,不仅实现了 DemoService 接口,还在某个不为人知的地方实现了 EchoService 这个接口。


就类似于这样式儿的:


public class 代理类 implements DemoService, EchoService


因为只有这样强转的时候才不会报错。


然后第二行调用了 $echo 方法,一定是某个地方实现了这个接口,实现方式里面保持出参和入参一致。


所以我们提出两点猜测:


1.DemoService 这个服务引用是由框架帮我们实现了 EchoService 接口。


2.同时框架帮我们实现了 $echo 方法,方法的逻辑是保证其出参和入参一致。


接着我们就去验证一下。

目录
相关文章
|
7月前
|
Dubbo Java 应用服务中间件
微服务学习 | Springboot整合Dubbo+Nacos实现RPC调用
微服务学习 | Springboot整合Dubbo+Nacos实现RPC调用
|
7月前
|
缓存 Dubbo Java
趁同事上厕所的时间,看完了 Dubbo SPI 的源码,瞬间觉得 JDK SPI 不香了
趁同事上厕所的时间,看完了 Dubbo SPI 的源码,瞬间觉得 JDK SPI 不香了
|
7月前
|
Dubbo Java 应用服务中间件
从源码全面解析 dubbo 服务端服务调用的来龙去脉
从源码全面解析 dubbo 服务端服务调用的来龙去脉
|
7月前
|
缓存 Dubbo Java
Dubbo 第三节_ Dubbo的可扩展机制SPI源码解析
Dubbo会对DubboProtocol对象进⾏依赖注⼊(也就是⾃动给属性赋值,属性的类型为⼀个接⼝,记为A接⼝),这个时候,对于Dubbo来说它并不知道该给这个属性赋什么值,换句话说,Dubbo并不知道在进⾏依赖注⼊时该找⼀个什么的的扩展点对象给这个属性,这时就会预先赋值⼀个A接⼝的⾃适应扩展点实例,也就是A接⼝的⼀个代理对象。在调⽤getExtension去获取⼀个扩展点实例后,会对实例进⾏缓存,下次再获取同样名字的扩展点实例时就会从缓存中拿了。Protocol是⼀个接。但是,不是只要在⽅法上加了。
|
2月前
|
存储 负载均衡 监控
dubbo学习一:zookeeper与dubbo的关系,下载安装启动zookeeper(解决启动中报错)
这篇文章是关于Apache Dubbo框架与Zookeeper的关系,以及如何下载、安装和启动Zookeeper的教程,包括解决启动过程中可能遇到的报错问题。
82 3
dubbo学习一:zookeeper与dubbo的关系,下载安装启动zookeeper(解决启动中报错)
|
2月前
|
Dubbo Java 应用服务中间件
Dubbo学习圣经:从入门到精通 Dubbo3.0 + SpringCloud Alibaba 微服务基础框架
尼恩团队的15大技术圣经,旨在帮助开发者系统化、体系化地掌握核心技术,提升技术实力,从而在面试和工作中脱颖而出。本文介绍了如何使用Dubbo3.0与Spring Cloud Gateway进行整合,解决传统Dubbo架构缺乏HTTP入口的问题,实现高性能的微服务网关。
|
2月前
|
监控 Dubbo Java
dubbo学习三:springboot整合dubbo+zookeeper,并使用dubbo管理界面监控服务是否注册到zookeeper上。
这篇文章详细介绍了如何将Spring Boot与Dubbo和Zookeeper整合,并通过Dubbo管理界面监控服务注册情况。
132 0
dubbo学习三:springboot整合dubbo+zookeeper,并使用dubbo管理界面监控服务是否注册到zookeeper上。
|
2月前
|
Dubbo IDE Java
dubbo学习二:下载Dubbo-Admin管理控制台,并分析在2.6.1及2.6.1以后版本的变化
这篇文章是关于如何下载和部署Dubbo管理控制台(dubbo-admin)的教程,并分析了2.6.1版本及以后版本的变化。
64 0
dubbo学习二:下载Dubbo-Admin管理控制台,并分析在2.6.1及2.6.1以后版本的变化
|
7月前
|
Dubbo Java 应用服务中间件
Java从入门到精通:3.2.2分布式与并发编程——了解分布式系统的基本概念,学习使用Dubbo、Spring Cloud等分布式框架
Java从入门到精通:3.2.2分布式与并发编程——了解分布式系统的基本概念,学习使用Dubbo、Spring Cloud等分布式框架
546 0
|
7月前
|
Dubbo Java 应用服务中间件
微服务框架(十七)Dubbo协议及编码过程源码解析
  此系列文章将会描述Java框架Spring Boot、服务治理框架Dubbo、应用容器引擎Docker,及使用Spring Boot集成Dubbo、Mybatis等开源框架,其中穿插着Spring Boot中日志切面等技术的实现,然后通过gitlab-CI以持续集成为Docker镜像。   本文为Dubbo协议、线程模型、和其基于Netty的NIO异步通讯机制及源码