Dubbo服务治理之灰度发布方案(版本发布控制影响范围)

本文涉及的产品
服务治理 MSE Sentinel/OpenSergo,Agent数量 不受限
简介: Dubbo服务治理之灰度发布方案(版本发布控制影响范围)

image.png

背景:基于Dubbo服务的治理,是否可以支持业务级别的灰度发布、是否基于业务参数的路由转发。例如以GIS为例,当发布一个新版本时,是否可以以按照解析地址或合作伙伴来区分,版本发布之初,只希望地址为:广东省的解析请求发送到新版本,而其他的地址请求还是使用旧版;或者根据合作伙伴例如UCP(优享寄)的请求转发到新版本服务器,其他合作伙伴还是转发到旧版,实现业务级别的灰度发布,控制新版本的影响范围。例如OMS系统,可以根据合作伙伴,将重量级客户的请求转发到单独的服务器集群,确保其高可用。


本文将对上述议题结合Dubbo提供的功能,提出设计方案。


image.png

Dubbo的服务调用原理图:

434fea5d6f5c5d322820e2f573ed3833.jpg

客户端在发起RPC服务调用之前,在客户端首先从服务器列表中选择一个服务调用者,包含如下关键角色:


1、Directory


服务的动态发现,通常基于注册中心进行服务的动态注册与发现,其具体实现类为RegistryDirectory。


2、Router


路由实现,其含义是根据Directory发现的所有服务提供者列表中,进行路由选择,也就是根据一定的路由规则选择合适的服务提供者,为Directory发现的服务提供者列表子集,可以基于Condition或脚本(默认为JS脚本,其实现类为ScriptRouter)。


3、LoadBalance

 

负载均衡机制,其作用主要是根据负载均衡算法(随机、轮询)等算法,从(Directory-->Router)中返回的服务提供者列表中选择一个服务提供者,进行本次的RPC服务调用。


4、Cluster


集群(容错机制),就是当从服务提供者列表中按照负载均衡算法选择一个服务提供者,进行RPC服务调用后,发送了异常后的策略,例如failover(重试)、failfast(快速失败)等。

 

服务的灰度发布,其目标是希望根据请求,某些请求走新版本服务器,某些请求走旧版本服务器,其本质就是路由机制,即通过一定的条件来缩小服务的服务提供者列表,正好与Dubbo的Router相吻合。


有关于Dubbo的Router机制,请参考官方文档第【46、47、48】页,如果想从源码的角度了解其实现机制,请参考Dubbo路由机制概述

 

有了理论支持,下文将根据上述理论进行实战。

image.png

本示例代码需要完成的任务是,对DemoService#createUser服务,其用户机构ID(orgId)为1的走新版本(当前服务提取者列表的最后一台服务器),其他的请求走所有的服务器(除最后一台服务器)。

55c8d0a7020a6f3101d0f9b32f531ed0.png

1032f7938d112f83ef27e3ea83b17dac.jpg

由于是需要基于请求参数,本文给出基于JS脚本的路由机制,首先,当前版本的dubbo-admin可以后台页面维护基于条件表达式的路由规则,其界面如下:

293f1b15be631bfa3c5c58d2c6edb8dc.jpg

ad9e7dbabe3b92c99adcfcdd42932d07.jpg

备注:并且当前dubbo-admin版本,并不支持基于JS表达式的路由规则,如果手动建立基于表达式的路由规则,其页面将无法列出路由表达式,其界面如下:


5e1bacd7e24bb4c19b3e0b4884f665d4.jpg


JS脚本


各个项目,各个服务需要根据自身的需求,定义如下脚本:

 1/**
 2 * DemoService router,针对不同的方法,可能需要各自提供,主要是参数的获取,不同的过滤规则
 3 * 针对参数进行路由过滤
 4 * 
 5 * 本示例针对 DemoSerivce# ResponseResult createUser(User user) 方法,根据user的orgId进行路由选择
 6 * @param invokers
 7 * @param invocation
 8 * @param context
 9 * @returns
10 */
11function demoService_createUser_router(invokers, invocation, context) {
12    if(invokers == null || invokers.size() < 1) {
13        return invokers;
14    }
15
16    if(!"createUser".equals(invocation.getMethodName())) { // 如果方法不匹配,默认无条件通过该路由规则
17        return invokers;
18    }
19
20    var availableInvokers = new java.util.ArrayList(invokers.size());
21    for (var i=0;i<invokers.size(); i++) {    // 先选择可用的服务提供者列表
22        if(invokers.get(i).isAvailable()) {
23            availableInvokers.add(invokers.get(i));
24        }
25    }
26
27    var invArguments = invocation.getArguments();
28    if(invArguments == null || invArguments.length == 0) { // 如果参数为空,无法根据参数进行路由选择
29        return availableInvokers; 
30    }
31
32    // 获取需要进行路由的参数,这里使用第一个参数 ,这里各自根据各自的业务 进行获取,本实例默认使用第一个参数
33    var firstArgument = invArguments[0];
34    var orgId = firstArgument == null ? "" : firstArgument.getOrgId();
35
36
37    if(orgId == 1 || orgId == "1") { // 如果orgId == 1 ,只走最后一个节点,其余的走其他节点
38        var selectInvokers = new java.util.ArrayList(1);
39        selectInvokers.add(availableInvokers.get(availableInvokers.size()-1));
40        return selectInvokers;
41    } else {
42        var selectInvokers = new java.util.ArrayList(availableInvokers.size()-1);
43        for(var i=0;i<availableInvokers.size()-1; i++) {
44            selectInvokers.add(availableInvokers.get(i));
45        }
46        return selectInvokers;
47    }
48}


向注册中心注册JS脚本路由规则


