我们可以通过 RestTemplate 调用启用 Zuul 的服务器吗

Can we call Zuul enabled server through RestTemplate

我试图通过直接提供 URL 通过 RestTemplate 调用启用 zuul 的服务器。 例如:restTemplate.getForObject("http://localhost:8090/emp-api", Employee[].class);

但是它给我一个错误:

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]

问题详细 : 我有四个项目 (Github link (branch-master): https://github.com/vickygupta0017/microservice-poc)

  1. 微服务服务器(尤里卡服务器)port:8080
  2. 微服务生产者(Rest-api)port:8086
  3. zuul-gatewayproxy (zuul-server) port:8090
  4. 微服务消费者(spring-mvc)port:8087

如果我直接从浏览器调用 zuul server("http://localhost:8090/emp-api),那么它将请求成功重定向到生产者。 但是如果我通过 RestTemplate 从消费者那里调用这个 URL 那么它就会给我这个错误。

参考: 如果我没有使用 zuul 服务器,那么我可以使用 RestTemplate 从 'microservice-consumer' 成功调用 'microservice-producer'。

如果您使用 ip 和端口调用服务,则不需要 Eureka,因为您正在进行微服务间通信,而 eureka 已经在服务发现和注册中。你想做负载均衡然后 zuul 就会出现。

使用微服务名称而不是 ip 和端口更改消费者中的代码,然后它将起作用。

@SpringBootApplication
@EnableDiscoveryClient
public class WebclientConsumerMicroserviceApplication {

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

并更改 employeeServicesImpl 中剩余的 uri。

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

它会起作用的就这样开始吧:

  1. 启动你的尤里卡
  2. 启动生产者服务
  3. 启动消费者服务即可。

注意:我们只需要通过服务名称调用服务,需要避免 ip 和端口(它们是动态的)。

如果你想 运行 使用 zuul 然后使用 zuul 服务名称:zuul-gateway 在 consumer

中配置如下
zuul-gateway:
  ribbon:
    eureka:
      enabled: false
    listOfServers: localhost:8090
    ServerListRefreshInterval: 1500

我已通过以下更改成功执行了您的代码,删除了

enablediscovery and LoadBalanced annotation

如果这将被启用,那么总是休息模板将去尤里卡发现,因为你正在使用代理服务器然后你的消费者不需要发现,因为你正在提供绝对路径也从 [=18 删除尤里卡配置=].

不能同时使用发现和绝对路径,一次只能使用一个。

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);
  }
}

RestTemplate 实例可能已配置为通过 Eureka 查找服务 localhost 而不是假设 http://localhost:.... 已经是 URL