Skip to content

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}
)
Clone this wiki locally