上文已经说明,目前的dubbo-admin不支持在界面上注册路由规则,现给出基于JAVA代码来编写注册程序:

 1public static void main(String[] args) throws Exception{
 2    URL registryUrl = URL.valueOf("zookeeper://127.0.0.1:2181");
 3    ZookeeperRegistryFactory zookeeperRegistryFactory = new 
 4                       ZookeeperRegistryFactory();
 5   zookeeperRegistryFactory.setZookeeperTransporter(new 
 6        CuratorZookeeperTransporter());
 7   Registry zookeeperRegistry = (ZookeeperRegistry) 
 8             zookeeperRegistryFactory.createRegistry(registryUrl);
 9   URL routerURL = 
10          URL.valueOf("script://0.0.0.0/com.alibaba.dubbo.demo.Demo
11                Service?category=routers&dynamic=false&enabled=true&fo
12                rce=false&name=demoService_createUser_router&priority=
13          0&runtime=true");
14   routerURL = routerURL.addParameter("rule", 
15   URL.encode(get_demoService_createUser_router()));
16   zookeeperRegistry.register(routerURL);     // 注册
17   // zookeeperRegistry.unregister(routerURL); // 取消注册
18}

一旦运行上述代码,将会动态注册URL,服务提供者无需重启,下次服务调用后会自动生效(其背后原理是基于注册中心的动态发现)。


上述示例代码,我已经在本地环境,已能成功运行,并达到预期效果,公司项目需要根据自身的特点,特别服务方法的参数(例如合作伙伴ID的获取方式),以及路由需求来定制编写其路由脚本(js脚本)。


总结


上述展示了Dubbo服务基于业务灰度发布的方案,以及基于合作伙伴的服务隔离机制(根据服务调用业务参数来决定服务调用者的筛选)。主要是展示了基于脚步的路由规则,其条件表达式的路由规则请参考其Demo,其核心理论支持是Dubbo提供的Router,在进行负载均衡前,根据路由规则对服务提供者列表进行筛选。


最后说明一下:本方案主要展示基于脚本的路由选择策略,通常在实际使用过程中基于条件路由较多,例如基于消费者IP进行条件选择。


相关实践学习
基于MSE实现微服务的全链路灰度
通过本场景的实验操作,您将了解并实现在线业务的微服务全链路灰度能力。
相关文章
|
5月前
|
Dubbo Cloud Native Java
干翻Dubbo系列第二篇:Dubbo3相对其他版本的升级
干翻Dubbo系列第二篇:Dubbo3相对其他版本的升级
|
8月前
|
JavaScript Dubbo 应用服务中间件
Apache Dubbo 首个 Node.js 3.0-alpha 版本正式发布
本文分享了 Dubbo3 Node.js 首个正式版本,演示基于 Triple 协议的 RPC 通信模式,包括代码生成、服务发布和服务访问等过程。
|
5月前
|
Dubbo 应用服务中间件 API
Go语言微服务框架重磅升级:dubbo-go v3.2.0 -alpha 版本预览
随着 Dubbo3 在云原生微服务方向的快速发展,Dubbo 的 go 语言实现迎来了 Dubbo3 版本以来最全面、最大幅度的一次升级,这次升级是全方位的,涉及 API、协议、流量管控、可观测能力等。
|
5月前
|
Dubbo Java 应用服务中间件
Dubbo 3.3.0-beta 版本正式发布
Dubbo 3.3.0-beta 版本正式发布
|
5月前
|
Dubbo Java 应用服务中间件
Dubbo 3.3.0-beta 版本正式发布
近日,Apache Dubbo 发布了 3.3 分支大版本 3.3.0-beta.1,相较于 3.2 系列版本,3.3.0-beta 引入了一些重量级的功能升级,按照社区规划,3.3 也将是 Dubbo3 非常重要的一个里程碑大版本,在 3.3.0 首个正式版本之后 Dubbo3 将正式进入长期稳定维护态,即标志着 Dubbo3 作为面向云原生时代的下一代微服务框架将具备规划的所有核心功能。
|
8月前
|
Dubbo Java 应用服务中间件
启动速度提升 10 倍:Apache Dubbo 静态化方案深入解析
Apache Dubbo 集成了 GraalVM Native Image 后 ,Dubbo 应用能够做到毫秒级启动,启动速度降低了十倍、资源损耗降低了四倍,为降本增效提供了更多的想象空间。
启动速度提升 10 倍:Apache Dubbo 静态化方案深入解析
|
8月前
|
JavaScript Dubbo 应用服务中间件
Apache Dubbo 首个 Node.js 3.0-alpha 版本正式发布
Apache Dubbo 首个 Node.js 3.0-alpha 版本正式发布
|
8月前
|
Dubbo JavaScript 应用服务中间件
浏览器可直接访问 Dubbo、gRPC 后端微服务,Dubbo-js 首个alpha 版本来了!
浏览器可直接访问 Dubbo、gRPC 后端微服务,Dubbo-js 首个alpha 版本来了!
|
8月前
|
Dubbo JavaScript 应用服务中间件
浏览器可直接访问 Dubbo、gRPC 后端微服务,Dubbo-js 首个 alpha 版本来了!
Dubbo-js 已于 9 月份发布支持 Dubbo3 协议的首个 alpha 版本,它的发布将有机会彻底改变微服务前后端的架构与通信模式,让你能直接在浏览器页面或 web 服务器中访问后端 Dubbo、gRPC 服务。
浏览器可直接访问 Dubbo、gRPC 后端微服务,Dubbo-js 首个 alpha 版本来了!
|
10月前
|
XML 负载均衡 Dubbo
Dubbo的高级特性:服务治理篇
大家好,我是王有志。今天我们一起来了解并学习如何使用Dubbo在服务治理方面提供的高级特性。
76 1