您好,登錄后才能下訂單哦!
SpringCloud中怎么實(shí)現(xiàn)LoadBalancer灰度策略,相信很多沒有經(jīng)驗(yàn)的人對(duì)此束手無策,為此本文總結(jié)了問題出現(xiàn)的原因和解決方法,通過這篇文章希望你能解決這個(gè)問題。
如果項(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(); }
目前版本 (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); } }
通過上文可知,目前 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)
請(qǐng)求攜帶版本號(hào),測(cè)試使用
curl --location --request GET 'http://localhost:6060/req?key=b' \ --header 'VERSION: b'
如上文所述,所有的個(gè)性化負(fù)載策略都需要手動(dòng)通過 LoadBalancerClient
注入非常的不方便。 我們可以參考 LoadBalancerClients
的批量注入邏輯構(gòu)造自己的 BeanRegistrar
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è)資訊頻道,感謝各位的閱讀!
免責(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)容。