溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Spring Cloud Gateway擴展有哪些特點

發(fā)布時間:2021-11-16 13:54:28 來源:億速云 閱讀:129 作者:iii 欄目:大數(shù)據(jù)

這篇文章主要講解了“Spring Cloud Gateway擴展有哪些特點”,文中的講解內(nèi)容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“Spring Cloud Gateway擴展有哪些特點”吧!

灰度發(fā)布

什么是灰度發(fā)布,概念請參考,我們來簡單的通過下圖來看下,通俗的講: 為了保證服務升級過程的平滑過渡提高客戶體驗,會一部分用戶 一部分用戶遞進更新,這樣生產(chǎn)中會同時出現(xiàn)多個版本的客戶端,為了保證多個版本客戶端的可用需要對應的多個版本的服務端版本?;叶劝l(fā)布就是通過一定策略保證 多個版本客戶端、服務端間能夠正確對應。
Spring Cloud Gateway擴展有哪些特點

所謂灰度發(fā)布,即某個服務存在多個實例時,并且實例版本間的版本并不一致,通過

實現(xiàn)方案

nginx + lua (openresty)

Spring Cloud Gateway擴展有哪些特點 Spring Cloud Gateway擴展有哪些特點

Netflix Zuul

只需要自定義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 Map<string, string> metadata = server.getInstanceInfo().getMetadata();
                if (StrUtil.isBlank(metadata.get(SecurityConstants.VERSION))) {
                    log.debug("當前微服務{(diào)} 未配置版本直接路由");
                    return true;
                }

                if (metadata.get(SecurityConstants.VERSION).equals(targetVersion)) {
                    return true;
                } else {
                    log.debug("當前微服務{(diào)} 版本為{},目標版本{} 匹配失敗", server.getInstanceInfo().getAppName()
                            , metadata.get(SecurityConstants.VERSION), targetVersion);
                    return false;
                }
            }
        };
    }
}

維護請求中的版本號

public class RibbonVersionHolder {
    private static final ThreadLocal<string> context = new TransmittableThreadLocal&lt;&gt;();

    public static String getContext() {
        return context.get();
    }

    public static void setContext(String value) {
        context.set(value);
    }

    public static void clearContext() {
        context.remove();
    }
}

Spring Cloud Gateway 中實現(xiàn)

第一反應,參考zuul 的實現(xiàn),自定義斷言,然后從上下中獲取版本信息即可。但由于 spring cloud gateway 是基于webflux 的反應式編程,所以傳統(tǒng)的TTL或者 RequestContextHolder 都不能正確的維護上下文請求。

先來看 spring clou的 gateway 默認的lb 策略實現(xiàn) LoadBalancerClientFilter

public class LoadBalancerClientFilter implements GlobalFilter, Ordered {
	@Override
	public int getOrder() {
		return LOAD_BALANCER_CLIENT_FILTER_ORDER;
	}

	@Override
	@SuppressWarnings("Duplicates")
	public Mono<void> filter(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
				&amp;&amp; input.getServer() instanceof NacosServer
				&amp;&amp; apply((NacosServer) input.getServer(), (HttpHeaders) input.getLoadBalancerKey());
	}
}

最后根據(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 Map<string, string> metadata = 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

結合nacos的動態(tài)配置可以非常方便的實現(xiàn)灰度 Spring Cloud Gateway擴展有哪些特點

感謝各位的閱讀,以上就是“Spring Cloud Gateway擴展有哪些特點”的內(nèi)容了,經(jīng)過本文的學習后,相信大家對Spring Cloud Gateway擴展有哪些特點這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內(nèi)容。

AI