您的位置:首页 > 其它

dubbo请求调用过程分析

2017-06-06 11:49 253 查看

服务消费方发起请求

当服务的消费方引用了某远程服务,服务的应用方在spring的配置实例如下:<dubbo:referenceid="demoService"interface="com.alibaba.dubbo.demo.DemoServ ice" />demoService实例其实是代理工厂生产的代理对象(大家可以参考代理那部分生成的伪代码),在代码中调用demoService.sayHello(“world!”)时,1.      将方法名方法参数传入InvokerInvocationHandler的invoke方对于Object中的方法toString, hashCode, equals直接调用invoker的对应方法,这里对于Object的方法需要被远程调用吗?调用了是不是报错比默认处理更好呢??远程调用层是以Invocation, Result为中心, 这里根据要调用的方法以及传入的参数构建RpcInvocation对象,作为Invoker的入参2.      MockClusterInvoker根据参数提供了三种调用策略不需要mock, 直接调用FailoverClusterInvoker强制mock,调用mock先调FailoverClusterInvoker,调用失败在mock、3.      FailoverClusterInvoker默认调用策略通过目录服务查找到所有订阅的服务提供者的Invoker对象路由服务根据策略来过滤选择调用的Invokers通过负载均衡策略LoadBalance来选择一个Invoker4.      执行选择的Invoker.inoker(invocation)经过监听器链,默认没有经过过滤器链,内置实现了很多执行到远程调用的DubboInvoker5.      DubboInvoker根据url 也就是根据服务提供者的长连接,这里封装成交互层对象ExchangeClient供这里调用判断远程调用类型同步,异步还是oneway模式ExchangeClient发起远程调用,底层remoting不在这里描述了获取调用结果:        Oneway返回空RpcResult        异步,直接返回空RpcResult, ResponseFuture回调        同步, ResponseFuture模式同步转异步,等待响应返回 

服务提供方接收调用请求

同样我们也是rpc调用层DubboProtocol层开始分析,对于通信层remoting的数据接收反序列等等过程不做分析。DubboProtocol的requestHandler是ExchangeHandler的实现,是remoting层接收数据后的回调。requestHandler.replay方法接收请求消息,这里只处理远程调用消息Invocation。1.      通过Invocation获取服务名和端口组成serviceKey=com.alibaba.dubbo.demo.DemoService:20880, 从DubboProtocol的exproterMap中获取暴露服务的DubboExporter, 在从dubboExporter 获取invoker返回2.      经过过滤器链3.      经过监听器链4.      到达执行真正调用的invoker, 这个invoker由代理工厂ProxyFactory.getInvoker(demoService, DemoService.class, registryUrl)创建,具体请看代理那部分介绍。调用demoService实例方法,将结果封装成RpcResult返回5.      交换层构建Response,通过Remoting层编码传输将结果响应给调用方 

服务消费方发起远程调用的底层通信


 服务提供方接收请求并响应的底层通信


一:provider提供方


