2

I am trying to call a zuul enabled server through RestTemplate by directly giving the URL. For example: restTemplate.getForObject("http://localhost:8090/emp-api", Employee[].class);

But it is giving an error to me:

java.lang.IllegalStateException: No instances available for localhost at org.springframework.cloud.netflix.ribbon.RibbonLoadBalancerClient.execute(RibbonLoadBalancerClient.java:90) ~[spring-cloud-netflix-core-1.2.3.RELEASE.jar:1.2.3.RELEASE]

Question in detail : I am having four projects (Github link (branch-master): https://github.com/vickygupta0017/microservice-poc)

  1. microservice-server (eureka-server) port:8080
  2. microservice-producer (Rest-api) port:8086
  3. zuul-gatewayproxy (zuul-server) port:8090
  4. microservice-consumer (spring-mvc) port:8087

    Flow Image

If I am calling zuul server directly from browser("http://localhost:8090/emp-api), then it is redirecting the request to producer successfully. But if I am calling this URL from the consumer through RestTemplate then it is giving me this error.

For Information : If I am not using zuul sever then I am able to call 'microservice-producer' from 'microservice-consumer' using RestTemplate successfully.

Vicky
  • 1,135
  • 1
  • 17
  • 37
  • See here: https://stackoverflow.com/questions/31574131/ribbon-with-spring-cloud-and-eureka-java-lang-illegalstateexception-no-instanc – diginoise Feb 15 '18 at 11:00
  • @diginoise, its not the case for me, I am already using "http://" before url. – Vicky Feb 15 '18 at 11:10

3 Answers3

2

I had successfully executed your code with below changes, removed the

enablediscovery and LoadBalanced annotation

if this will be enabled then always rest template will go to eureka for discovery, as you are using proxy server then your consumer don't need the discovery because you are giving absolute path also remove eureka configurations from application.yml.

You cannot use discovery and absolute path at the same time, only one can be used at a time.

package com.eureka.discovery.client;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import com.eureka.discovery.client.bo.Employee;

@SpringBootApplication
@RestController
//@EnableDiscoveryClient
public class UserApplication {

  @Bean
//@Loadbalancer
  RestTemplate restTemplate(){
    return new RestTemplate();
  }

  @Autowired
  RestTemplate restTemplate;

  @RequestMapping("/hi")
  public String hi() {
      Employee[] employeeList = this.restTemplate.getForObject("http://localhost:8090/emp-api", Employee[].class);
    return String.format("%s, %s!", "Testing", "Abhay");
  }

  public static void main(String[] args) {
    SpringApplication.run(UserApplication.class, args);
  }
}
ABHAY JOHRI
  • 1,997
  • 15
  • 19
  • I do not know, how you are successfully able to execute my code as to access my producer service you have to pass URL (http://localhost:8090/emp-api). where zuul server is running at port 8090 and `emp-api` is what zuul server will catch and route it to my producer. I am able to successfully run it if I am hitting this URL from a browser but when I am hitting it from 'microservice-consumer-zull' it is giving an error. – Vicky Feb 16 '18 at 16:48
  • You are asking for help or you are arguing? Check the file that I had shared and replace abhay with emp-api, I had replaced it with abhay. I – ABHAY JOHRI Feb 16 '18 at 16:56
  • Still you have any doubt let me know. I had executed it then I am saying ..Ok.. look the code carefully instead of arguments.. learn how to take help from anyone. – ABHAY JOHRI Feb 16 '18 at 16:58
  • Sorry for any misunderstanding and my intention was not like this, I know there is something which I am not getting or missing. Actually, I had tried the things as per your suggestion but did not work for me. For simplicity, I have created a new git repository (https://github.com/vickygupta0017/microservice-zuul), where I have put everything as per your suggestion but still getting the same issue. It will be very helpful if you will point out my mistake.Btw thanks for the answers. – Vicky Feb 16 '18 at 18:55
  • if you can share your github address, I will add you to this repository contributors, so that you will be able to make changes. I am new to these kinds of stuff, your guidance can give more to me. – Vicky Feb 16 '18 at 19:01
  • I tried to update the code in your shared location but I dont have access, I had shared the workable code my github(https://github.com/abhayjohri87/Microservice). – ABHAY JOHRI Feb 17 '18 at 02:34
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/165313/discussion-between-abhay-johri-and-gaurav). – ABHAY JOHRI Feb 17 '18 at 02:35
  • thanks for your support. The issue was with the annotation LoadBalanced, I had used it over RestTemplate bean creation, that was causing the issue. – Vicky Feb 17 '18 at 05:56
  • if you can look into this also (https://stackoverflow.com/questions/48863771/failure-while-calling-a-microservice-via-ribbon-enabled-client) – Vicky Feb 19 '18 at 16:43
1

The RestTemplate instance might have been configured to lookup the service localhost via Eureka instead of assuming http://localhost:.... is already the URL

ootero
  • 3,235
  • 2
  • 16
  • 22
  • Yes that was the case, RestTemplate instance was configured with annotation LoadBalanced, that is why it was looking for service via Eureka. +1 for that answer. – Vicky Feb 17 '18 at 06:03
  • if you can look into this also (https://stackoverflow.com/questions/48863771/failure-while-calling-a-microservice-via-ribbon-enabled-client). – Vicky Feb 19 '18 at 16:44
0

If you are calling the services with ip and port then there is no need of Eureka, As you are doing inter micro service communication and eureka is already in picture for service discovery and registry. You want to do load balancing then zuul will come in picture.

Change your code in consumer with mricroservice name instead of ip and port then it will work.

@SpringBootApplication
@EnableDiscoveryClient
public class WebclientConsumerMicroserviceApplication {

    public static final String EMPLOYEE_SERVICE_URL = "http://employee-microservice/";

and also change the remaining uri in employeeServicesImpl.

    public List<Employee> getEmployeeList() {
//  Employee[] employeeList =  restTemplate.getForObject("http://employee-microservice/employees", Employee[].class);
    Employee[] employeeList =  restTemplate.getForObject(url+"employees, Employee[].class);

It will be working Just start this way :

  1. Start your Eureka
  2. Start the Producer Service
  3. Start the Consumer Service and it will be workable.

Note : We need to call the services only via service name and needs to avoid ip and port(they are dynamic).

If you want to run using zuul then use the zuul service name : zuul-gateway with below configuration in consumer

zuul-gateway:
  ribbon:
    eureka:
      enabled: false
    listOfServers: localhost:8090
    ServerListRefreshInterval: 1500
ABHAY JOHRI
  • 1,997
  • 15
  • 19
  • you cannot call producer with localhost:8090 from consumer, as localhost is not registered with eureka because of that eureka not able to find which microservice to call. – ABHAY JOHRI Feb 16 '18 at 12:53
  • I am not using `eureka` for zuul at all, see the `develop` branch. I am trying to consume a service via `zuul-proxy` (i.e. `microservice-consumer-zuul` will intract with `zuul-proxy-server` to find what service to consume of `microservice-producer`). – Vicky Feb 16 '18 at 14:10
  • what you have suggested is to consume the producer service directly (using eureka service discovery). which is already working if you will see 'microservice-consumer', It is consuming the producer service. And as far as I know 'zuul' is not used for the load balancing, it is used as a proxy server for routing. – Vicky Feb 16 '18 at 14:19