Ribbon client: "No instances available for xxx"
bgao-ca edited this page Jul 22, 2018
·
4 revisions
Here is the log when "client1" call client2's /greeting
2018-07-20 16:54:17.771 DEBUG [client1,bd71d796b7441b53,240da689decf7d58,true] 34420 --- [o-auto-1-exec-8] o.s.web.client.RestTemplate : Created GET request for "http://client2/greeting"
2018-07-20 16:54:17.788 DEBUG [client1,bd71d796b7441b53,240da689decf7d58,true] 34420 --- [o-auto-1-exec-8] o.s.web.client.RestTemplate : Setting request Accept header to [text/plain, application/json, application/*+json, */*]
2018-07-20 16:54:18.768 INFO [client1,bd71d796b7441b53,ff2cc1a4cb5e684e,true] 34420 --- [o-auto-1-exec-9] c.n.u.concurrent.ShutdownEnabledTimer : Shutdown hook installed for: NFLoadBalancer-PingTimer-client2
2018-07-20 16:54:18.788 DEBUG [client1,bd71d796b7441b53,16e869af5335309c,true] 34420 --- [o-auto-1-exec-6] o.s.web.client.RestTemplate : Created GET request for "http://client2/greeting"
2018-07-20 16:54:18.849 DEBUG [client1,bd71d796b7441b53,16e869af5335309c,true] 34420 --- [o-auto-1-exec-6] o.s.web.client.RestTemplate : Setting request Accept header to [text/plain, application/json, application/*+json, */*]
2018-07-20 16:54:18.968 INFO [client1,bd71d796b7441b53,ff2cc1a4cb5e684e,true] 34420 --- [o-auto-1-exec-9] c.netflix.loadbalancer.BaseLoadBalancer : Client: client2 instantiated a LoadBalancer: DynamicServerListLoadBalancer:{NFLoadBalancer:name=client2,current l
ist of Servers=[],Load balancer stats=Zone stats: {},Server stats: []}ServerList:null
2018-07-20 16:54:19.043 INFO [client1,bd71d796b7441b53,ff2cc1a4cb5e684e,true] 34420 --- [o-auto-1-exec-9] c.n.l.DynamicServerListLoadBalancer : Using serverListUpdater PollingServerListUpdater
2018-07-20 16:54:19.053 INFO [client1,bd71d796b7441b53,ff2cc1a4cb5e684e,true] 34420 --- [o-auto-1-exec-9] c.n.l.DynamicServerListLoadBalancer : DynamicServerListLoadBalancer for client client2 initialized: DynamicServerListLoadBalancer:{NFLoadBalancer:name=
client2,current list of Servers=[],Load balancer stats=Zone stats: {},Server stats: []}ServerList:com.netflix.loadbalancer.ConfigurationBasedServerList@36d65658
2018-07-20 16:54:19.202 WARN [client1,bd71d796b7441b53,4141cbf32481aeeb,true] 34420 --- [o-auto-1-exec-8] com.netflix.loadbalancer.RoundRobinRule : No up servers available from load balancer: DynamicServerListLoadBalancer:{NFLoadBalancer:name=client2,current li
st of Servers=[],Load balancer stats=Zone stats: {},Server stats: []}ServerList:com.netflix.loadbalancer.ConfigurationBasedServerList@36d65658
2018-07-20 16:54:19.258 ERROR [client1,bd71d796b7441b53,33c34c103151d6b5,true] 34420 --- [o-auto-1-exec-9] o.s.c.s.i.web.ExceptionLoggingFilter : Uncaught exception thrown
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is java.lang.IllegalStateException: No instances available for client2
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:982) ~[spring-webmvc-5.0.7.RELEASE.jar!/:5.0.7.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:866) ~[spring-webmvc-5.0.7.RELEASE.jar!/:5.0.7.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:635) ~[tomcat-embed-core-8.5.31.jar!/:8.5.31]
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:851) ~[spring-webmvc-5.0.7.RELEASE.jar!/:5.0.7.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:742) ~[tomcat-embed-core-8.5.31.jar!/:8.5.31]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) [tomcat-embed-core-8.5.31.jar!/:8.5.31]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-8.5.31.jar!/:8.5.31]
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) ~[tomcat-embed-websocket-8.5.31.jar!/:8.5.31]
......
java.lang.IllegalStateException: No instances available for client2
at org.springframework.cloud.netflix.ribbon.RibbonLoadBalancerClient.execute(RibbonLoadBalancerClient.java:104) ~[spring-cloud-netflix-ribbon-2.0.0.RELEASE.jar!/:2.0.0.RELEASE]
at org.springframework.cloud.client.loadbalancer.RetryLoadBalancerInterceptor.lambda$intercept$0(RetryLoadBalancerInterceptor.java:76) ~[spring-cloud-commons-2.0.0.RELEASE.jar!/:2.0.0.RELEASE]
at org.springframework.retry.support.RetryTemplate.doExecute(RetryTemplate.java:287) ~[spring-retry-1.2.2.RELEASE.jar!/:na]
at org.springframework.retry.support.RetryTemplate.execute(RetryTemplate.java:180) ~[spring-retry-1.2.2.RELEASE.jar!/:na]
at org.springframework.cloud.client.loadbalancer.RetryLoadBalancerInterceptor.intercept(RetryLoadBalancerInterceptor.java:67) ~[spring-cloud-commons-2.0.0.RELEASE.jar!/:2.0.0.RELEASE]
at org.springframework.http.client.InterceptingClientHttpRequest$InterceptingRequestExecution.execute(InterceptingClientHttpRequest.java:92) ~[spring-web-5.0.7.RELEASE.jar!/:5.0.7.RELEASE]
at brave.spring.web.TracingClientHttpRequestInterceptor.intercept(TracingClientHttpRequestInterceptor.java:53) ~[brave-instrumentation-spring-web-5.1.0.jar!/:na]
at org.springframework.cloud.sleuth.instrument.web.client.LazyTracingClientHttpRequestInterceptor.intercept(TraceWebClientAutoConfiguration.java:292) ~[spring-cloud-sleuth-core-2.0.0.RELEASE.jar!/:2.0.0.RELEASE]
at org.springframework.http.client.InterceptingClientHttpRequest$InterceptingRequestExecution.execute(InterceptingClientHttpRequest.java:92) ~[spring-web-5.0.7.RELEASE.jar!/:5.0.7.RELEASE]
at org.springframework.http.client.InterceptingClientHttpRequest.executeInternal(InterceptingClientHttpRequest.java:76) ~[spring-web-5.0.7.RELEASE.jar!/:5.0.7.RELEASE]
at org.springframework.http.client.AbstractBufferingClientHttpRequest.executeInternal(AbstractBufferingClientHttpRequest.java:48) ~[spring-web-5.0.7.RELEASE.jar!/:5.0.7.RELEASE]
at org.springframework.http.client.AbstractClientHttpRequest.execute(AbstractClientHttpRequest.java:53) ~[spring-web-5.0.7.RELEASE.jar!/:5.0.7.RELEASE]
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:723) ~[spring-web-5.0.7.RELEASE.jar!/:5.0.7.RELEASE]
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:680) ~[spring-web-5.0.7.RELEASE.jar!/:5.0.7.RELEASE]
at org.springframework.web.client.RestTemplate.getForObject(RestTemplate.java:332) ~[spring-web-5.0.7.RELEASE.jar!/:5.0.7.RELEASE]
at com.test.cloud.client1.Client1Application.greeting(Client1Application.java:48) ~[classes!/:1.0.1-SNAPSHOT]
the message "No up servers available from load balancer" is from RibbonRule's choose, in my case since I integreated the Ribbon with Eureka, it should get the server list from eureka registration server but it got an empty server list, and the eureka server works fine and zuul also works fine.
my configuration is:
application.properties
spring.application.name=client1
server.port=0
# eureka server settings
eureka.client.service-url.default-zone=http://127.0.0.1:8761/eureka
eureka.client.registerWithEureka=true
eureka.client.fetchRegistry=true
eureka.instance.preferIpAddress=true
eureka.instance.instance-id=${spring.cloud.client.hostname}:${spring.application.name}:${random.int}
eureka.instance.home-page-url-path=/actuator/info
# ribbon settings for retry
#em-client2.ribbon.MaxAutoRetries=3
#em-client2.ribbon.MaxAutoRetriesNextServer=3
#em-client2.ribbon.OkToRetryOnAllOperations=true
#
ribbon.MaxAutoRetries=3
ribbon.MaxAutoRetriesNextServer=3
ribbon.OkToRetryOnAllOperations=true
# configuration server
spring.cloud.config.uri=http://localhost:8761/config
management.endpoints.web.exposure.include=*
#logging.level.org.apache.http=DEBUG
logging.level.org.springframework.web.client.RestTemplate=DEBUG
Java code:
package com.test.cloud.client1;
import com.netflix.loadbalancer.IPing;
import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.PingUrl;
import com.netflix.loadbalancer.RoundRobinRule;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.netflix.ribbon.RibbonClients;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
@Slf4j
@RestController
@RibbonClients(defaultConfiguration = {Client2ClientConfiguration.class })
@EnableDiscoveryClient
@SpringBootApplication
public class Client1Application {
@Bean
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
}
@Autowired
private Environment environment;
@Autowired
@LoadBalanced
private RestTemplate restTemplate;
@Value("${spring.application.name}")
private String appName;
@RequestMapping("/greeting")
public String greeting() {
String port = environment.getProperty("local.server.port");
String msgFromClient2 = restTemplate.getForObject("http://client2/greeting", String.class);
String message = String.format("Hello from '%s:%s' from [%s]!", appName, port, msgFromClient2);
log.debug(message);
return message;
}
public static void main(String[] args) {
SpringApplication.run(Client1Application.class, args);
}
}
@Configuration
class Client2ClientConfiguration {
@Bean
public IPing ribbonPing() {
PingUrl pingUrl = new PingUrl();
pingUrl.setPingAppendString("/actuator/info");
return pingUrl;
}
@Bean
public IRule ribbonRule() {
return new RoundRobinRule();
}
}
Solution:
we need to include the following jar file in classpath, then the auto configuration will automatically apply the RibbonEurekaAutoConfiguration which will apply the configuration EurekaRibbonClientConfiguration.
<dependency>
<groupId>com.netflix.ribbon</groupId>
<artifactId>ribbon-eureka</artifactId>
</dependency>
@RibbonClients(
defaultConfiguration = {EurekaRibbonClientConfiguration.class}
)