SpringCloud LoadBalancer灰度策略实现
如何使用 Spring Cloud 2020 中重磅推荐的负载均衡器 Spring Cloud LoadBalancer (下文简称 SCL),如何扩展负载均衡策略? 你将从本文中获取到答案
快速上手 SCL
- 如果项目中想使用 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);
}
}
}
>>> 源码 https://gitee.com/log4j/pig,欢迎署名转载 <<<
SpringCloud LoadBalancer灰度策略实现的更多相关文章
- 小D课堂 - 新版本微服务springcloud+Docker教程_4-04 高级篇幅之服务间调用之负载均衡策略调整实战
笔记 4.高级篇幅之服务间调用之负载均衡策略调整实战 简介:实战调整默认负载均衡策略实战 自定义负载均衡策略:http://cloud.spring.io/spring-cloud-stati ...
- 微服务SpringCloud+Docker入门到高级实战(教程详情)
第一章 课程介绍和学习路线 1.微服务架构SpringCloud课程介绍 简介:课程介绍和课程大纲讲解,讲课风格和重点内容理解技巧 2.技术选型和学后水平 简介:课程所需基础和技术选型讲解,学完课程可 ...
- 小D课堂 - 新版本微服务springcloud+Docker教程_1_01课程简介
笔记 ============================================= SpringCloud课程笔记.txt 第一章 课程介绍和学习路线 1.微服务架构SpringClou ...
- Istio最佳实践:在K8s上通过Istio服务网格进行灰度发布
Istio是什么? Istio是Google继Kubernetes之后的又一开源力作,主要参与的公司包括Google,IBM,Lyft等公司.它提供了完整的非侵入式的微服务治理解决方案,包含微服务的管 ...
- 灰度发布:灰度很简单,发布很复杂&灰度发布(灰度法则)的6点认识
什么是灰度发布,其要点有哪些? 最近跟几个聊的来的同行来了一次说聚就聚的晚餐,聊了一下最近的工作情况如何以及未来规划等等,酒足饭饱后我们聊了一个话题“灰度发布”. 因为笔者所负责的产品还没有达到他们产 ...
- 如何用istio实现应用的灰度发布
Istio为用户提供基于微服务的流量治理能力.Istio允许用户按照标准制定一套流量分发规则,并且无侵入的下发到实例中,平滑稳定的实现灰度发布功能. 基于华为云的Istio服务网格技术,使得灰度发布全 ...
- idou老师教你学Istio 18 : 如何用istio实现应用的灰度发布
Istio为用户提供基于微服务的流量治理能力.Istio允许用户按照标准制定一套流量分发规则,并且无侵入的下发到实例中,平滑稳定的实现灰度发布功能. 基于华为云的Istio服务网格技术,使得灰度发布全 ...
- 基于 Istio 与 Kubernetes 对应用进行灰度发布与 Tracing
灰度发布,是指在黑与白之间,能够平滑过渡的一种发布方式.通俗来说,即让产品的迭代能够按照不同的灰度策略对新版本进行线上环境的测试,灰度发布可以保证整体系统的稳定,在初始灰度的时候就可以对新版本进行测试 ...
- 分布式系统:xxl-job改造spring-cloud
目录 改造原因 主要改造思路 调度中心 调度中心 执行器侧 总结 修改后的源码仓库地址:GitHub. : 改造原因 原有的xxl-job使用自己实现的http协议进行注册以及调度等,与目前框架中本身 ...
随机推荐
- springboot项目启动后tomcat服务器自动关闭 解决方法
需要在pom.xml中添加 <dependency> <groupId>org.springframework.boot</groupId> <artifac ...
- JavaWeb实现用户登录注册功能实例代码(基于Servlet+JSP+JavaBean模式)
一.Servlet+JSP+JavaBean开发模式(MVC)介绍 Servlet+JSP+JavaBean模式(MVC)适合开发复杂的web应用,在这种模式下,servlet负责处理用户请求,jsp ...
- Pycharm模块导入失败,带有红色波浪线。
在Pycharm中打开一个python开源工程,结果在导入库的部分一堆红色波浪线显示错误,并且按住Ctrl + 鼠标左击无法跳转到指定类或方法,如下图所示. 解决方法: (1)首先忽略掉这些报错,先运 ...
- 数组的常用方法之split
今天我们来聊一下数组的常用方法:split 返回值:一个新数组. 1.该方法可以直接调用不传任何值,则会直接将字符串转化成数组. var str = 'I love Javascript'; cons ...
- 使用CSS计数器美化数字有序列表
在web设计中,使用一种井井有条的方法来展示数据是十分重要的,这样用户就可以很清晰的理解网站所展示的数据结构和内容,使用有序列表就是实现数据有组织的展示的一种简单方法. 如果你需要更加深入地控制有序列 ...
- C#连接Excel读取与写入数据库SQL ( 下 )
接上期 dataset简而言之可以理解为 虚拟的 数据库或是Excel文件.而dataset里的datatable 可以理解为数据库中的table活着Excel里的sheet(Excel里面不是可以新 ...
- Codeforces1493D GCD of an Array
题目链接 点我跳转 题目大意 给定一个长度为 \(N\) 的序列 \(A\) 有 \(Q\) 次操作,每次操作给定两个数 \(i\) , \(X\),使得 \(A[i] = A[i] \times X ...
- 漏洞复现-Discuz-命令执行(wooyun-2010-080723)
0x00 实验环境 攻击机:win10 靶机:Ubuntu18 (docker搭建的vulhub靶场) 0x01 影响版本 Discuz 7.x 6.x版本 0x02 实验目的 学习d ...
- CVE-2017-10271 XMLDecoder 反序列化
漏洞描述:WebLogic的 WLS Security组件对外提供webservice服务,其中使用了XMLDecoder来解析用户传入的XML数据,在解析的过程中出现反序列化漏洞,可以构造请求对运行 ...
- C# 应用 - 使用 HttpClient 发起 Http 请求
1. 需要的库类 \Reference Assemblies\Microsoft\Framework\.NETFramework\v4.7.2\System.Net.Http.dll System.N ...