溫馨提示×

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

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

SpringCloud中怎么實(shí)現(xiàn)LoadBalancer灰度策略

發(fā)布時(shí)間:2021-08-03 15:40:26 來源:億速云 閱讀:465 作者:Leah 欄目:編程語言

SpringCloud中怎么實(shí)現(xiàn)LoadBalancer灰度策略,相信很多沒有經(jīng)驗(yàn)的人對(duì)此束手無策,為此本文總結(jié)了問題出現(xiàn)的原因和解決方法,通過這篇文章希望你能解決這個(gè)問題。

快速上手 SCL

  • 如果項(xiàng)目中想使用 SCL,則僅需要添加如下 maven 依賴即可

<dependency>
	<groupId>org.springframework.cloud</groupId>
	<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
  • SCL 是構(gòu)建服務(wù)發(fā)現(xiàn)的基礎(chǔ)上,由于目前 Spring Cloud Alibaba 并未兼容 SCL (具體兼容方案可以參考 pig),當(dāng)然你可以選擇使用Eureka 測(cè)試。

  • 若將 RestTemplate 和 客戶端負(fù)載均衡結(jié)合使用,在 bean 定義上增加 @LoadBalanced 注解即可.

@Bean
@LoadBalanced
public RestTemplate restTemplate() {
    return new RestTemplate();
}

個(gè)性化負(fù)載均衡策略

SpringCloud中怎么實(shí)現(xiàn)LoadBalancer灰度策略

  • 目前版本 (spring cloud 2020) 內(nèi)置輪詢、隨機(jī)的負(fù)載均衡策略,默認(rèn)輪詢策略。

  • 當(dāng)然可以通過 LoadBalancerClient 注解,指定服務(wù)級(jí)別的負(fù)載均衡策略

@LoadBalancerClient(value = "demo-provider", configuration = RandomLoadbalancerConfig.class)
public class RandomLoadbalancerConfig {
	@Bean
	public ReactorLoadBalancer<ServiceInstance> reactorServiceInstanceLoadBalancer(Environment environment,
			LoadBalancerClientFactory loadBalancerClientFactory) {
		String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME);
		return new RandomLoadBalancer(
				loadBalancerClientFactory.getLazyProvider(name, ServiceInstanceListSupplier.class), name);
	}
}

自定義負(fù)載均衡策略

  • 通過上文可知,目前 SCL 支持的負(fù)載均衡策略相較于 Ribbon 還是較少,需要開發(fā)者自行實(shí)現(xiàn),好在 SCL 提供了便捷的 API 方便擴(kuò)展使用。 這里演示自定義一個(gè)基于注冊(cè)中心元數(shù)據(jù)的灰度負(fù)載均衡策略。

  • 定義灰度負(fù)載均衡策略

@Slf4j
public class GrayRoundRobinLoadBalancer extends RoundRobinLoadBalancer {

	private ObjectProvider<ServiceInstanceListSupplier> serviceInstanceListSupplierProvider;

	private String serviceId;

	@Override
	public Mono<Response<ServiceInstance>> choose(Request request) {
		ServiceInstanceListSupplier supplier = serviceInstanceListSupplierProvider
				.getIfAvailable(NoopServiceInstanceListSupplier::new);
		return supplier.get(request).next().map(serviceInstances -> getInstanceResponse(serviceInstances, request));
	}

	Response<ServiceInstance> getInstanceResponse(List<ServiceInstance> instances, Request request) {

		// 注冊(cè)中心無可用實(shí)例 拋出異常
		if (CollUtil.isEmpty(instances)) {
			log.warn("No instance available {}", serviceId);
			return new EmptyResponse();
		}

		DefaultRequestContext requestContext = (DefaultRequestContext) request.getContext();
		RequestData clientRequest = (RequestData) requestContext.getClientRequest();
		HttpHeaders headers = clientRequest.getHeaders();

		String reqVersion = headers.getFirst(CommonConstants.VERSION);
		if (StrUtil.isBlank(reqVersion)) {
			return super.choose(request).block();
		}

		// 遍歷可以實(shí)例元數(shù)據(jù),若匹配則返回此實(shí)例
		for (ServiceInstance instance : instances) {
			NacosServiceInstance nacosInstance = (NacosServiceInstance) instance;
			Map<String, String> metadata = nacosInstance.getMetadata();
			String targetVersion = MapUtil.getStr(metadata, CommonConstants.VERSION);
			if (reqVersion.equalsIgnoreCase(targetVersion)) {
				log.debug("gray requst match success :{} {}", reqVersion, nacosInstance);
				return new DefaultResponse(nacosInstance);
			}
		}
		// 降級(jí)策略,使用輪詢策略
		return super.choose(request).block();
	}
}
  • 針對(duì)客戶端注入灰度負(fù)載均衡策略

@LoadBalancerClient(value = "demo-provider", configuration = GrayRoundLoadbalancerConfig.class)
  • 服務(wù)實(shí)例定義版本號(hào)

SpringCloud中怎么實(shí)現(xiàn)LoadBalancer灰度策略

  • 請(qǐng)求攜帶版本號(hào),測(cè)試使用

curl --location --request GET 'http://localhost:6060/req?key=b' \
--header 'VERSION: b'

優(yōu)化負(fù)載均衡策略注入

  • 如上文所述,所有的個(gè)性化負(fù)載策略都需要手動(dòng)通過 LoadBalancerClient 注入非常的不方便。 我們可以參考 LoadBalancerClients 的批量注入邏輯構(gòu)造自己的 BeanRegistrar

SpringCloud中怎么實(shí)現(xiàn)LoadBalancer灰度策略

public class GrayLoadBalancerClientConfigurationRegistrar implements ImportBeanDefinitionRegistrar {

	@Override
	public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {
		Field[] fields = ReflectUtil.getFields(ServiceNameConstants.class);

		// 遍歷服務(wù)名稱,注入支持灰度策略的負(fù)載均衡器
		for (Field field : fields) {
			Object fieldValue = ReflectUtil.getFieldValue(ServiceNameConstants.class, field);
			registerClientConfiguration(registry, fieldValue, GrayLoadBalancerClientConfiguration.class);
		}
	}
}

看完上述內(nèi)容,你們掌握SpringCloud中怎么實(shí)現(xiàn)LoadBalancer灰度策略的方法了嗎?如果還想學(xué)到更多技能或想了解更多相關(guān)內(nèi)容,歡迎關(guān)注億速云行業(yè)資訊頻道,感謝各位的閱讀!

向AI問一下細(xì)節(jié)

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

AI