您好,登錄后才能下訂單哦!
SpringCloud中怎么實現LoadBalancer灰度策略,相信很多沒有經驗的人對此束手無策,為此本文總結了問題出現的原因和解決方法,通過這篇文章希望你能解決這個問題。
如果項目中想使用 SCL,則僅需要添加如下 maven 依賴即可
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-loadbalancer</artifactId> </dependency>
SCL 是構建服務發現的基礎上,由于目前 Spring Cloud Alibaba 并未兼容 SCL (具體兼容方案可以參考 pig),當然你可以選擇使用Eureka 測試。
若將 RestTemplate 和 客戶端負載均衡結合使用,在 bean 定義上增加 @LoadBalanced
注解即可.
@Bean @LoadBalanced public RestTemplate restTemplate() { return new RestTemplate(); }
目前版本 (spring cloud 2020) 內置輪詢、隨機的負載均衡策略,默認輪詢策略。
當然可以通過 LoadBalancerClient
注解,指定服務級別的負載均衡策略
@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 支持的負載均衡策略相較于 Ribbon
還是較少,需要開發者自行實現,好在 SCL 提供了便捷的 API 方便擴展使用。 這里演示自定義一個基于注冊中心元數據的灰度負載均衡策略。
定義灰度負載均衡策略
@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) { // 注冊中心無可用實例 拋出異常 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(); } // 遍歷可以實例元數據,若匹配則返回此實例 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); } } // 降級策略,使用輪詢策略 return super.choose(request).block(); } }
針對客戶端注入灰度負載均衡策略
@LoadBalancerClient(value = "demo-provider", configuration = GrayRoundLoadbalancerConfig.class)
服務實例定義版本號
請求攜帶版本號,測試使用
curl --location --request GET 'http://localhost:6060/req?key=b' \ --header 'VERSION: b'
如上文所述,所有的個性化負載策略都需要手動通過 LoadBalancerClient
注入非常的不方便。 我們可以參考 LoadBalancerClients
的批量注入邏輯構造自己的 BeanRegistrar
public class GrayLoadBalancerClientConfigurationRegistrar implements ImportBeanDefinitionRegistrar { @Override public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) { Field[] fields = ReflectUtil.getFields(ServiceNameConstants.class); // 遍歷服務名稱,注入支持灰度策略的負載均衡器 for (Field field : fields) { Object fieldValue = ReflectUtil.getFieldValue(ServiceNameConstants.class, field); registerClientConfiguration(registry, fieldValue, GrayLoadBalancerClientConfiguration.class); } } }
看完上述內容,你們掌握SpringCloud中怎么實現LoadBalancer灰度策略的方法了嗎?如果還想學到更多技能或想了解更多相關內容,歡迎關注億速云行業資訊頻道,感謝各位的閱讀!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。