LoadBalance已有策略
LoadBalance的源码中已有两种策略,RandomLoadBalancer(随机)、RoundRobinLoadBalancer(轮询,默认的负载均衡策略)。
LoadBalance自定义策略
以下为使用自定义负载均衡策略的样例,根据配置服务提供者的权重,按比例随机访问服务器。仅展示自定义负载均衡策略相关的部分,Eureka等其他相关代码不作展示。提供两个服务提供者,端口分别为11000,11001。
自定义负载均衡策略
public class WeightLoadBalancer implements ReactorServiceInstanceLoadBalancer {
final String serviceId;
ObjectProvider<ServiceInstanceListSupplier> serviceInstanceListSupplierProvider;
public WeightLoadBalancer(ObjectProvider<ServiceInstanceListSupplier> serviceInstanceListSupplierProvider,
String serviceId) {
this.serviceId = serviceId;
this.serviceInstanceListSupplierProvider = serviceInstanceListSupplierProvider;
}
@Override
public Mono<Response<ServiceInstance>> choose(Request request) {
ServiceInstanceListSupplier supplier = serviceInstanceListSupplierProvider
.getIfAvailable(NoopServiceInstanceListSupplier::new);
return supplier.get(request).next().map(this::select);
}
private Response<ServiceInstance> select(List<ServiceInstance> instances) {
if (instances.isEmpty()) {
return new EmptyResponse();
}
// 简单模拟权重,仅作演示
// 11000:3 11001:1
int[] ports = {11000, 11000, 11000, 11001};
int port = ports[ThreadLocalRandom.current().nextInt(ports.length)];
for (ServiceInstance instance : instances) {
if (port == instance.getPort()) {
return new DefaultResponse(instance);
}
}
return new DefaultResponse(instances.get(0));
}
}
LoadBalance配置类
public class MyLoadBalanceConfig {
@Bean
public ReactorLoadBalancer<ServiceInstance> reactorLoadBalancer(Environment environment, LoadBalancerClientFactory loadBalancerClientFactory){
String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME);
// 随机
// return new RandomLoadBalancer(loadBalancerClientFactory.getLazyProvider(name, ServiceInstanceListSupplier.class), name);
// 轮询
// return new RoundRobinLoadBalancer(loadBalancerClientFactory.getLazyProvider(name, ServiceInstanceListSupplier.class), name);
// 权重,自定义
return new WeightLoadBalancer(loadBalancerClientFactory.getLazyProvider(name, ServiceInstanceListSupplier.class), name);
}
}
启动类设置LoadBalance配置
@SpringBootApplication
@EnableDiscoveryClient
@LoadBalancerClients(
@LoadBalancerClient(name = "cloud-payment-service", configuration = MyLoadBalanceConfig.class)
)
public class OrderApplication {
public static void main(String[] args) {
SpringApplication.run(OrderApplication.class, args);
}
}
调用的Controller
@Controller
@RequestMapping("/order")
public class OrderController {
@Autowired
private LoadBalancerClient loadBalancerClient;
@GetMapping("/loadBalance")
public void loadBalance(){
ServiceInstance instance = loadBalancerClient.choose("cloud-payment-service");
System.out.println("port:" + instance.getPort());
}
}
多次访问的效果如下:
port:11000
port:11000
port:11000
port:11000
port:11000
port:11000
port:11001
port:11000
port:11000
port:11000
port:11001
port:11000
port:11000
port:11001