0

I am trying to call a 'microservice'(microservice-producer) via ribbon enabled the client(ribbon-client) but it is giving me an error.

java.lang.IllegalStateException: No instances available for employee-microservice

I am following the official spring.io link for the client side load balancing(https://spring.io/guides/gs/client-side-load-balancing/) and I am also following all the specification given at this link. You can see the code at my GitHub address : (https://github.com/vickygupta0017/microservice-ribbon).

I am not sure what I am missing or doing wrong, could someone please help me out?

Vicky
  • 1,135
  • 1
  • 17
  • 37

2 Answers2

1

In case where eureka server is not used to identify whether server is reachable or not , ribbon client uses "RibbonConfiguration" - pingUrl parameter. By Default it is empty string that means it is going to ping list of server without any context to get an answer whether server is reachable or not. So here you can do 2 things.

  1. Create a service that is bound to root context of the server "/" and send a positive response.

    @RequestMapping(value = "/")
    public String status(HttpServletRequest request) {
        return "";
    }
    
  2. Or update Ribbon client Configuration (EmployeeConfiguration) and return PingUrl with relevant "service-name".

    @Bean
    public IPing ribbonPing(IClientConfig config) {
       return new PingUrl(false,"/employees");
    }
    

Go for the first one as it will solve the basic purpose to see if server is reachable or not.

Ref: https://spring.io/guides/gs/client-side-load-balancing/

Our IPing is a PingUrl, which will ping a URL to check the status of each server. Say Hello has, as you’ll recall, a method mapped to the / path; that means that Ribbon will get an HTTP 200 response when it pings a running Say Hello server. The IRule we set up, the AvailabilityFilteringRule, will use Ribbon’s built-in circuit breaker functionality to filter out any servers in an “open-circuit” state: if a ping fails to connect to a given server, or if it gets a read failure for the server, Ribbon will consider that server “dead” until it begins to respond normally.

fly2matrix
  • 2,351
  • 12
  • 13
  • thanks a lot for the well-explained answer. you deserve more but I can give only +1. – Vicky Feb 20 '18 at 14:52
  • we can also remove the method `ribbonPing` from the configuration, by doing this it is not going to check the availability of server by a method mapped to the / path. – Vicky Feb 21 '18 at 15:36
0

Configuration for Ribbon Client are not Correct, I had executed the code successfully with below changes in Ribbon Client, On Client call it were throwing Null Pointer Exception as several parameters of Ribbon Client were not set successfully along with that I can see @Configuration were missing in EmployeeConfiguration Class, hence how it will initialize Ribbon client.

Also Checked in the complete workable code at below location :

https://github.com/abhayjohri87/RibbonClientLBWithMicroServices.git

package com.ribbon.client;
import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.netflix.ribbon.RibbonClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import com.netflix.client.config.DefaultClientConfigImpl;
import com.netflix.client.config.IClientConfig;
import com.netflix.loadbalancer.ConfigurationBasedServerList;
import com.netflix.loadbalancer.Server;
import com.netflix.loadbalancer.ServerList;
//import com.ribbon.Employee.configuration.EmployeeConfiguration;
import com.ribbon.client.RibbonClientApplication.UserConfig;


@SpringBootApplication
@RestController
@RibbonClient(name = "employee-microservice", configuration = UserConfig.class)
public class RibbonClientApplication {

      @LoadBalanced
      @Bean
      RestTemplate restTemplate(){
        return new RestTemplate();
      }

      @Autowired
      RestTemplate restTemplate;

      @RequestMapping("/listEmployee")
      public List getEmployeeList() {
        List empList = this.restTemplate.getForObject("http://employee-microservice/employees", ArrayList.class);
        return empList;
      }

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


    @Configuration
    static class UserConfig {

        private String name = "employee-microservice";

        @Bean
        @ConditionalOnMissingBean
        public IClientConfig ribbonClientConfig() {
            DefaultClientConfigImpl config = new DefaultClientConfigImpl();
            config.loadProperties(this.name);
            return config;
        }

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

    }
}
ABHAY JOHRI
  • 1,997
  • 15
  • 19