多环境灰度之Spring Cloud Alibaba

124 阅读3分钟

Nacos基础

我们基于Nacos的配置管理模型,来实现配置文件和服务的隔离

基本概念:不同namespace下的服务之间不可以访问,但是同一个namespace下的服务可以跨group访问。因此我们利用这个特性,将基线环境的服务和配置放置在默认的DEFAULT_GROUP下,特性环境的配置和服务放在特性分支的group下。

元数据:配置在nacos服务实例上的信息标签,可以用于服务标签、服务版本号、服务实例权重、路由规则、安全策略等描述服务的数据,也可以用户灰度路由。

在此,我们选择以group的方式来进行服务灰度路由(元数据也可)。下面我们将拿实际的操作来展示如何在Spring Cloud Alibaba架构下,实现微服务多环境部署。

Spring Cloud 微服务

服务基本配置

微服务应用

配置管理

应用管理

特性环境

对应左图,服务实例全在

对应右图,灰度product实例下线

在此,我们看出来,正常流量(未携带灰度请求头标签)全部都路由到基线服务中,灰度服务实例,并未有任何日志打印。

在此,我们看出来,携带了灰度请求头标识的流量,全部都路由到灰度服务中,正常服务实例,并未有任何日志打印。

mysql

我们这里在同一个mysql实例中,设置有两张表,base库(基线环境),gray库(特性环境),两个库里面的表名和结构都一致,只是base库里面的数据都带有base后缀,gray库里面的数据都带有gray后缀,方便我们区分数据来源。

我们将通过http请求,组装UserDTO对象,包含user,product,detail表中的数据。

基线服务,特性服务都存活

基线服务product下线,即特性环境实例数缺失的情况

此时我们猜测,返回的UserDTO对象应该是什么呢?

下面,让我们来一趟究竟。

Product灰度实例下线,让我们再来请求一次

结论是,及时product灰度实例下线了,灰度流量依然可以通过基线product实例,路由到灰度gray库,获取到product表中的数据。

redis

redis中,我们默认库0为基线环境的库,库1为灰度环境的库。基线环境库中的所有数据都是base前缀,灰度环境库中的所有数据都是gray前缀

服务实例全在

product灰度服务实例下线

kafka

基线环境,我们监听的是topic是 topic-a,灰度环境我们监听的是topic是topic-a-gray

正常流量,监听的是基线环境的topic-a,消息内容为base

接受消息,打印的topic为topic-a,消息内容为base,符合预期

灰度流量,监听的topic是topic-a-gray,消息内容为gray

接受消息,打印的topic为topic-a-gray,消息内容为gray,符合预期

总结

通过以上实验,达到了我们初步制定的目标方案,通过逻辑隔离的方案,在节约成本的条件下,实现了全链路灰度的诉求。

挑战

在实际开发实践中,我们会遇到各种各样的挑战,如何对流量打标签,如何将不用的流量路由到不同的服务,不同的mysql数据库,不同的redis库,不同的Kafka topic,feign调用如何传递灰度标签,如果跨nacos group访问服务实例,流量标签在跨threadlocal中如何防止跨线程的丢失,基线服务如何动态的获取特性环境的数据库,redis等配置信息。

这些挑战仅仅简单的通过文档是无法表达出细节实现的。

Talk is cheap. Show me your code

github仓库