ClassPathXmlApplicationContext <init>(构造方法)-> ClassPathXmlApplicationContext refresh()-> ClassPathXmlApplicationContext finishRefresh()-> AbstractApplicationContext publishEvent()-> ServiceBean onApplicationEvent()-> ServiceConfig doExport()#构造dubbo对象 application provider module protocol registry service reference consume等
-> ServiceConfig doExportUrls #导出URL,获取注册中心RegistryConfig#注册中心:registry://10.199.101.228:2181/com.alibaba.dubbo.registry.RegistryService?application=demo&backup=10.199.101.227:2181,10.199.101.229:2181&dubbo=2.4.9&pid=8045®istry=zookeeper×tamp=1491546077803
-> ServiceConfig doExportUrlsFor1Protocol()#需要暴露 dubbo://10.199.66.242:20880/com.unj.dubbotest.provider.DemoService?anyhost=true&application=dubbo_demo_provider&dubbo=2.4.9&interface=com.unj.dubbotest.provider.DemoService&methods=sayHello,getUsers&pid=8045&revision=0.0.1&side=provider×tamp=1491546674441&version=0.0.1
-> ServiceConfig exportLocal()-> Exporter<?> exporter = protocol.export(proxyFactory.getInvoker(ref, (Class) interfaceClass, local));#暴露Invoker<XxxService>调用服务代理类
-> proxyFactory.getInvoker(ref, (Class) interfaceClass, local)#返回 AbstractProxyInvoker代理ProxyInvoker<XxxService>public abstract class AbstractProxyInvoker<T> implements Invoker<T> {private final T proxy; //代理目标实例 XxxServiceImplprivate final Class<T> type;private final URL url;}-> InvokerInvocationHandler.invoke()#invoker.invoke(new RpcInvocation(method, args)).recreate();
-> DubboProtocol export(Invoker<T> invoker)# 返回暴露Exporter<T>public class DubboExporter<T> extends AbstractExporter<T> {private final String key; //com.unj.dubbotest.provider.DemoService:0.0.1:20880private final Map<String, Exporter<?>> exporterMap;public DubboExporter(Invoker<T> invoker, String key, Map<String, Exporter<?>> exporterMap){super(invoker);this.key = key;this.exporterMap = exporterMap;}
-> DubboProtocol openServer(url)#url dubbo://10.199.66.242:20880/com.unj.dubbotest.provider.DemoService?anyhost=true&application=dubbo_demo&dubbo=2.4.9&interface=com.unj.dubbotest.provider.DemoService&methods=sayHello,getUsers&pid=8045&revision=0.0.1&side=provider×tamp=1491546674441&version=0.0.#serverMap.put(key, createServer(url)); key:10.199.66.242:20880 value:ExchangeServer
-> DubboProtocol createServer(URL url)#返回HeaderExchangeServer,添加参数列表 如心跳,心跳时间-> Exchangers.bind(url, requestHandler);#返回HeaderExchangeServer,getTransporter()获取的实例来源于配置,默认返回一个NettyTransporter-> HeaderExchangeServer.bind(URL url, ExchangeHandler handler);-> HeaderExchangeServer(Transporters.bind(url, new DecodeHandler(new HeaderExchangeHandler(handler))));#HeaderExchangeServer包装实例NettyServer
-> NettyTransporter.bind(URL url, ChannelHandler listener)#return new NettyServer(url, listener)
-> NettyServer.doOpen();#打开socket监听端口准备接收消息#ServerBootstrap bind(getBindAddress())绑定地址端口#RpcInvocation 具体类名、方法名、调用参数#DubboInvoker – 执行具体的远程调用,包含初始化信息如client#Protocol – 服务地址的发布和订阅#Exporter – 暴露服务的引用,或取消暴露
二:consume(消费方):->ReferenceConfig.init#consume端启动初始化->DubboProtocol.refer#根据参数url,接口等构建Invoker->JavassistProxyFactory.getProxy(Invoker<T> invoker, Class<?>[] interfaces)#构建代理对象Proxy.getProxy(interfaces).newInstance(new InvokerInvocationHandler(invoker));->DemoService.say(String hello);#真正调用时候->InvokerInvocationHandler.invoke(Object proxy, Method method, Object[] args)#invoker.invoke(new RpcInvocation(method, args)).recreate();RpcInvocation包装参数方法名->DubboInvoker.doInovke(final Invocation invocation)#统一代理调用->ExchangeClient.send(invocation, isSent);->HeaderExchangeChannel.request(Object request, int timeout)->NettyChannel.send(Object message, boolean sent)
三:dubbo 底层通讯:NettyClient <-- 异步NIO传输 socket监听-> NettyServer四:consume --> provider 调用过程:-> NettyServer->NettyHandler.messageReceived #接收消息处理器-> MultiMessageHandler->HeartbeatHandler->AllChannelHandler->DecodeHandler->HeaderExchangeHandler->DubboProtocol$requestHandler#NettyServer启动时候绑定MultiMessageHandler#DubboProtocol.getServers() 检索serverMap获取Exporter<?>#DubboProtocol.getServers() 检索serverMap获取ExchangeServer-> ExchangeHandlerAdapter.reply#真正获取Invoker,将传入message 转换 invocation-> invoker.invoke(invocation)-> JavassistProxyFactory$AbstractProxyInvoker.doInvoke#服务端Invoker代理 AbstractProxyInvoker调用目标引用service,客户端DubboInvoker
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Dubbo Invoker