服务导出实现博客地址:https://www.cnblogs.com/iscys/p/10177089.html
对于服务的引入我们就不说那些dubbo spi 机制 执行调用链这些东西了,如果不清楚,请看我上面服务导出的博客,这里就说一些关键的代码步骤,目的就是让客户端的调用和服务器端的处理能够进行串起来;
(一)netty 客户端的创建 以及代理生成
关于netty 客户端的创建以及代理生成逻辑主要在 com.alibaba.dubbo.config.ReferenceConfig 类中的 get() 方法中,从而会的代理对象;调用过程如下:
1.Spring FactoryBean 的实现调用:
public Object getObject() throws Exception { return get(); }
2.通过init()方法进行服务的引用,tcp 的长链接 以及代理对象创建;
public synchronized T get() { if (destroyed) { throw new IllegalStateException("Already destroyed!"); } if (ref == null) { init(); } return ref; }
3.tcp与服务端的连接:
在refer调用链中会调用到DubboProtocol 的refer 方法,会创建DubboInvoker 对象,此时的url 是 服务器端 的url 地址 ,通过此url 进行tc p 长链接的建立,并将连接保存到DubboInvoke 对象中,供消费端调用


然后通过 getClients(url) 方法进行创建与服务器端的t c p 连接 ,默认是共享连接,避免每服务每连接;

创建新连接

4.代理对象的创建:默认使用的是j a vs si s t 代理

也就是说我们消费端示例出来的对象就是这个代理对象,我们消费端所有的请求都会进入到这个 InvokerInvocationHandler 中被invoke 方法调用

这样一个消费端到示例代理对象就可以拿到了,其后消费端到每个操作都是tcp 之间的数据通讯传输;
(二)消费端与服务端的通讯
消费端与服务端的通讯主要是靠 Invocation Response Request DefaultFuture 这4个模型构成了tcp 通讯基石模型
我们知道消费端的调用首先会到代理类的invoke 方法中,再由代理进行分发,我们暂且忽略消费端调用时候的负载均衡机制,只关注消息的发送与接收模型
1.首先会将我们的方法以及参数封装成一个RpcInvocation (Invocation) 对象 :
Invocation 模型:将消费端的参数,方法进行完整的封装成对象;

2.在最终会调用到我们的DubboInvoker 对象(这个对象是在 refer调用链创建的 )的doInvoke 方法; 这个对象我们在tcp 与服务端建立长链接的时候已经见过了;里面维护着tcp 连接对象

然后就是拿到连接去发送请求:

构造Request 请求模型:
Request 模型:消费端与客户端通讯的模型,生成通讯的唯一识别ID,将Invocation 参数信息模型放入;

在request 中会生成一个唯一ID,这个ID生成的原子性的 采用 AtomicLong增长,
然后将Rpcinvocation 对象放入request 中

DefaultFuture 模型:
DefaultFuture 模型:用于存放当前的请求ID,阻塞式的接收服务端的返回信息;


这个FUTURES Map 容器是dub bo 精华所在,里面维护着请求的id 与DefaultFuture 的关联;为什么这么说呢,我们看DefaultFuture 中还维护着
response 对象
Response 模型:用于接收服务端向消费端的返回结构,里面维护着消费端向服务端发送Request 的唯一ID;

这个response 对象用来接收服务端发送过来的消息,那么问题来了,同一个tcp 连接一时间段发送很多消息,那么如何判断返回的消息是哪个消费者发出来的呢?这个就是ID作用,在服务端返回消息的时候将request id 带上一并返回,这时消费端的tcp 接受端,就可以通过这个ID 将消息返回的结果Response 装入DefaultFuture response 对象中,然后阻塞进行拿到response结果,做到异步转同步的效果;代码逻辑也是这样的 :
在就收到消息的时候 通过ID 拿到DefaultFuture

给response 赋值:

消费端通过ge t() 阻塞拿到返回到结果,做到将异步转为同步

得到返回到结果

为什么我这么确认说,t c p 返回到结果会操作这个FUTURES 容器呢?
我们NettyClient 自定义的处理器:

我们看nettyhander 的消息接收

一直会调用到com.alibaba.dubbo.remoting.exchange.support.header.HeaderExchangeHandler这个头类的 received 方法:

我们看 handleResponse,可以看到DefaultFuture 处理response返回结果

浙公网安备 33010602011771号