源码分析: Dubbo如何实现http+jsonrpc调用
Dubbo是大家都很熟悉的RPC框架,jsonrpc是一种基于json传输的rpc协议,今天我们来看下基于dubbo框架的jsonrpc协议传输的应用实践!话不多说,咱们单刀直入!
Dubbo协议扩展
dubbo默认的协议是Dubbo协议,同时也提供了多种协议的实现,目前实现的扩展有:
org.apache.dubbo.rpc.protocol.injvm.InjvmProtocolorg.apache.dubbo.rpc.protocol.dubbo.DubboProtocolorg.apache.dubbo.rpc.protocol.rmi.RmiProtocolorg.apache.dubbo.rpc.protocol.http.HttpProtocolorg.apache.dubbo.rpc.protocol.http.hessian.HessianProtocol
具体说明可以参考:Dubbo RPC协议. 本文演示的就是使用http协议方式
Dubbo-Http协议的使用姿势
从github上下载demo下来看,这里的demo演示是注解的形式。
dubbo提供的demo地址请参考文末链接。

消费端姿势
注册中心:Consul
其实消费端的配置很简单,配置下consul的地址即可,这样一来就默认使用consul方式的注册中心了。
dubbo.application.name=dubbo-demo-annotation-consumerdubbo.registry.address=consul://localhost:8500
服务引用(http)
那么,问题来了,就是消费端怎么设置http协议调用呢?很简单,就是在服务引用DemoService上加上注@DubboReference,如下:
@DubboReference(protocol=”http”)
package org.apache.dubbo.demo.consumer.comp;import org.apache.dubbo.config.annotation.DubboReference;import org.apache.dubbo.demo.DemoService;import org.springframework.stereotype.Component;import java.util.concurrent.CompletableFuture;@Component("demoServiceComponent")public class DemoServiceComponent implements DemoService { @DubboReference(protocol="http") private DemoService demoService; @Override public String sayHello(String name) { return demoService.sayHello(name); } @Override public CompletableFuture<String> sayHelloAsync(String name) { return null; }}
服务端姿势
服务端的使用姿势更加简单。配置如下所示,这样一来服务启动之后就会把DemoService注册到Consul注册中心了。
dubbo.application.name=dubbo-demo-annotation-providerdubbo.protocol.name=httpdubbo.protocol.port=20880
可以看到consul上已经注册了服务:

抓包测试
启动服务提供者和消费者之后,就可以进行抓包了。可以看到底层走的的确是jsonrpc的协议。

调用流程分析
Dubbo的调用我觉得用官网文档的这个图比较清晰。

Directory会监听注册中心的事件,从而更新本地的服务列表,这些列表内的提供者信息最终会被封装为相应的invoker对象,确切的说是RegisterDirectory,即通过Directory的实现类来管理这些List< Invoker>。当消费者发起调用,会走到AbstractClusterInvoker抽象类的Invoke方法。接着会做几件事:第一件事就是从Directory中拿到List< Invoker>.而AbstractDirecoty的实现类有两个,其中和注册中心有关的就是RegistryDirectory。



注意这里还有路由规则的过滤,也就是对注册中心的提供者列表做过滤,比如标签路由、条件路由等。然后还有一个必须要说的就是这个notify事件通知方法,对服务提供者的状态进行监听,从而及时更新本地的服务提供者列表。

拿到List之后,那就要进行初始化一个负载均衡,看下这个initLoadBlance方法。

服务列表有了,负载均衡器也有了,接下来就是集群调用了,集群的调用方式如图所示,默认的就是FailOver这种失败自动切换方式了。

今天暂时就分析到这里了,欢迎随时留言一起交流!
参考资料
Dubbo官方文档:
http://dubbo.apache.org/zh-cn/docs/source_code_guide/directory.html
Dubbo-Demo地址:
https://github.com/apache/dubbo/tree/master/dubbo-demo
夜雨聆风
