背景介绍

现在很多的公司都在用dubbo、springcloud做为服务化/微服务的开发框架,服务化之后应用越来越多,链路越来越长,服务环境的治理变的很困难。比如:研发团队的人很多的,同时有几个分支在开发和测试,会造成多个同名的服务存在,为了避免不同feature之间的服务不串调,很多研发人员会改服务的版本号来避免这种情况;还有一种情况是因为修改服务版本号,调用链链路上所有的节点都需要修改,存在浪费机器资源的现象。

需求场景描述

  1. 稳定的测试环境一般是有测试的同学维护的,上面的代码一般是验证完成(即将上线)的分支,或者就是和线上代码保持一致的分支(基准代码);
  2. 下图中需求1是正在开发的某个需求,它涉及了2个需要改动的应用A和B,由于他们在需求1里(代码也切分支),我们称需求1里面的应用A为A1,需求1里面的应用B为B1;
  3. 同理,需求2也是正在开发的某个需求,因为它和需求1同时开发,涉及的应用也有重合,所以称为并发需求。需求2中的应用A为A2,应用B为B2,应用E为E2;
  4. 在不修改服务版本号的情况下,需求1的研发人员希望A1直接调用下游B,然后B调用C1,因为应用B、C、D在需求1里面是没有代码变更的,所以完整的调用链路如下:A1->B->C1->D->E
  5. 需求2中有代码变更的应用是A2、B2、E2,不需要更变的是C、D,所以完成的调用链路如下:A2->B2->C->D->E2

总结起来:
研发只希望调用本需求内应用,如果链路中某个应用没有代码变更,则调用稳定环境中的应用(保证链路能走通,并且把这种逻辑路由的关系传递到下游应用中)

谈dubbo路由

dubbo框架内部自带路由的,它支持2种路由规则:ConditionRouter、ScriptRouter,MockInvokersSelector暂时不讨论。

1、 其中ConditionRouter表示条件路由,条件表达式以 => 分割为whenRule和thenRule:

例子:*

condition://0.0.0.0/com.foo.BarService?category=routers&dynamic=false&rule=" + URL.encode("host = 10.20.153.10 => host = 10.20.153.11"

  • 从url根据RULE_KEY获取路由条件路由内容
  • rule.indexOf("=>") 分割路由内容: =>前面是消费者条件(when),=>后面是provider的条件(then)
  • 分别调用parseRule(rule) 解析路由为whenRule和thenRules

ConditionRouter执行route方法:

  • 如果url不满足when条件即过来条件, 不过滤返回所有invokers
  • 遍历所有invokers判断是否满足then条件, 将满足条件的加入集合result
  • Result不为空,有满足条件的invokers返回
  • Result为空, 没有满足条件的invokers, 判断参数FORCE_KEY是否强制过来,如果强制过滤返回空, 不是返回所有即不过滤

ConditionRouter的点评

ConditionRouter并不是适合我们的需求,因为我们需要是配合简单运维实现自动路由,不需要开发人员写额外代码和配置,很显然ConditionRouter=>后面的then条件是固定的一个provider或者一组provider,而不能动态路由;第二点是ConditionRouter在稳定测试环境的应用上也需要在URL里面打上路由标识,这就违反了我们初衷:不需要开发人员写额外代码和配置

2、 ScriptRouter表示脚本路由

通过url的RULE_KEY参数获取脚本内容,然后通过java的脚本引擎执行脚本代码, dubbo的测试用例都是通过javascript作为脚本但是理论上也支持groovy, jruby脚本

  • 从url获取脚本类型javascript, groovy等等
  • 从url根据RULE_KEY获取路由规则内容
  • 根据脚本类型获取java支持的脚本执行引擎

ScriptRouter的点评

ScriptRouter虽然比ConditionRouter灵活,可以在消费端执行脚本来控制路由的逻辑,但是还是有同样的问题,对于稳定的测试环境里的应用也需要配置路由脚本,不能做到真正的少配置、少运维、少写额外代码

逻辑路由的方案

我们分析了场景和需求,又分析现有的dubbo路由方案的不满足,现在来来看一下一种可行的方案:

  1. 逻辑路由provider和consumer都通过URL来获取路由标识
  2. 最小运维开支:通过申请应用环境的时候,在机器打上环境变量
  3. 最小的dubbo框架改动:在LoadBalance和AbstractClusterInvoker上修改逻辑路由方案

show me code

具体实现的代码,我放在github上,变更也不大,分支

  1. 在LoadBalance和AbstractClusterInvoker上修改逻辑路由主要逻辑
  2. 在provider注册服务的URL时,加上逻辑路由的标识
  3. dubbox新增加了一个依赖:logical-router,这是我自己写的小的jar包,方便之后做扩展(比如rest入口的应用程序,自启动的应用程序等等)
  4. 运维相关:只需要给申请相同的逻辑路由标识应用的机器,打上相同的环境变量:LOGICAL_ROUTER_ENV

diff文件

更方便的查看变更:diff文件

