SpringCloud如何实现灰度发布(springcloud,开发技术)

时间:2024-04-25 23:19:01 作者 : 石家庄SEO 分类 : 开发技术
  • TAG :

1.什么是灰度发布?

灰度发布又称金丝雀发布,是在系统升级的时候能够平滑过渡的一种发布方式。在其上可以进行A/B测试,即让一部分用户继续用产品特性A,一部分用户开始用产品特性B,如果用户对B没有什么反对意见,那么逐步扩大范围,把所有用户都迁移到B上面来。灰度发布可以保证整体系统的稳定,在初始灰度的时候就可以发现、调整问题,以保证其影响度。

关于金丝雀发布名称的来历:矿工下要矿井,要验证是否有瓦斯,金丝雀对瓦斯很敏感,通过观察金丝雀的反应判断是否安全。

2.灰度发布有什么作用?

1.降低发布带来的影响,虽然功能都在测试环境测过,但毕竟没有发布到生产环境,如果先让少部分用户先使用新版本,提前发现bug,或者性能问题,提前做好修复,就可以降低新版本带来的影响;

2.通过对新老版本的对比,观察新版本带来的效果。结合工作中使用到的灰度发布实践和对其他大厂的灰度发布调研,总结了以下灰度发布方案。

3.灰度发布的实现方式:网关到服务,服务到服务

3.1网关到服务代码实现

3.1.1整体流程

指定灰度规则->预制代码规则->springcloud自定义metadata

3.1.2前置环境(需要自行搭建四个至少服务)

  • eureka:注册中心

  • zuul:网关

  • service-v1:集群服务v1版本

  • service-v2:集群服务v2版本

3.1.3核心代码

pom.xml

<!--实现通过metadata进行灰度路由--><dependency><groupId>io.jmnarloch</groupId><artifactId>ribbon-discovery-filter-spring-cloud-starter</artifactId><version>2.1.0</version></dependency>

灰度过滤器(核心代码)

@ComponentpublicclassGrayFilterextendsZuulFilter{@OverridepublicStringfilterType(){returnFilterConstants.PRE_TYPE;}@OverridepublicintfilterOrder(){return0;}@OverridepublicbooleanshouldFilter(){returntrue;//returnfalse关闭该过滤器}@AutowiredprivateCommonGrayRuleDaoCustomcommonGrayRuleDaoCustom;@OverridepublicObjectrun()throwsZuulException{RequestContextcurrentContext=RequestContext.getCurrentContext();HttpServletRequestrequest=currentContext.getRequest();StringuserId=request.getHeader("userId");//根据用户id查规则查库,Stringrule=findRuleById(userId);//金丝雀if("v1".equals(rule)){RibbonFilterContextHolder.getCurrentContext().add("version","v1");//普通用户}elseif("v2".equals(rule)){RibbonFilterContextHolder.getCurrentContext().add("version","v2");}returnnull;}//查库的伪代码privateStringfindRuleById(StringuserId){Map<String,String>map=newHashMap();map.put("9527","v1");map.put("9528","v2");returnmap.get(userId);}}

3.2网关到服务代码实现

3.2.1整体流程

springcloud自定义metadata->获取当前用户的版本->遍历服务获取服务的的版本,返回合适的服务

3.2.2前置环境(需要自行搭建5个至少服务)

  • eureka:注册中心

  • service-A:服务调用方

  • service-v1:集群服务v1版本

  • service-v2:集群服务v2版本

3.2.3核心代码

threadlocal工具类

publicclassRibbonParameters{privatestaticfinalThreadLocallocal=newThreadLocal();publicstatic<T>Tget(){return(T)local.get();}publicstatic<T>voidset(Tt){local.set(t);}}

切面获取version的值

@Aspect@ComponentpublicclassRequestAspect{@Pointcut("execution(*com.mashibing.apipassenger.controller..*Controller*.*(..))")privatevoidanyMehtod(){}@Before(value="anyMehtod()")publicvoidbefore(JoinPointjoinPoint){HttpServletRequestrequest=((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest();Stringversion=request.getHeader("version");//方式二:HashMap<Object,Object>map=newHashMap<>();map.put("version",version);RibbonParameters.set(map);}

rule规则

importcom.netflix.client.config.IClientConfig;importcom.netflix.loadbalancer.AbstractLoadBalancerRule;importcom.netflix.loadbalancer.ILoadBalancer;importcom.netflix.loadbalancer.Server;importcom.netflix.niws.loadbalancer.DiscoveryEnabledServer;importorg.springframework.context.annotation.Configuration;importjava.util.List;importjava.util.Map;@ConfigurationpublicclassGrayRuleextendsAbstractLoadBalancerRule{@OverridepublicvoidinitWithNiwsConfig(IClientConfigclientConfig){}@OverridepublicServerchoose(Objectkey){returnchoose(getLoadBalancer(),key);}privateServerchoose(ILoadBalancerlb,Objectkey){System.out.println("灰度,rule");Serverserver=null;while(server==null){List<Server>reachableServers=lb.getReachableServers();//获取当前线程的参数用户version=v1Map<String,String>map=(Map<String,String>)RibbonParameters.get();Stringversion="";if(map!=null&&map.containsKey("version")){version=map.get("version");}System.out.println("当前rule,version="+version);//遍历服务列表选取用户服务for(inti=0;i<reachableServers.size();i++){server=reachableServers.get(i);//用户的version知道了,服务自定义的meta不知道Map<String,String>metadata=((DiscoveryEnabledServer)server).getInstanceInfo().getMetadata();StringmetaMap=metadata.get("version");//用户的version知道了,服务meta也知道了if(version.trim().equals(metaMap)){returnserver;}}}returnnull;}}

注意:提前踩坑,No qualifying bean of type &lsquo;com.netflix.loadbalancer.IRule&lsquo; available: expected single matching bean

SpringCloud如何实现灰度发布

当是觉得很奇怪,命名自己只定义了grayRule负载均衡策略规则,metadataAwareRule这个我代码中并没有。经过排查自己使用在pom中引入了Ribbon的包,该包默认会带负载均衡策略规则。导致有多个规则,从而报错。

<dependency><groupId>io.jmnarloch</groupId><artifactId>ribbon-discovery-filter-spring-cloud-starter</artifactId><version>2.1.0</version></dependency>

删除该包即可

删除后重新运行

SpringCloud如何实现灰度发布

服务与服务的灰度发布的另外一种方式:可以在requestAspect中获取到version后,直接比对版本:RibbonFilterContextHolder.getCurrentContext().add("version", "v1"),这种凡是与网关与服务的灰度发布相似。

 </div> <div class="zixun-tj-product adv-bottom"></div> </div> </div> <div class="prve-next-news">
本文:SpringCloud如何实现灰度发布的详细内容,希望对您有所帮助,信息来源于网络。
上一篇:jquery如何判断元素是否有子节点下一篇:

18 人围观 / 0 条评论 ↓快速评论↓

(必须)

(必须,保密)

阿狸1 阿狸2 阿狸3 阿狸4 阿狸5 阿狸6 阿狸7 阿狸8 阿狸9 阿狸10 阿狸11 阿狸12 阿狸13 阿狸14 阿狸15 阿狸16 阿狸17 阿狸18