- 浏览: 561930 次
- 性别:
- 来自: 深圳
文章分类
最新评论
-
jiang2011jiang:
mybatis3源码核心类1--Configuration -
tuyf_hs:
同求 图片
zookeeper+dubbo+dubbo管理集群的简要配置[单机] -
安静听歌:
请问图片还能找的会吗?你的图片和原文的图片都挂了,,,如果有图 ...
zookeeper+dubbo+dubbo管理集群的简要配置[单机] -
ahua186186:
yngwiet 写道楼主,有一个地方不太明白,为什么要用“ge ...
ListView中getChildAt(index)的使用注意事项 -
yngwiet:
楼主,有一个地方不太明白,为什么要用“getChildAt(p ...
ListView中getChildAt(index)的使用注意事项
1.今天没太多事情,挤出点时间,研究了下dubbo的路由规则实现。
首先,看看dubbo消费端的主要调用流程(这里就不画图了),以后补充:
第一步:创建消费端代理:ReferenceConfig.createProxy,这里没什么特别,典型的C/S调用设计,都是通过JAVA动态代理或是Javassist的代理实现,比如mybatis mapper。
思考:假如我想实现API网关的dubbo协议路由怎么实现呢:毫无疑问必须使用ReferenceConfig的get.set以及init方法,下一篇将展开讨论实现细节..
第二步:直接跳到动态代理代码里的InvokerInvocationHandler:
这里忽略invoker的初始化(基本就是提供者注册+消费端订阅后初始化)
思考:假如让你实现一个RPC的客户端同步和异步调用你会怎么实现呢?
第三步:AbstractClusterInvoker.invoke;
这里主要是加载一个列表:invoker list
第四步:真正加载invoker的实现:AbstractDirectory
注意这里有个路由选择的逻辑,也就是我们今天关注的重点:
router.route:具体的路由实现逻辑:比如ConditionRouter
思考:假如你的程序中需要实现动态的插件式功能,你如何实现呢:基本思路:配置中心配置+ 配置通知更新+插件根据优先级生效。---典型的分布式协调场景,ZK标配
相比静态的插件式功能实现思路:SPI思想,要灵活很多
第五步:FailoverClusterInvoker.doInvoke:
这里通过负责均衡策略选择一个invoker,然后通过各种过滤器过滤。
最后:通过DubboInvoker发送数据给服务提供端。
了解完调用的主流程,我们基本就梳理清楚路由逻辑的实现在那个环节,以及需要注意设置那些属性,比如runtime.
但是经过我本人测试dubbo的路由功能并不稳定,所有用它做灰度发布不靠谱(但是通过权重设置实现rolling update还是比较靠谱的),不稳定因素有:
1.消费端没有及时订阅新增的服务提供者信息,而我们的需求是需要路由到增的服务提供者,导致ConditionRouter.matchCondition无法匹配成功,然后就不会使用路由规则。
2.路由规则没有及时通知更新到消费端,导致AbstractDirectory.setRouters一直没有添加ConditionRouter。(经过测试这个经常出现,这个问题比较严重,也有可能是我环境的问题)
学习感悟:总的来说通过今天的研究还是学到了一些常用的设计思路,而不仅仅是研究代码和原理。
首先,看看dubbo消费端的主要调用流程(这里就不画图了),以后补充:
第一步:创建消费端代理:ReferenceConfig.createProxy,这里没什么特别,典型的C/S调用设计,都是通过JAVA动态代理或是Javassist的代理实现,比如mybatis mapper。
思考:假如我想实现API网关的dubbo协议路由怎么实现呢:毫无疑问必须使用ReferenceConfig的get.set以及init方法,下一篇将展开讨论实现细节..
第二步:直接跳到动态代理代码里的InvokerInvocationHandler:
这里忽略invoker的初始化(基本就是提供者注册+消费端订阅后初始化)
思考:假如让你实现一个RPC的客户端同步和异步调用你会怎么实现呢?
public class InvokerInvocationHandler implements InvocationHandler { private final Invoker<?> invoker; public InvokerInvocationHandler(Invoker<?> handler) { this.invoker = handler; } public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { String methodName = method.getName(); Class[] parameterTypes = method.getParameterTypes(); if (method.getDeclaringClass() == Object.class) { return method.invoke(this.invoker, args); } else if ("toString".equals(methodName) && parameterTypes.length == 0) { return this.invoker.toString(); } else if ("hashCode".equals(methodName) && parameterTypes.length == 0) { return this.invoker.hashCode(); } else { return "equals".equals(methodName) && parameterTypes.length == 1 ? this.invoker.equals(args[0]) : this.invoker.invoke(new RpcInvocation(method, args)).recreate(); } } }
第三步:AbstractClusterInvoker.invoke;
这里主要是加载一个列表:invoker list
public Result invoke(Invocation invocation) throws RpcException { this.checkWheatherDestoried(); //选择invoker List<Invoker<T>> invokers = this.list(invocation); LoadBalance loadbalance; if (invokers != null && invokers.size() > 0) { loadbalance = (LoadBalance)ExtensionLoader.getExtensionLoader(LoadBalance.class).getExtension(((Invoker)invokers.get(0)).getUrl().getMethodParameter(invocation.getMethodName(), "loadbalance", "random")); } else { loadbalance = (LoadBalance)ExtensionLoader.getExtensionLoader(LoadBalance.class).getExtension("random"); } RpcUtils.attachInvocationIdIfAsync(this.getUrl(), invocation); return this.doInvoke(invocation, invokers, loadbalance); } protected List<Invoker<T>> list(Invocation invocation) throws RpcException { List<Invoker<T>> invokers = this.directory.list(invocation); return invokers; }
第四步:真正加载invoker的实现:AbstractDirectory
注意这里有个路由选择的逻辑,也就是我们今天关注的重点:
router.route:具体的路由实现逻辑:比如ConditionRouter
思考:假如你的程序中需要实现动态的插件式功能,你如何实现呢:基本思路:配置中心配置+ 配置通知更新+插件根据优先级生效。---典型的分布式协调场景,ZK标配
相比静态的插件式功能实现思路:SPI思想,要灵活很多
public List<Invoker<T>> list(Invocation invocation) throws RpcException { if (this.destroyed) { throw new RpcException("Directory already destroyed .url: " + this.getUrl()); } else { List<Invoker<T>> invokers = this.doList(invocation); List<Router> localRouters = this.routers; if (localRouters != null && localRouters.size() > 0) { Iterator var5 = localRouters.iterator(); while(var5.hasNext()) { Router router = (Router)var5.next(); try { if (router.getUrl() == null || router.getUrl().getParameter("runtime", true)) { invokers = router.route(invokers, this.getConsumerUrl(), invocation); } } catch (Throwable var7) { logger.error("Failed to execute router: " + this.getUrl() + ", cause: " + var7.getMessage(), var7); } } } return invokers; } }
第五步:FailoverClusterInvoker.doInvoke:
这里通过负责均衡策略选择一个invoker,然后通过各种过滤器过滤。
最后:通过DubboInvoker发送数据给服务提供端。
了解完调用的主流程,我们基本就梳理清楚路由逻辑的实现在那个环节,以及需要注意设置那些属性,比如runtime.
但是经过我本人测试dubbo的路由功能并不稳定,所有用它做灰度发布不靠谱(但是通过权重设置实现rolling update还是比较靠谱的),不稳定因素有:
1.消费端没有及时订阅新增的服务提供者信息,而我们的需求是需要路由到增的服务提供者,导致ConditionRouter.matchCondition无法匹配成功,然后就不会使用路由规则。
2.路由规则没有及时通知更新到消费端,导致AbstractDirectory.setRouters一直没有添加ConditionRouter。(经过测试这个经常出现,这个问题比较严重,也有可能是我环境的问题)
学习感悟:总的来说通过今天的研究还是学到了一些常用的设计思路,而不仅仅是研究代码和原理。
发表评论
-
shiro落地的设计复杂度(最后总结)
2018-06-19 17:22 577经过1周的源码研究,终于对shiro的原理有了深刻的理解,基于 ... -
shiro login成功后保存了哪些数据
2018-06-19 17:05 1467shiro login成功后 保存了Principals 和 ... -
shiro 会话原理分析
2018-06-19 12:40 15891、从哪里获取sessionid每次请求都会尝试获取ses ... -
shiro内部原理分析
2018-06-15 17:07 2404一句话总结:会话域Context一路收集principal ... -
Zookeeper入门-001 源码环境搭建
2018-03-15 11:47 9031.到github下载源码:https://github.c ... -
shiro SecurityUtils.getSubject()深度分析
2018-01-12 17:38 489301.总的来说,SecurityUtils.getSubject ... -
@Async核心实现1 --------AsyncExecutionAspectSupport
2017-12-27 10:34 1979基本原理: 通过spring的扩展接口AbstractBea ... -
从零开始玩转JMX(1):简介和 Standard MBean
2017-08-23 15:20 0http://www.importnew.com/22299. ... -
java基础回顾
2017-08-15 11:21 0http://www.cnblogs.com/skywang1 ... -
mybatis-generator-maven-plugin 插件扩展 增加自定义方法
2017-08-10 16:50 0https://my.oschina.net/alexgaoy ... -
解决了DeferredResult请求长时间占用数据库连接的问题
2017-08-04 09:55 2354最近看了看开源项目appllo配置中心的源码,发现一个很有意思 ... -
httpclient发送webservice
2017-05-03 23:25 0http://aperise.iteye.com/blog/2 ... -
与大师面对面交流:Chris Richardson 来华布道微服务架构
2016-11-28 21:28 820http://www.daocloud.io/microser ... -
eclipse反编译
2016-11-23 20:48 0http://jingyan.baidu.com/articl ... -
spring security
2016-09-12 19:28 0http://www.importnew.com/5641.h ... -
浅析JPA中EntityManager无法remove entity的问题
2016-07-18 21:50 0http://rickqin.blog.51cto.com/1 ... -
Permission Denied(publickey) 解决
2016-07-14 19:18 27761.生成公钥和私钥放到C:\Users\itservice\. ... -
权限管理系统
2016-04-18 13:29 0http://git.oschina.net/ketayao/ ... -
Java工程师成神之路--面试必须复习的基础
2015-12-28 17:20 0http://www.open-open.com/news/v ... -
spring AOP何时添加AnnotationAwareAspectJAutoProxyCreator
2015-12-27 00:46 22341.spring AOP的原理都知道是从解析自定义标签时注册一 ...
相关推荐
藏区特产销售平台--论文.zip
文件放服务器下载,请务必到电脑端资源详情查看然后下载
文件太大放服务器下载,请务必到电脑端资源详情查看然后下载
文件太大放服务器下载,请务必到电脑端资源详情查看然后下载
文件太大放服务器下载,请务必到电脑端资源详情查看然后下载
文件放服务器下载,请务必到电脑端资源详情查看然后下载
该单片机项目可作为课程设计和期末大作业或者毕设,项目完整,有原理图和代码,需要的自行下载即可!
文件太大放服务器下载,请务必到电脑端资源详情查看然后下载
文件放服务器下载,请务必到电脑端资源详情查看然后下载
文件太大放服务器下载,请务必到电脑端资源详情查看然后下载
文件太大放服务器下载,请务必到电脑端资源详情查看然后下载
文件太大放服务器下载,请务必到电脑端资源详情查看然后下载
文件放服务器下载,请务必到电脑端资源详情查看然后下载
文件太大放服务器下载,请务必到电脑端资源详情查看然后下载
文件太大放服务器下载,请务必到电脑端资源详情查看然后下载
文件太大放服务器下载,请务必到电脑端资源详情查看然后下载
文件放服务器下载,请务必到电脑端资源详情查看然后下载
文件放服务器下载,请务必到电脑端资源详情查看然后下载
文件放服务器下载,请务必到电脑端资源详情查看然后下载
文件放服务器下载,请务必到电脑端资源详情查看然后下载