十年网站开发经验 + 多家企业客户 + 靠谱的建站团队
量身定制 + 运营维护+专业推广+无忧售后,网站问题一站解决
SpringCloud中怎么实现LoadBalancer灰度策略,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。
成都网站制作、网站建设的开发,更需要了解用户,从用户角度来建设网站,获得较好的用户体验。创新互联建站多年互联网经验,见的多,沟通容易、能帮助客户提出的运营建议。作为成都一家网络公司,打造的就是网站建设产品直销的概念。选择创新互联建站,不只是建站,我们把建站作为产品,不断的更新、完善,让每位来访用户感受到浩方产品的价值服务。
如果项目中想使用 SCL,则仅需要添加如下 maven 依赖即可
org.springframework.cloud spring-cloud-starter-loadbalancer
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 ReactorLoadBalancerreactorServiceInstanceLoadBalancer(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 ObjectProviderserviceInstanceListSupplierProvider; private String serviceId; @Override public Mono > choose(Request request) { ServiceInstanceListSupplier supplier = serviceInstanceListSupplierProvider .getIfAvailable(NoopServiceInstanceListSupplier::new); return supplier.get(request).next().map(serviceInstances -> getInstanceResponse(serviceInstances, request)); } Response getInstanceResponse(List 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 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灰度策略的方法了吗?如果还想学到更多技能或想了解更多相关内容,欢迎关注创新互联行业资讯频道,感谢各位的阅读!