Как настроить приложение Spring Cloud Gateway, чтобы оно могло использовать Service Discovery в Spring Cloud Kubernetes? - PullRequest
0 голосов
/ 16 мая 2019

Я создал два приложения Spring Boot, которые будут развернуты в кластере Kubernetes.Одно из этих приложений будет действовать как шлюз и, следовательно, использует Spring Cloud Gateway в качестве зависимости.Также я хочу интегрировать обнаружение служб с Spring Cloud Kubernetes и чтобы шлюз использовал обнаружение служб для автоматической генерации соответствующих маршрутов.Но когда я открываю приложение шлюза, работающее в локальном кластере Minikube, и вызываю второе приложение / службу, я получаю сообщение об ошибке 503 со следующим сообщением: Unable to find instance for ...-service

В настоящее время я установил следующее:

  • Minikube
  • VirtualBox
  • Docker Toolbox

Я создал проект Gradle с двумя подпроектами (шлюзом и другим сервисом).Все проекты будут построены / развернуты локально.Учетная запись службы по умолчанию имеет разрешение на чтение API Kubernetes.После развертывания этих сервисов я выставляю службу шлюза извне.В службе шлюза у меня реализованы некоторые конечные точки, которые

  1. предоставляют список всех служб в кластере с помощью DiscoveryClient.
  2. на прикладном уровне вызывают другую службу на основе URIпредоставляется DiscoveryClient.

Кажется, все работает, но когда я вызываю другую службу с URI/serviceId, я получаю ошибку 503 ...

Используются следующие версии Spring Cloud:spring-cloud-starter-kubernetes 1.0.1.RELEASE spring-cloud-starter-gateway 2.1.1.RELEASE

Мое демонстрационное приложение доступно на https://github.com/nmaoez/spring-cloud-gateway-kubernetes, а README.md предоставляет шаги дляполучить обе службы в локальном кластере Minikube.Также показаны все доступные конечные точки.Но интересной частью являются application.yaml и класс приложения шлюза.

application.yaml:

spring:
  application:
    name: gateway-service
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true
          lower-case-service-id: true
management:
  endpoints:
    web:
      exposure:
        include: '*'

GatewayApplication.java

@SpringBootApplication
@EnableDiscoveryClient
@RestController
public class GatewayApplication {

  @Autowired
  RestTemplate restTemplate;

  @Autowired
  private DiscoveryClient discoveryClient;

  @GetMapping("/")
  @ResponseBody
  public String hello() {
    return "GatewayApplication says hello!";
  }

  @GetMapping("/test")
  @ResponseBody
  public String invokeTestService() {
    List<ServiceInstance> testServiceInstances = this.discoveryClient.getInstances("test-service");
    return restTemplate.getForObject(testServiceInstances.get(0).getUri(), String.class);
  }

  @GetMapping("/services")
  public List<String> services() {
    return this.discoveryClient.getServices();
  }

  @GetMapping("/services/{serviceId}")
  public List<ServiceInstance> servicesById(@PathVariable("serviceId") String serviceId) {
    return this.discoveryClient.getInstances(serviceId);
  }

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

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

Я получилЭто как-то работает после того, как я переписал поле выражения url в gateway-service / application.yaml в

url-expression: "uri+'/'"

После этого я получил правильный ответ после того, как вызвал gateway-uri/another-service/.Но я не хочу явно заменять значение по умолчанию lb://serviceid.Как я могу это сделать?

Я ожидаю, что если я вызову другую службу в кластере через шлюз, я получу ответ 200 и правильный ответ, основанный на контроллере остальных приложений.

1 Ответ

0 голосов
/ 06 июня 2019

Вы также должны добавить зависимость к spring-cloud-starter-kubernetes-ribbon.

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-kubernetes-ribbon</artifactId>
            <version>1.0.1.RELEASE</version>
        </dependency>

Тогда он будет работать без каких-либо переписываний, просто с spring.cloud.gateway.discovery.locator.enabled: true

...