nacos在2.x版本,Naco作为注册中心,Zuul作为网关进行整合
1 问题描述(Forwarding error、 Load balancer does not have available server for client)
Naco2.x 作为注册中心,Zuul作为网关,进行整合时,出现了
com.netflix.zuul.exception.ZuulException: Forwarding error
Caused by: com.netflix.client.ClientException: **Load balancer does not have available server for client: **
1.1 异常堆栈信息(简写)
com.netflix.zuul.exception.ZuulException: Forwarding error
Caused by: com.netflix.client.ClientException: Load balancer does not have available server for client: nacos-consumer
at com.netflix.loadbalancer.LoadBalancerContext.getServerFromLoadBalancer(LoadBalancerContext.java:483) ~[ribbon-loadbalancer-2.3.0.jar:2.3.0]
2、问题原因
- spring-cloud-alibaba 2021,nacos 2.x 版本已经没有自带ribbon的整合,所以需要引入另一个支持的jar包 loadbalancer
- spring-cloud-alibaba 2021,nacos 2.x 版本已经取消了对ribbon的支持,所以无法通过修改Ribbon负载均衡的模式来实现nacos提供的负载均衡模式
3、如何解决
3.1 参考博客
https://blog.csdn.net/cxionc123/article/details/107763370
3.2 解决代码
package cn.lyf.nacos.config;
import com.alibaba.cloud.nacos.NacosDiscoveryProperties;
import com.alibaba.cloud.nacos.NacosServiceManager;
import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.api.naming.pojo.Instance;
import com.netflix.client.config.IClientConfig;
import com.netflix.loadbalancer.AbstractLoadBalancerRule;
import com.netflix.loadbalancer.DynamicServerListLoadBalancer;
import com.netflix.loadbalancer.Server;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
/**
* 解决spring-cloud-alibaba 2021.1 Naco 2.1.0 作为注册中心,Zuul作为网关,使用Ribbon进行负载均衡时
* Caused by: com.netflix.client.ClientException: Load balancer does not have available server for client:的异常问题
*
* @author lyf
* @since 2022-06-14
*/
@Slf4j
@Configuration
public class NacosLoadBalancerRule extends AbstractLoadBalancerRule {
@Autowired
private NacosDiscoveryProperties discoveryProperties;
@Autowired
private NacosServiceManager nacosServiceManager;
@Override
public Server choose(Object key) {
DynamicServerListLoadBalancer loadBalancer = (DynamicServerListLoadBalancer) getLoadBalancer();
String name = loadBalancer.getName();
try {
// Instance selectOneHealthyInstance(String serviceName) throws NacosException;
// 会使用默认的Group DEFAULT_GROUP
// Instance selectOneHealthyInstance(String serviceName, String groupName) throws NacosException;
// 如果已经定义了微服务的Group,需要加上此参数
Instance instance = nacosServiceManager.getNamingService(discoveryProperties.getNacosProperties())
.selectOneHealthyInstance(name, discoveryProperties.getGroup());
// NacosServer 在Nacos 2.x版本已经移除,所以替换为new Server(instance.getIp(), instance.getPort())
return new Server(instance.getIp(), instance.getPort());
} catch (NacosException e) {
log.error("", e);
return null;
}
}
@Override
public void initWithNiwsConfig(IClientConfig iClientConfig) {
}
}
3.3 在yaml中禁用eureka
ribbon:
eureka:
enabled: false
4 代码地址
https://gitee.com/liuyangfang/nacos-zuul.git