摘要:灰度發布就是通過一定策略保證多個版本客戶端服務端間能夠正確對應。但由于是基于的反應式編程,所以傳統的或者都不能正確的維護上下文請求。歡迎關注我們獲得更多的好玩實踐
灰度發布
什么是灰度發布,概念請參考,我們來簡單的通過下圖來看下,通俗的講: 為了保證服務升級過程的平滑過渡提高客戶體驗,會一部分用戶 一部分用戶遞進更新,這樣生產中會同時出現多個版本的客戶端,為了保證多個版本客戶端的可用需要對應的多個版本的服務端版本。灰度發布就是通過一定策略保證 多個版本客戶端、服務端間能夠正確對應。
所謂灰度發布,即某個服務存在多個實例時,并且實例版本間的版本并不一致,通過
實現方案 nginx + lua (openresty)只需要自定義ribbon 的斷言即可,核心是通過TTL 獲取上下請求header中的版本號
@Slf4j public class MetadataCanaryRuleHandler extends ZoneAvoidanceRule { @Override public AbstractServerPredicate getPredicate() { return new AbstractServerPredicate() { @Override public boolean apply(PredicateKey predicateKey) { String targetVersion = RibbonVersionHolder.getContext(); RibbonVersionHolder.clearContext(); if (StrUtil.isBlank(targetVersion)) { log.debug("客戶端未配置目標版本直接路由"); return true; } DiscoveryEnabledServer server = (DiscoveryEnabledServer) predicateKey.getServer(); final Mapmetadata = server.getInstanceInfo().getMetadata(); if (StrUtil.isBlank(metadata.get(SecurityConstants.VERSION))) { log.debug("當前微服務{} 未配置版本直接路由"); return true; } if (metadata.get(SecurityConstants.VERSION).equals(targetVersion)) { return true; } else { log.debug("當前微服務{} 版本為{},目標版本{} 匹配失敗", server.getInstanceInfo().getAppName() , metadata.get(SecurityConstants.VERSION), targetVersion); return false; } } }; } }
維護請求中的版本號
public class RibbonVersionHolder { private static final ThreadLocalSpring Cloud Gateway 中實現context = new TransmittableThreadLocal<>(); public static String getContext() { return context.get(); } public static void setContext(String value) { context.set(value); } public static void clearContext() { context.remove(); } }
第一反應,參考zuul 的實現,自定義斷言,然后從上下中獲取版本信息即可。但由于 spring cloud gateway 是基于webflux 的反應式編程,所以傳統的TTL或者 RequestContextHolder 都不能正確的維護上下文請求。
先來看 spring clou的 gateway 默認的lb 策略實現 LoadBalancerClientFilter
public class LoadBalancerClientFilter implements GlobalFilter, Ordered { @Override public int getOrder() { return LOAD_BALANCER_CLIENT_FILTER_ORDER; } @Override @SuppressWarnings("Duplicates") public Monofilter(ServerWebExchange exchange, GatewayFilterChain chain) { return chain.filter(exchange); } protected ServiceInstance choose(ServerWebExchange exchange) { return loadBalancer.choose( ((URI) exchange.getAttribute(GATEWAY_REQUEST_URL_ATTR)).getHost()); } }
我們只需要重寫 choose 方法,把上下文請求傳遞到路由斷言中即可,如下
@Override protected ServiceInstance choose(ServerWebExchange exchange) { HttpHeaders headers = exchange.getRequest().getHeaders(); return loadBalancer.choose(((URI) exchange.getAttribute(GATEWAY_REQUEST_URL_ATTR)).getHost(), headers); }
然后在路由斷言中通過 PredicateKey獲取到即可
public abstract class AbstractDiscoveryEnabledPredicate extends AbstractServerPredicate { /** * {@inheritDoc} */ @Override public boolean apply(@Nullable PredicateKey input) { return input != null && input.getServer() instanceof NacosServer && apply((NacosServer) input.getServer(), (HttpHeaders) input.getLoadBalancerKey()); } }
最后根據版本來計算
public class GrayMetadataAwarePredicate extends AbstractDiscoveryEnabledPredicate { @Override protected boolean apply(NacosServer server, HttpHeaders headers) { PigxRibbonRuleProperties ribbonProperties = SpringContextHolder.getBean(PigxRibbonRuleProperties.class); if (!ribbonProperties.isGrayEnabled()) { log.debug("gray closed,GrayMetadataAwarePredicate return true"); return true; } final Map整合nacosmetadata = server.getMetadata(); String version = metadata.get(CommonConstants.VERSION); // 判斷Nacos服務是否有版本標簽 if (StrUtil.isBlank(version)) { log.debug("nacos server tag is blank ,GrayMetadataAwarePredicate return true"); return true; } // 判斷請求中是否有版本 String target = headers.getFirst(CommonConstants.VERSION); if (StrUtil.isBlank(target)) { log.debug("request headers version is blank,GrayMetadataAwarePredicate return true"); return true; } log.debug("請求版本:{} ,當前服務版本:{}", target, version); return target.equals(version); } }
結合nacos的動態配置可以非常方便的實現灰度
以上源碼參考個人項目 基于Spring Cloud、OAuth2.0開發基于Vue前后分離的開發平臺
QQ: 2270033969 一起來聊聊你們是咋用 spring cloud 的吧。
歡迎關注我們獲得更多的好玩JavaEE 實踐
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/45132.html
摘要:灰度發布就是通過一定策略保證多個版本客戶端服務端間能夠正確對應。但由于是基于的反應式編程,所以傳統的或者都不能正確的維護上下文請求。歡迎關注我們獲得更多的好玩實踐 灰度發布 什么是灰度發布,概念請參考,我們來簡單的通過下圖來看下,通俗的講: 為了保證服務升級過程的平滑過渡提高客戶體驗,會一部分用戶 一部分用戶遞進更新,這樣生產中會同時出現多個版本的客戶端,為了保證多個版本客戶端的可用需...
摘要:灰度發布就是通過一定策略保證多個版本客戶端服務端間能夠正確對應。但由于是基于的反應式編程,所以傳統的或者都不能正確的維護上下文請求。歡迎關注我們獲得更多的好玩實踐 灰度發布 什么是灰度發布,概念請參考,我們來簡單的通過下圖來看下,通俗的講: 為了保證服務升級過程的平滑過渡提高客戶體驗,會一部分用戶 一部分用戶遞進更新,這樣生產中會同時出現多個版本的客戶端,為了保證多個版本客戶端的可用需...
摘要:灰度發布就是通過一定策略保證多個版本客戶端服務端間能夠正確對應。但由于是基于的反應式編程,所以傳統的或者都不能正確的維護上下文請求。歡迎關注我們獲得更多的好玩實踐 灰度發布 什么是灰度發布,概念請參考,我們來簡單的通過下圖來看下,通俗的講: 為了保證服務升級過程的平滑過渡提高客戶體驗,會一部分用戶 一部分用戶遞進更新,這樣生產中會同時出現多個版本的客戶端,為了保證多個版本客戶端的可用需...
摘要:灰度發布是指在黑與白之間,能夠平滑過渡的一種發布方式。如何使用進行灰度發布呢將分一下四步第一,設置網關權重路由設置中提供了去實現根據分組設置權重進行路由,因此使用起來相對比較簡單,有興趣的可以閱讀源碼。 灰度發布是指在黑與白之間,能夠平滑過渡的一種發布方式。在其上可以進行A/B testing,即讓一部分用戶繼續用產品特性A,一部分用戶開始用產品特性B,如果用戶對B沒有什么反對意見,那...
閱讀 653·2021-11-23 09:51
閱讀 3600·2021-11-15 11:38
閱讀 927·2021-10-14 09:42
閱讀 3166·2021-09-29 09:35
閱讀 2104·2021-09-03 10:33
閱讀 769·2021-07-30 16:33
閱讀 1558·2019-08-30 15:55
閱讀 1841·2019-08-30 14:04