Spring Cloud 基于 Nacos 本地优化负载均衡配置
青苗 | 414 |
2023-05-16
基于 Nacos 负载均衡本地优先处理策略
下面是处理本地优先负载均衡,未处理 nacos 集群优先,这部分代码主要也是用于本地调试,因此集群优化不在考虑范围采用默认随机策略。
@Slf4j
public class DevNacosLoadBalancer extends NacosLoadBalancer {
private ObjectProvider<ServiceInstanceListSupplier> serviceInstanceListSupplierProvider;
private final String serviceId;
public DevNacosLoadBalancer(ObjectProvider<ServiceInstanceListSupplier> serviceInstanceListSupplierProvider, String serviceId, NacosDiscoveryProperties nacosDiscoveryProperties) {
super(serviceInstanceListSupplierProvider, serviceId, nacosDiscoveryProperties);
this.serviceId = serviceId;
this.serviceInstanceListSupplierProvider = serviceInstanceListSupplierProvider;
}
@Override
public Mono<Response<ServiceInstance>> choose(Request request) {
ServiceInstanceListSupplier supplier = serviceInstanceListSupplierProvider.getIfAvailable(NoopServiceInstanceListSupplier::new);
return supplier.get().next().map(serviceInstances -> {
if (serviceInstances.isEmpty()) {
log.warn("No servers available for service: " + this.serviceId);
return new EmptyResponse();
}
ServiceInstance chooseService = null;
for (ServiceInstance serviceInstance : serviceInstances) {
if (this.isLocalIp(serviceInstance.getHost())) {
log.debug("choose: {}, {}", serviceInstance.getHost(), serviceInstance.getServiceId());
chooseService = serviceInstance;
break;
}
}
if (null == chooseService) {
// 内置随机策略选择
chooseService = NacosBalancer.getHostByRandomWeight3(serviceInstances);
}
return new DefaultResponse(chooseService);
});
}
/**
* 判断是否为本地 IP
*
* @param ip 待判断 IP
* @return
*/
public static boolean isLocalIp(String ip) {
try {
Enumeration<NetworkInterface> networkInterfaces = NetworkInterface.getNetworkInterfaces();
while (networkInterfaces.hasMoreElements()) {
NetworkInterface ni = networkInterfaces.nextElement();
Enumeration<InetAddress> e2 = ni.getInetAddresses();
while (e2.hasMoreElements()) {
InetAddress ia = e2.nextElement();
if (ia instanceof Inet6Address) {
continue;
}
String address = ia.getHostAddress();
if (null != address && address.equals(ip)) {
return true;
}
}
}
} catch (SocketException e) {
e.printStackTrace();
}
return false;
}
}
本地优化负载均衡配置
需要通过注解@LoadBalancerClients
注入自定义的负载均衡器,注解 @ConditionalOnDiscoveryEnabled
启动负载均衡,也可以通过配置例如:spring.cloud.loadbalancer.nacos.enabled = true
@Configuration(proxyBeanMethods = false)
@ConditionalOnDiscoveryEnabled
@LoadBalancerClients(defaultConfiguration = LocalFirstLoadBalancerConfiguration.class)
public class LocalFirstLoadBalancerConfiguration {
@Bean
@Primary
public ReactorLoadBalancer<ServiceInstance> nacosLoadBalancer(Environment environment,
LoadBalancerClientFactory loadBalancerClientFactory,
NacosDiscoveryProperties nacosDiscoveryProperties) {
String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME);
return new DevNacosLoadBalancer(loadBalancerClientFactory.getLazyProvider(name,
ServiceInstanceListSupplier.class), name, nacosDiscoveryProperties);
}
}
推荐指数:
真诚点赞 诚不我欺~