SpringCloud 2023 LoadBalancer介绍、使用、获取服务列表原理、负载均衡算法
目录
- 1. 介绍
- 2. 使用
- 3 获取服务列表原理
- 4. 负载均衡算法
1. 介绍
功能:
- 提供客户端的负载均衡算法,将请求均摊到多个服务器上。
- 属于客户端负载均衡(Nginx属于服务端负载均衡),会将服务列表缓存到JVM本地,然后客户端自己选择请求服务器
- 支持Spring Web Flux的WebClient
2. 使用
基本使用可以参考Nacos之SpringCloud集成Nacos注册中心
3 获取服务列表原理
底层是通过DiscoveryClient
动态获取所有上线的服务列表。伪代码如下:
@RestController
public class OrderController {
@Autowired
private DiscoveryClient discoveryClient;
@GetMapping("/nacos/getNacosAllServiceInfo")
public String getNacosAllServiceInfo() {
List<String> serviceNames = discoveryClient.getServices();
Map<String, Object> serviceMap = new HashMap<>();
for (String serviceName : serviceNames) {
List<ServiceInstance> serviceInstances = discoveryClient.getInstances(serviceName);
List<Map<String,String>> serviceInstanceInfos = new ArrayList<>();
for(ServiceInstance serviceInstance: serviceInstances) {
Map<String, String> serviceInstanceMap = new HashMap<>();
serviceInstanceMap.put("serviceId", serviceInstance.getServiceId());
serviceInstanceMap.put("instanceId", serviceInstance.getInstanceId());
serviceInstanceMap.put("host", serviceInstance.getHost());
serviceInstanceMap.put("port", String.valueOf(serviceInstance.getPort()));
serviceInstanceMap.put("uri", serviceInstance.getUri().toString());
serviceInstanceInfos.add(serviceInstanceMap);
}
serviceMap.put(serviceName, serviceInstanceInfos);
}
return serviceMap.toString();
}
}
访问http://localhost:8002/nacos/getNacosAllServiceInfo,返回的数据如下:
{orderment=[{instanceId=192.168.163.1#8002#DEFAULT#DEFAULT_GROUP@@orderment, port=8002, host=192.168.163.1, serviceId=orderment, uri=http://192.168.163.1:8002}], payment=[{instanceId=192.168.163.1#8001#DEFAULT#DEFAULT_GROUP@@payment, port=8001, host=192.168.163.1, serviceId=payment, uri=http://192.168.163.1:8001}]}
4. 负载均衡算法
- 默认的轮询算法RoundRobinLoadBalancer: rest接口第几次请求数 % 服务器集群总数量 = 实际调用服务器位置下标,每次服务重启动后rest接口计数从1开始
- 同时提供了随机算法RandomLoadBalancer的实现。切换代码如下。说明:
- 实现了LoadBalancerConfig,会使默认的RoundRobinLoadBalancer失效
- 要向哪个服务发送请求,就要在
@LoadBalancerClient
或@LoadBalancerClients
中定义
//@LoadBalancerClient(value = "payment1", configuration = LoadBalancerConfig.class)
@LoadBalancerClients({
@LoadBalancerClient(value = "payment1", configuration = LoadBalancerConfig.class),
@LoadBalancerClient(value = "payment2", configuration = LoadBalancerConfig.class),
})
public class LoadBalancerConfig {
@Bean
ReactorLoadBalancer<ServiceInstance> randomLoadBalancer(Environment environment,
LoadBalancerClientFactory loadBalancerClientFactory) {
String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME);
return new RandomLoadBalancer(loadBalancerClientFactory
.getLazyProvider(name, ServiceInstanceListSupplier.class),
name);
}
}