一种dubbo逻辑路由方案(服务化隔离环境)的更多相关文章

  1. 一种dubbo逻辑路由方案

    背景介绍 现在很多的公司都在用dubbo.springcloud做为服务化/微服务的开发框架,服务化之后应用越来越多,链路越来越长,服务环境的治理变的很困难.比如:研发团队的人很多的,同时有几个分支在 ...

  2. 暑假打工 2 个 月,让我明白了 Keepalived 高可用的三种路由方案

    暑假打工 2 个 月,让我明白了 Keepalived 高可用的三种路由方案 这是悟空的第 158 篇原创文章 原文链接:首发悟空聊架构 官网:www.passjava.cn 你好,我是悟空. 前言 ...

  3. 三种UIScrollView嵌套实现方案

    背景 随着产品功能不断的迭代,总会有需求希望在保证不影响其他区域功能的前提下,在某一区域实现根据选择器切换不同的内容显示. 苹果并不推荐嵌套滚动视图,如果直接添加的话,就会出现下图这种情况,手势的冲突 ...

  4. (转载)MySQL数据库的几种常见高可用方案

    转自: https://yq.aliyun.com/articles/74454   随着人们对数据一致性的要求不断的提高,越来越多的方法被尝试用来解决分布式数据一致性的问题,如MySQL自身的优化. ...

  5. 基于 OpenResty 的动态服务路由方案

    2019 年 5 月 11 日,OpenResty 社区联合又拍云,举办 OpenResty × Open Talk 全国巡回沙龙武汉站,又拍云首席布道师在活动上做了< 基于 OpenResty ...

  6. 老猿学5G扫盲贴:中国移动5G融合计费漫游计费架构和路由方案

    专栏:Python基础教程目录 专栏:使用PyQt开发图形界面Python应用 专栏:PyQt+moviepy音视频剪辑实战 专栏:PyQt入门学习 老猿Python博文目录 老猿学5G博文目录 一. ...

  7. ASP.NET Core 2.2 : 十六.扒一扒新的Endpoint路由方案

    ASP.NET Core 从2.2版本开始,采用了一个新的名为Endpoint的路由方案,与原来的方案在使用上差别不大,但从内部运行方式上来说,差别还是很大的.上一篇详细介绍了原版路由方案的运行机制, ...

  8. 深度点评五种常见WiFi搭建方案

    总结十年无线搭建经验,针对企业常见的五种办公室无线网络方案做个简要分析,各种方案有何优劣,又适用于那种类型的企业. 方案一:仅路由器或AP覆盖 简述:使用路由器或AP覆盖多个无线盲区,多个AP的部署实 ...

  9. 基于ngx_lua的动态服务路由方案

    基于ngx_lua的动态服务路由方案 http://geek.csdn.net/news/detail/131497

随机推荐

  1. 求第k小的元素

    用快排解决: 用快排,一趟排序后,根据基准值来缩小问题规模.基准值的下角标i 加1 表示了基准值在数组中第几小.如果k<i+1,那就在左半边找:如果k>i+1那就在右半边找.当基准值的下角 ...

  2. 1-2 Spring 的基本使用

    1.Spring容器的配置文件applicationContext.xml的引入 名称可以自己定义 <?xml version="1.0" encoding="UT ...

  3. C++实现Date日期类

    定义一个Date类,包含三个属性年.月.日 实现了如下功能: 年月日的增加.减少:2017年10月1日加上100个月30天是2025年5月31日 输出某天是星期几:2017年10月1日是星期日 判断某 ...

  4. Lucene-01:创建索引

    我们在D盘下建一个文件夹叫lucene,lucene内再建两个文件夹,一个叫example,一个叫index01.example文件夹下三个txt文件,a.txt内容为hello java,b.txt ...

  5. 用Canvas写一个简单的游戏--别踩白块儿

    第一次写博客也不知怎么写,反正就按照我自己的想法来吧!怎么说呢?还是不要扯那些多余的话了,直接上正题吧! 第一次用canvas写游戏,所以挑个简单实现点的来干:别踩白块儿,其他那些怎么操作的那些就不用 ...

  6. Docker自动化部署方案

    一 概述 Docker发布版本应该与现有的版本发布尽量一致,参考jenkins的版本发布过程:我认为maven库和docker库有很多类似的地方,因此打包过程参考maven的打包过程:重点实现dock ...

  7. Konckout第四个实例:组合类型数据绑定 -- 日期双向绑定显示

    <!doctype html> <html > <head> <meta http-equiv="Content-Type" conten ...

  8. Linux下的进程与线程(一)—— 进程概览

    进程是操作系统分配资源的基本单位.线程是操作系统进行运行和调度的基本单位. 进程之间可以切换,以便轮流占用CPU,实现并发.一般进程运行在用户模式下,只能执行指令集中的部分指令. 当进程进行上下文切换 ...

  9. 多目标跟踪(MOT)论文随笔-POI: Multiple Object Tracking with High Performance Detection and Appearance Feature

    网上已有很多关于MOT的文章,此系列仅为个人阅读随笔,便于初学者的共同成长.若希望详细了解,建议阅读原文. 本文是tracking by detection 方法进行多目标跟踪的文章,最大的特点是使用 ...

  10. Linux进程间通信-消息队列(mqueue)

    前面两篇文章分解介绍了匿名管道和命名管道方式的进程间通信,本文将介绍Linux消息队列(posix)的通信机制和特点. 1.消息队列 消息队列的实现分为两种,一种为System V的消息队列,一种是P ...