- 1 简介
- 2 使用步骤(Eureka+LoadBalancer)
- 2.1 引入pom.xml
- 2.2 自定义负载均衡算法(MyLoadBalancer.java)
- 2.3 选择负载均衡算法(CustomLoadBalancerConfiguration.java)
- 2.4 整合Eureka(ApplicationContextConfig.java)
- 2.5 自定义负载均衡算法效果
入门网址→
入门
- SpringCloud原有的客户端负载均衡方案Ribbon已经被废弃,取而代之的是SpringCloud LoadBalancer。
- 相比较于Ribbon,Spring Cloud LoadBalancer不仅能够支持RestTemplate,还支持WebClient。WeClient是Spring Web Flux中提供的功能,可以实现响应式异步请求,因此学习Spring Cloud LoadBalancer之前,建议先了解下Spring Web Flux。
Eureka 自带了 spring-cloud-starter-loadbalancer ,如果没自带自行引入
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-loadbalancerartifactId>
<version>3.1.1version>
dependency>
2.2 自定义负载均衡算法(MyLoadBalancer.java)
//这个方法基本是copy的RandomLoadBalancer自己改一改出来的
public class MyLoadBalancer implements ReactorServiceInstanceLoadBalancer {
private static final Log log = LogFactory.getLog(MyLoadBalancer.class);
final AtomicInteger position;//请求的次数
final String serviceId; //服务名称 用于提示报错信息的
private int flag = 0; //定义计数器
//两个参数的构造方法 需要服务名称和实例提供者 这个在方法中传递进来
public MyLoadBalancer(ObjectProvider<ServiceInstanceListSupplier> serviceInstanceListSupplierProvider,
String serviceId) {
//如果不传请求次数就自己初始化 反正每次都+1
this(new Random().nextInt(100), serviceId, serviceInstanceListSupplierProvider);
}
public MyLoadBalancer(int seedPosition, String serviceId, ObjectProvider<ServiceInstanceListSupplier> serviceInstanceListSupplierProvider) {
this.position = new AtomicInteger(seedPosition);
this.serviceId = serviceId;
this.serviceInstanceListSupplierProvider = serviceInstanceListSupplierProvider;
}
ObjectProvider<ServiceInstanceListSupplier> serviceInstanceListSupplierProvider;
@Override
public Mono<Response<ServiceInstance>> choose(Request request) {
//从服务提供者中获取到当前request请求中的serviceInstances并且遍历
ServiceInstanceListSupplier supplier = serviceInstanceListSupplierProvider
.getIfAvailable(NoopServiceInstanceListSupplier::new);
return supplier.get(request).next()
.map(serviceInstances -> processInstanceResponse(supplier, serviceInstances));
}
private Response<ServiceInstance> processInstanceResponse(ServiceInstanceListSupplier supplier,
List<ServiceInstance> serviceInstances) {
Response<ServiceInstance> serviceInstanceResponse = getInstanceResponse(serviceInstances);
if (supplier instanceof SelectedInstanceCallback && serviceInstanceResponse.hasServer()) {
((SelectedInstanceCallback) supplier).selectedServiceInstance(serviceInstanceResponse.getServer());
}
return serviceInstanceResponse;
}
private Response<ServiceInstance> getInstanceResponse(List<ServiceInstance> instances) {
if (instances.isEmpty()) {
if (log.isWarnEnabled()) {
log.warn("No servers available for service: " + serviceId);
}
return new EmptyResponse();
}
//pos是当前请求的次数 这样可以自定义负载均衡的切换 这个每次+1的 *** 作是复制的 最好是不删
Integer pos = Math.abs(this.position.incrementAndGet());
if (pos >= 2147483647) pos = 0;
if (pos % 3 == 0) {
//是3的倍数就切换
flag = pos % instances.size();
}
//主要的就是这句代码设置负载均衡切换
ServiceInstance instance = instances.get(flag);
return new DefaultResponse(instance);
}
}
2.3 选择负载均衡算法(CustomLoadBalancerConfiguration.java)
The classes you pass as
@LoadBalancerClient
or@LoadBalancerClients
configuration arguments should either not be annotated with@Configuration
or be outside component scan scope.
翻译:作为@LoadBalancerClient或@LoadBalancerClients配置参数传递的类要么不应该带有@Configuration注释,要么应该在组件扫描范围之外。
public class CustomLoadBalancerConfiguration {
@Bean
ReactorLoadBalancer<ServiceInstance> randomLoadBalancer(Environment environment,
LoadBalancerClientFactory loadBalancerClientFactory) {
String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME);
//LoadBalancer自带的负载均衡算法只有两个:随机算法和轮询算法
//选择随机算法
// return new RandomLoadBalancer(loadBalancerClientFactory.getLazyProvider(name, ServiceInstanceListSupplier.class),name);
//选择自定义负载均衡算法
return new MyLoadBalancer(loadBalancerClientFactory.getLazyProvider(name, ServiceInstanceListSupplier.class), name);
}
}
2.4 整合Eureka(ApplicationContextConfig.java)
添加注解:@LoadBalancerClient(value = "CLOUD-PAYMENT-SERVICE", configuration = CustomLoadBalancerConfiguration.class)
@Configuration
@LoadBalancerClient(value = "CLOUD-PAYMENT-SERVICE", configuration = CustomLoadBalancerConfiguration.class)
public class ApplicationContextConfig {
/**
* RestTemplate的作用是完成微服务之间的调用
* @return
*/
@Bean //依赖注入
@LoadBalanced //对payment8090和对payment8091负载均衡
public RestTemplate getRestTemplate(){
return new RestTemplate();
}
}
2.5 自定义负载均衡算法效果
每三次切换一次服务器
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)