十年網(wǎng)站開(kāi)發(fā)經(jīng)驗(yàn) + 多家企業(yè)客戶(hù) + 靠譜的建站團(tuán)隊(duì)
量身定制 + 運(yùn)營(yíng)維護(hù)+專(zhuān)業(yè)推廣+無(wú)憂(yōu)售后,網(wǎng)站問(wèn)題一站解決
這篇文章主要講解了“Spring Cloud Gateway擴(kuò)展有哪些特點(diǎn)”,文中的講解內(nèi)容簡(jiǎn)單清晰,易于學(xué)習(xí)與理解,下面請(qǐng)大家跟著小編的思路慢慢深入,一起來(lái)研究和學(xué)習(xí)“Spring Cloud Gateway擴(kuò)展有哪些特點(diǎn)”吧!
創(chuàng)新互聯(lián)公司專(zhuān)注為客戶(hù)提供全方位的互聯(lián)網(wǎng)綜合服務(wù),包含不限于成都做網(wǎng)站、成都網(wǎng)站設(shè)計(jì)、泉州網(wǎng)絡(luò)推廣、小程序開(kāi)發(fā)、泉州網(wǎng)絡(luò)營(yíng)銷(xiāo)、泉州企業(yè)策劃、泉州品牌公關(guān)、搜索引擎seo、人物專(zhuān)訪、企業(yè)宣傳片、企業(yè)代運(yùn)營(yíng)等,從售前售中售后,我們都將竭誠(chéng)為您服務(wù),您的肯定,是我們最大的嘉獎(jiǎng);創(chuàng)新互聯(lián)公司為所有大學(xué)生創(chuàng)業(yè)者提供泉州建站搭建服務(wù),24小時(shí)服務(wù)熱線:028-86922220,官方網(wǎng)址:www.cdcxhl.com
什么是灰度發(fā)布,概念請(qǐng)參考,我們來(lái)簡(jiǎn)單的通過(guò)下圖來(lái)看下,通俗的講: 為了保證服務(wù)升級(jí)過(guò)程的平滑過(guò)渡提高客戶(hù)體驗(yàn),會(huì)一部分用戶(hù) 一部分用戶(hù)遞進(jìn)更新,這樣生產(chǎn)中會(huì)同時(shí)出現(xiàn)多個(gè)版本的客戶(hù)端,為了保證多個(gè)版本客戶(hù)端的可用需要對(duì)應(yīng)的多個(gè)版本的服務(wù)端版本?;叶劝l(fā)布就是通過(guò)一定策略保證 多個(gè)版本客戶(hù)端、服務(wù)端間能夠正確對(duì)應(yīng)。
所謂灰度發(fā)布,即某個(gè)服務(wù)存在多個(gè)實(shí)例時(shí),并且實(shí)例版本間的版本并不一致,通過(guò)
只需要自定義ribbon 的斷言即可,核心是通過(guò)TTL 獲取上下請(qǐng)求header中的版本號(hào)
@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("客戶(hù)端未配置目標(biāo)版本直接路由"); return true; } DiscoveryEnabledServer server = (DiscoveryEnabledServer) predicateKey.getServer(); final Mapmetadata = server.getInstanceInfo().getMetadata(); if (StrUtil.isBlank(metadata.get(SecurityConstants.VERSION))) { log.debug("當(dāng)前微服務(wù){(diào)} 未配置版本直接路由"); return true; } if (metadata.get(SecurityConstants.VERSION).equals(targetVersion)) { return true; } else { log.debug("當(dāng)前微服務(wù){(diào)} 版本為{},目標(biāo)版本{} 匹配失敗", server.getInstanceInfo().getAppName() , metadata.get(SecurityConstants.VERSION), targetVersion); return false; } } }; } }
維護(hù)請(qǐng)求中的版本號(hào)
public class RibbonVersionHolder { private static final ThreadLocalcontext = new TransmittableThreadLocal<>(); public static String getContext() { return context.get(); } public static void setContext(String value) { context.set(value); } public static void clearContext() { context.remove(); } }
第一反應(yīng),參考zuul 的實(shí)現(xiàn),自定義斷言,然后從上下中獲取版本信息即可。但由于 spring cloud gateway 是基于webflux 的反應(yīng)式編程,所以傳統(tǒng)的TTL或者 RequestContextHolder 都不能正確的維護(hù)上下文請(qǐng)求。
先來(lái)看 spring clou的 gateway 默認(rèn)的lb 策略實(shí)現(xiàn) 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()); } }
我們只需要重寫(xiě) choose 方法,把上下文請(qǐng)求傳遞到路由斷言中即可,如下
@Override protected ServiceInstance choose(ServerWebExchange exchange) { HttpHeaders headers = exchange.getRequest().getHeaders(); return loadBalancer.choose(((URI) exchange.getAttribute(GATEWAY_REQUEST_URL_ATTR)).getHost(), headers); }
然后在路由斷言中通過(guò) 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()); } }
最后根據(jù)版本來(lái)計(jì)算
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 Mapmetadata = server.getMetadata(); String version = metadata.get(CommonConstants.VERSION); // 判斷Nacos服務(wù)是否有版本標(biāo)簽 if (StrUtil.isBlank(version)) { log.debug("nacos server tag is blank ,GrayMetadataAwarePredicate return true"); return true; } // 判斷請(qǐng)求中是否有版本 String target = headers.getFirst(CommonConstants.VERSION); if (StrUtil.isBlank(target)) { log.debug("request headers version is blank,GrayMetadataAwarePredicate return true"); return true; } log.debug("請(qǐng)求版本:{} ,當(dāng)前服務(wù)版本:{}", target, version); return target.equals(version); } }
結(jié)合nacos的動(dòng)態(tài)配置可以非常方便的實(shí)現(xiàn)灰度
感謝各位的閱讀,以上就是“Spring Cloud Gateway擴(kuò)展有哪些特點(diǎn)”的內(nèi)容了,經(jīng)過(guò)本文的學(xué)習(xí)后,相信大家對(duì)Spring Cloud Gateway擴(kuò)展有哪些特點(diǎn)這一問(wèn)題有了更深刻的體會(huì),具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是創(chuàng)新互聯(lián),小編將為大家推送更多相關(guān)知識(shí)點(diǎn)的文章,歡迎關(guān)注!