简单的想想大致流程
在分析Dubbo
的服务调用过程前我们先来思考一下如果让我们自己实现的话一次调用过程需要经历哪些步骤?
首先我们已经知晓了远程服务的地址,然后我们要做的就是把我们要调用的方法具体信息告知远程服务,让远程服务解析这些信息。
然后根据这些信息找到对应的实现类,然后进行调用,调用完了之后再原路返回,然后客户端解析响应再返回即可。
调用具体的信息
那客户端告知服务端的具体信息应该包含哪些呢?
首先客户端肯定要告知要调用是服务端的哪个接口,当然还需要方法名、方法的参数类型、方法的参数值,还有可能存在多个版本的情况,所以还得带上版本号。
由这么几个参数,那么服务端就可以清晰的得知客户端要调用的是哪个方法,可以进行精确调用!
然后组装响应返回即可,我这里贴一个实际调用请求对象列子。
data 就是我所说的那些数据,其他是框架的,包括协议版本、调用方式等等这个下面再分析。
到此其实大致的意思大家都清楚了,就是普通的远程调用,告知请求的参数,然后服务端解析参数找到对应的实现调用,再返回。
落地的调用流程
上面的是想象的调用流程,真实的落地调用流程没有这么简单。
首先远程调用需要定义协议,也就是互相约定我们要讲什么样的语言,要保证双方都能听得懂。
比如我会英语和中文,你也会英语、中文,我们之间要做约定,选定一个语言比如都用中文来谈话,有人说不对啊,你中文夹着的英文我也能听得懂啊。
那是因为你的大脑很智能,它能智能地识别到交流的语言,而计算机可不是,你想想你的代码写 print 1,它还能打出 2 不成?
也就是计算机是死板的,我们的程序告诉它该怎么做,它就会生硬的怎么做。
需要一个协议
所以首先需要双方定义一个协议,这样计算机才能解析出正确的信息。
常见的三种协议形式
应用层一般有三种类型的协议形式,分别是:固定长度形式、特殊字符隔断形式、header+body 形式。
固定长度形式:指的是协议的长度是固定的,比如100个字节为一个协议单元,那么读取100个字节之后就开始解析。
优点就是效率较高,无脑读一定长度就解析。
缺点就是死板,每次长度只能固定,不能超过限制的长度,并且短了还得填充,在 RPC 场景中不太合适,谁晓得参数啥的要多长,定长了浪费,定短了不够。
特殊字符隔断形式:其实就是定义一个特殊结束符,根据特殊的结束符来判断一个协议单元的结束,比如用换行符等等。
这个协议的优点是长度自由,反正根据特殊字符来截断,缺点就是需要一直读,直到读到一个完整的协议单元之后才能开始解析,然后假如传输的数据里面混入了这个特殊字符就出错了。
header+body 形式:也就是头部是固定长度的,然后头部里面会填写 body 的长度, body 是不固定长度的,这样伸缩性就比较好了,可以先解析头部,然后根据头部得到 body 的 len 然后解析 body。
dubbo 协议就是属于 header+body 形式,而且也有特殊的字符 0xdabb ,这是用来解决 TCP 网络粘包问题的。
Dubbo 协议
Dubbo 支持的协议很多,我们就简单的分析下 Dubbo 协议。