spring-cloud / spring-cloud-netflix

Integration with Netflix OSS components
http://cloud.spring.io/spring-cloud-netflix/
Apache License 2.0
4.86k stars 2.44k forks source link

Ribbon not loading a list of servers during spring boot startup or initialisation #2705

Closed RohitGupta31 closed 5 years ago

RohitGupta31 commented 6 years ago

Bug:

I want to use the listofservers which are defined in a configuration file during spring boot startup (i.e. in a @Postconstruct annotation) to connect to an aws s3 instance.

  ribbon:
    listOfServers: localhost:8080
    ServerListRefreshInterval: 15000

Eureka is disabled.

This is being set using the

@RibbonClient(name = "test", configuration = TestConfiguration.class).

Am autowiring the loadbalacer client

    @Autowired
    private LoadBalancerClient loadBalancer;
eg: @PostConstruct
loadBalancer.choose("test").getUri().toString()

& loading the servers in a config file as

   @Bean
    public ServerList<Server> ribbonServerList(IClientConfig config) {
        ConfigurationBasedServerList serverList = new ConfigurationBasedServerList();
        serverList.initWithNiwsConfig(config);
        return serverList;
    }.

But the list of servers during initialization is always empty, so i get back an exception that riboon client cannot find the list of servers during springboot startup.

: No up servers available from load balancer: DynamicServerListLoadBalancer:{NFLoadBalancer:name=s3,current list of Servers=[],Load balancer stats=Zone stats: {},Server stats: []}ServerList:com.netflix.loadbalancer.ConfigurationBasedServerList@3efedc6f
WARN 19548 --- [main] c.netflix.loadbalancer.BaseLoadBalancer  : LoadBalancer [s3]:  Error choosing server for key default

even though the serverList is defined in the application.yml file, if i don't read the serverList from @postcontruct annotation it is working fine.

I looked up online but could not find examples of using this in a @postcontruct annotation, but i need this to be used there is there any other alternative?

RohitGupta31 commented 6 years ago

user.zip

Attached a test project & the logs with which the issue is reproducible

logs during application startup.txt

ryanjbaxter commented 6 years ago

Please learn how to format code on GitHub.

I would imagine that your @PostConstruct code is running before Ribbon is fully initialized. I am not sure what we could do about that.

RohitGupta31 commented 6 years ago

Ok.

Yep you are right, but the loadbalancerclient is autowired so I thought the server list to be set before we use it in @PostContruct, we would need the list of servers to be used during initialisation as there are calls to be made to S3 server to create a bucket.

Do you reckon this as a bug otherwise is there an alternative. Appreciate your reply.

spencergibb commented 6 years ago

We've generally not recommended using ribbon during initialization phases. This may help: http://cloud.spring.io/spring-cloud-static/Edgware.SR1/single/spring-cloud.html#ribbon-child-context-eager-load

RohitGupta31 commented 6 years ago

Thanks, that property doesn't seem to have any effect, still getting the same error. I have added that to yaml file as follows.

say-hello:
  ribbon:
    eureka:
      enabled: false
    eager-load:
      enabled: true
      clients: localhost:8090,localhost:9092,localhost:9999
    listOfServers: localhost:8090,localhost:9092,localhost:9999
    ServerListRefreshInterval: 15000

Is that the correct way?

spencergibb commented 6 years ago

no, clients is the ribbon client name. In your case say-hello.

RohitGupta31 commented 6 years ago

oops unfortunately even that doesn't seem to have any effect. Getting the same error. user.zip

say-hello:
  ribbon:
    eureka:
      enabled: false
    eager-load:
      enabled: true
      clients: say-hello
    listOfServers: localhost:8090,localhost:9092,localhost:9999
    ServerListRefreshInterval: 15000
spencergibb commented 6 years ago

eager-load can't be under say-hello:. It needs to be:

ribbon:
  eureka:
     enabled: false
  eager-load:
    enabled: true
    clients: say-hello
say-hello:
  ribbon:
    listOfServers: localhost:8090,localhost:9092,localhost:9999
    ServerListRefreshInterval: 15000
RohitGupta31 commented 6 years ago

Still no luck tho. Getting the same error in the startup log I noticed that ribbon.eager-load.enabled property is matched.

RibbonAutoConfiguration#ribbonApplicationContextInitializer matched:

logs.txt

spencergibb commented 6 years ago

Not sure what else to say:

We've generally not recommended using ribbon during initialization phases.

RohitGupta31 commented 6 years ago

Just wondering if adding ribbon.eager-load.enabled property does not list the servers during startup, could this be a bug?

spencergibb commented 6 years ago

@RohitGupta31 only if you provide a minimal project that recreates the problem.

ArtemZubenko commented 6 years ago

Hi Rohit, Try deleting @Bean public IRule ribbonRule(IClientConfig config) { return new AvailabilityFilteringRule(); } from your SayHelloConfiguration.java

anhtuanluu36 commented 6 years ago

@spencergibb I have the same issue like @RohitGupta31. I added the following lines in application.yaml:

ribbon:
  eager-load:
    enabled: true
    clients: merchant-security
  eureka:
    enabled: false
merchant-security:
  ribbon:
    listOfServers: localhost:8081, localhost:8082
    ServerListRefreshInterval: 15000

I used @FeignClient: @FeignClient(name = "merchantSecurityPermissionClient", serviceId = "merchant-security")

In the method "public void configure(HttpSecurity http) throws Exception" of the Configuration class (this class extends ResourceServerConfigurerAdapter.java). I called @FeignClient and it return an error: Caused by: com.netflix.client.ClientException: Load balancer does not have available server for client: merchant-security

However, after Spring Boot StartUp, I call @FeignClient again and it works fine.

raulvillalbamedina commented 6 years ago

I have the same problem, I remove the ribbonRule and works fine. thanks @ArtemZubenko . Why? Is correct not use ribbonRule?

spring-projects-issues commented 5 years ago

Closing due to age of the question. If you would like us to look at this issue, please comment and we will look at re-opening the issue.

kanghouchao commented 5 years ago

I have the same problem,I push my code to git : https://github.com/kanghouchao/oldheaven.git

When I run test in restlet for this url : http://localhost:8080/test first I get right response When request for this url second I get a exception : com.netflix.client.ClientException Befor the exception I get a warn : No up servers available from load balancer

spencergibb commented 5 years ago

@kanghouchao unfortunately, your sample is very complex and there are no instructions on how to reproduce it. Please simplify your sample and provide instructions.

kanghouchao commented 5 years ago

@spencergibb thanks for your suggest,I pushed a simply demo as I can to github:https://github.com/kanghouchao/sample-springcloud.git About instructions, I don't know how to explain that demo sorry for my poor english I luncher two module's Starter in springboot,the server and client I want to use the feign client in model named client to get the message from the module named server The requestmapping in server registed in zookeeper-3.4.13.

And I think the error is from Ribbon,I added Ribbon but I didn't use it,There is not Configuration for Ribbon that's all, Thanks again.

kanghouchao commented 5 years ago

@spencergibb I forgot saying that I used zookeeper dependencies in client

kanghouchao commented 5 years ago

@spencergibb If I don't use the zookeeper dependecies configuration, Everything is ok

kanghouchao commented 5 years ago

@spencergibb or use RestTemplate.getForObject(...)