0.参考
文章1 ribbon中应用HystrixRequestVariableDefault的一个注意事项
文章2 SpringCloud灰度公布实际(附源码) zuul实现的能够参考。
1.思路
革新gataway的### Weight Route Predicate Factory,在指定权重的同时指定每个对应权重的服务的版本号。次要须要改写的中央是要在分流之后,将版本号传给ribbon,ribbon在做负载平衡抉择的时候,依据传入的版本号,与服务的eureka.matedata中的version匹配,从而达到灰度公布的目标。
gateway的配置相似如下,VersionWeight为重写的断言工厂。
- id: temp_old uri: lb://TEMPLATE predicates: - Path=/temp/** - VersionWeight=group1, 10, v1 filters: - StripPrefix=1 - id: temp_new uri: lb://TEMPLATE predicates: - Path=/temp/** - VersionWeight=group1, 1, v2 filters: - StripPrefix=1
2.考察革新点
debug后晓得了整个申请程序
客户端-> gateway filter -> LoadBalancerClientFilter -> (如果应用ribbon) RibbonLoadBalancerClient-> (某个Rule) XXXAvoidanceRule -> (对应的 Predicate) XXXAvoidancePredicate
所以抉择的服务的要害就是Ribbon的rule和Predicate
步骤
- 写一个grayContext, 基于threadlocal解决version的上下文传递。
- 自定义负载策略:负载策略的要害是Rule 和 Predicate, Rule 继承 PredicateBasedRule, Predicate 继承 AbstractServerPredicate, 实现Predicate 中的 apply办法 此办法是负载策略外围(逻辑:从grayContext获取version,与服务的eureka.matedata中的version匹配。匹配上则为指标服务)
- 改写权重断言策略:改写WeightRoutePredicateFactory,在Factory 分流实现后,把路由中配置的 version 放入到grayContext 中。并且要将vesion 放入到 request的head中,用来向下传递。
下面是对gateway的革新,通过革新后,gateway散发的时候就依据version能指定申请的服务器,接下来是微服务间通过fegin或者restTemplate调用时的革新,目标是将version持续往下传递
- 对request申请拦挡:在微服务中对request申请进行拦挡,将request中的version放到grayContext中
- 对fegin增加拦截器:实现RequestInterceptor,从grayContext中取出version放在头部中。fegin的loadbanced也是基于ribbon的,所以应用自定义负载策略进行散发,策略和gateway统一。
- 如果应用restTemplate,增加拦截器:实现ClientHttpRequestInterceptor,从grayContext中取出version放在头部中。
这样就将version串联起来,从而实现了指定流量到对应的服务。
留神点
如果断路器应用Hystrix,要留神Hystrix用信号量隔离,没问题,如果应用线程池隔离,咱们基于threadlocal解决version就有效了,
hystrix有提供对应的办法 应用 HystrixRequestVariableDefault
参考文章1这篇文章中提到的应用形式,能了解HystrixRequestVariableDefault是个怎么的用法,其作用和threadlocal相似。
3.待解决问题
- 不应用ribbon的状况,引入spring-cloud-loadbalancer, loadbalancer 和 ribbon差蛮多,不反对主动刷新serverlist,只有一个RoundRobinLoadBalancer。 会应用ReactiveLoadBalancerClientFilter,要通过实现ReactorServiceInstanceLoadBalancer 接口 来实现负载策略
感觉没太大差,然而要本人实现主动刷新serverlist。能够参考ribbon的做法来做。举荐是应用spring-cloud-loadbalancer,因为ribbon是阻塞的。 - 官网举荐应用CircuitBreaker, 因为Hystrix 不保护了。CircuitBreaker 只有信号量隔离,能够间接应用threadlocal。