错误堆栈信息:
java.lang.NullPointerException: null
at com.google.common.base.Preconditions.checkNotNull(Preconditions.java:213) ~[guava-16.0.1.jar:na]
at com.google.common.cache.LocalCache.get(LocalCache.java:3933) ~[guava-16.0.1.jar:na]
at com.google.common.cache.LocalCache.getOrLoad(LocalCache.java:3938) ~[guava-16.0.1.jar:na]
at com.google.common.cache.LocalCache$LocalLoadingCache.get(LocalCache.java:4821) ~[guava-16.0.1.jar:na]
at com.netflix.loadbalancer.LoadBalancerStats.getServerStats(LoadBalancerStats.java:185) ~[ribbon-loadbalancer-2.3.0.jar:2.3.0]
at com.netflix.loadbalancer.LoadBalancerStats.getSingleServerStat(LoadBalancerStats.java:372) ~[ribbon-loadbalancer-2.3.0.jar:2.3.0]
at com.netflix.loadbalancer.AvailabilityPredicate.apply(AvailabilityPredicate.java:73) ~[ribbon-loadbalancer-2.3.0.jar:2.3.0]
at com.netflix.loadbalancer.AvailabilityPredicate.apply(AvailabilityPredicate.java:35) ~[ribbon-loadbalancer-2.3.0.jar:2.3.0]
Servlet.service() for servlet [dispatcherServlet] in context with path [] threw
exception [Request processing failed; nested exception is
java.lang.IllegalStateException: No instances available for user-service] with root
cause
从以上提示信息中可以发现错误原因为java.lang.IllegalStateException: No instances available for user-service] with root cause,无法找到该实例,导致这个出错的原因在于我们使用@RibbonClient指定了自定义的负载均衡配置实现类,可见该类中一定有错误,我们可以通过查看相关实现类以及配置文件控制台输出的一些提示信息来找出原因;
server.port=8090
spring.application.name=api-getaway
#eureka.client.service-url.defaultZone=http://127.0.0.1:8666/eureka
#消费者无需注册
eureka.client.register-with-eureka=false
logbook.write.level=info
logbook.format.style=curl
ribbon.eureka.enabled=false
#every 15 seconds
server.ribbon.ServerListRefreshInterval=15000
user-service.ribbon.listOfServers=127.0.0.1:8081,127.0.0.1:8082
package com.qingyun.house.api;
import com.qingyun.house.api.config.NewRuleConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.ribbon.RibbonClient;
import org.springframework.cloud.netflix.ribbon.RibbonClients;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.List;
//@EnableDiscoveryClient
@RibbonClients(value = {@RibbonClient(name = "user-service",configuration = NewRuleConfig.class)})
@SpringBootApplication
@Controller
public class ApiGetawayApplication {
public static void main(String[] args) {
SpringApplication.run(ApiGetawayApplication.class, args);
}
@Autowired
public DiscoveryClient discoveryClient;
@ResponseBody
@RequestMapping(value = "/get")
public List getRegister(){
return discoveryClient.getInstances("user-service");
}
}
package com.qingyun.house.api.config;
import com.netflix.loadbalancer.*;
import org.springframework.context.annotation.Bean;
public class NewRuleConfig {
@Bean
public IPing ribbonPing(){
return new PingUrl(false,"/health");
}
@Bean
public IRule ribbonRule(){
//return new RandomRule();
return new AvailabilityFilteringRule();
}
}
2020-01-07 17:11:32.202 WARN 13272 --- [nio-8090-exec-6]
com.netflix.loadbalancer.RoundRobinRule : No up servers available from load balancer:
DynamicServerListLoadBalancer:{NFLoadBalancer:name=user-service,current list of
Servers=[127.0.0.1:8081, 127.0.0.1:8082],Load balancer stats=Zone stats: {unknown=
[Zone:unknown; Instance count:2; Active connections count: 0; Circuit breaker
tripped count: 0; Active connections per server: 0.0;]
从以上日志中可以发现我们在配置文件中配置的节点信息是不可用的,由此可以确定以上路径是Ping
不通的,由此我们去检查服务提供者的日志打印信息。
2020-01-07 17:39:57.693 INFO 13212 --- [nio-8081-exec-9] org.zalando.logbook.Logbook : Incoming Request: 85a2a255ae3346f4
GET http://127.0.0.1:8081/health HTTP/1.1
host: 127.0.0.1:8081
connection: Keep-Alive
user-agent: Apache-HttpClient/4.5.10 (Java/1.8.0_121)
2020-01-07 17:39:57.696 INFO 13212 --- [nio-8081-exec-9] org.zalando.logbook.Logbook : Outgoing Response: 85a2a255ae3346f4
Duration: 3 ms
HTTP/1.1 404 Not Found
分析以上日志可以发现http://127.0.0.1:8081/health
无法访问,原因在于SpringBoot Actuator健康监测有一个默认前缀为/actuator
,所以我们的解决方案有两种:
/
,在配置文件中修改 management.endpoints.web.base-path=/
actuator/health
@Bean
public IPing ribbonPing(){
return new PingUrl(false,"/actuator/health");
}
以上问题被完美解决!
原文地址:https://blog.csdn.net/qq_43199016/article/details/103878184