spring cloud 灰度发布,springboot灰度发布

  spring cloud 灰度发布,springboot灰度发布

  00-1010 1.什么是灰度释放?2.灰度释放的作用是什么?3.灰度发布的实现:网关到服务,服务到服务3.1网关到服务代码实现3.2网关到服务代码实现。

  

目录

灰度释放,也叫金丝雀释放,是一种在系统升级时可以平滑过渡的释放方式。可以对其进行A/B测试,即一部分用户继续使用产品特性A,一部分用户开始使用产品特性B,如果用户对B没有异议,则逐步扩大范围,将所有用户迁移到B,灰度发布可以保证整个系统的稳定性,在初始灰度下发现问题并进行调整,保证其影响。

 

  关于金丝雀放生名字的由来:矿工去矿上验证是否有瓦斯。金丝雀对气体非常敏感,通过观察金丝雀的反应来判断是否安全是安全的。

  00-1010 1.减少释放的影响。虽然功能已经在测试环境中测试过了,但终究没有发布到生产环境中。如果让小部分用户先使用新版本,提前发现bug或性能问题,提前修复,可以降低新版本的影响;

  2.通过新旧版本的对比,观察新版本的效果。结合工作中使用灰度出版的实践和对其他大厂灰度出版的调查,总结出以下灰度出版方案。

  

1.什么是灰度发布?

 

  3.1.1总体流程

  指定灰度规则-预编码规则-springcloud自定义元数据

  3.1.2前端环境(需要自己搭建四个服务)

  Eureka:注册表zuul:网关服务-v1:集群服务v1版本服务-v2:集群服务v2版本3.1.3核心代码

  pom.xml

  !-通过元数据实现灰度路由-依赖groupIdio.jmnarloch/groupId工件Ribbon-Discovery-Filter-Spring-Cloud-Starter/工件ID版本2 . 1 . 0/Version/依赖灰度过滤器(核心代码)

  @Componentpublic类GrayFilter扩展ZuulFilter { @ Override public String filter type(){ return filter constants。PRE _ TYPE} @ Override public int filter order(){ return 0;} @Override公共布尔should filter(){ return true;//返回false关闭过滤器} @ auto wired private commongrayruledaocustom commongrayruledaocustom;@Override公共对象run()抛出ZuulException { request context current context=request context . getcurrent context();http servlet request request=current context . get request();string userId=request . get header( userId );//根据用户id检查规则和数据库,String rule=findRuleById(userId);//金丝雀if (v1 )。equals(rule)){ ribbonfilterContextHolder。GetCurrentContext()。添加(版本, v1 );//普通用户} else if (v2 )。equals(rule)){ ribbonfilterContextHolder。GetCurrentContext()。添加(版本, v2 );}返回null}//用于搜索库的伪代码私有St

  ring findRuleById(String userId) { Map<String, String> map = new HashMap(); map.put("9527", "v1"); map.put("9528", "v2"); return map.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工具类

  

public class RibbonParameters { private static final ThreadLocal local = new ThreadLocal(); public static <T> T get() { return (T) local.get(); } public static <T> void set(T t) { local.set(t); }}

切面获取version的值

 

  

@Aspect@Componentpublic class RequestAspect { @Pointcut("execution(* com.mashibing.apipassenger.controller..*Controller*.*(..))") private void anyMehtod() { } @Before(value = "anyMehtod()") public void before(JoinPoint joinPoint) { HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); String version = request.getHeader("version"); //方式二: HashMap<Object, Object> map = new HashMap<>(); map.put("version",version); RibbonParameters.set(map); }

rule规则

 

  

import com.netflix.client.config.IClientConfig;import com.netflix.loadbalancer.AbstractLoadBalancerRule;import com.netflix.loadbalancer.ILoadBalancer;import com.netflix.loadbalancer.Server;import com.netflix.niws.loadbalancer.DiscoveryEnabledServer;import org.springframework.context.annotation.Configuration; import java.util.List;import java.util.Map; @Configurationpublic class GrayRule extends AbstractLoadBalancerRule { @Override public void initWithNiwsConfig(IClientConfig clientConfig) { } @Override public Server choose(Object key) { return choose(getLoadBalancer(), key); } private Server choose(ILoadBalancer lb, Object key) { System.out.println("灰度,rule"); Server server = null; while (server == null) { List<Server> reachableServers = lb.getReachableServers(); //获取当前线程的参数 用户 version=v1 Map<String, String> map = (Map<String, String>) RibbonParameters.get(); String version = ""; if (map != null && map.containsKey("version")) { version = map.get("version"); } System.out.println("当前rule,version=" + version); //遍历服务列表选取用户服务 for (int i = 0; i < reachableServers.size(); i++) { server = reachableServers.get(i); //用户的version知道了,服务自定义的meta不知道 Map<String, String> metadata = ((DiscoveryEnabledServer) server).getInstanceInfo().getMetadata(); String metaMap = metadata.get("version"); //用户的version知道了,服务meta也知道了 if (version.trim().equals(metaMap)) { return server; } } } return null; }}

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

 

  

 

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

  

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

删除该包即可

 

  删除后重新运行

  

 

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

  自此灰度发布完成。

  到此这篇关于SpringCloud实现灰度发布的方法步骤的文章就介绍到这了,更多相关SpringCloud 灰度发布内容请搜索盛行IT以前的文章或继续浏览下面的相关文章希望大家以后多多支持盛行IT!

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: