Y.Huang
Y.Huang

Reputation: 119

annotation @RibbonClient not work together with RestTemplate

I am trying Ribbon configuration with RestTemplate based on bookmark service example but without luck, here is my code:

@SpringBootApplication
@RestController
@RibbonClient(name = "foo", configuration = SampleRibbonConfiguration.class)
public class BookmarkServiceApplication {

    public static void main(String[] args) {
        SpringApplication.run(BookmarkServiceApplication.class, args);
    }

    @Autowired
    RestTemplate restTemplate;

    @RequestMapping("/hello")
    public String hello() {
        String greeting = this.restTemplate.getForObject("http://foo/hello", String.class);
        return String.format("%s, %s!", greeting);
    }
}

with error page as below:

Whitelabel Error Page

This application has no explicit mapping for /error, so you are seeing this as a fallback.

Tue Mar 22 19:59:33 GMT+08:00 2016
There was an unexpected error (type=Internal Server Error, status=500).
No instances available for foo

but if I remove annotation @RibbonClient, everything will be just ok,

@RibbonClient(name = "foo", configuration = SampleRibbonConfiguration.class)

and here is SampleRibbonConfiguration implementation:

public class SampleRibbonConfiguration {

  @Autowired
  IClientConfig ribbonClientConfig;

  @Bean
  public IPing ribbonPing(IClientConfig config) {
    return new PingUrl();
  }

  @Bean
  public IRule ribbonRule(IClientConfig config) {
    return new AvailabilityFilteringRule();
  }
}

Is it because RibbonClient can not work with RestTemplate together?

and another question is that does Ribbon configuration like load balancing rule could be configured via application.yml configuration file? as from Ribbon wiki, seems we can configure Ribbon parameters like NFLoadBalancerClassName, NFLoadBalancerRuleClassName etc in property file, does Spring Cloud also supports this?

Upvotes: 0

Views: 1687

Answers (1)

dustin.schultz
dustin.schultz

Reputation: 13646

I'm going to assume you're using Eureka for Service Discovery.

Your particular error:

No instances available for foo

can happen for a couple of reasons

1.) All services are down

All of the instances of your foo service could legitimately be DOWN.

Solution: Try visiting your Eureka Dashboard and ensure all the services are actually UP.

If you're running locally, the Eureka Dashboard is at http://localhost:8761/

2.) Waiting for heartbeats

When you very first register a service via Eureka, there's a period of time where the service is UP but not available. From the documentation

A service is not available for discovery by clients until the instance, the server and the client all have the same metadata in their local cache (so it could take 3 heartbeats)

Solution: Wait a good 30 seconds after starting your foo service before you try calling it via your client.

In your particular case I'm going to guess #2 is likely what's happening to you. You're probably starting the service and trying to call it immediately from the client.

When it doesn't work, you stop the client, make some changes and restart. By that time though, all of the heartbeats have completed and your service is now available.

For your second question. Look at the "Customizing the Ribbon Client using properties" section in the reference documentation. (link)

Upvotes: 2

Related Questions