Spring Cloud Gateway с локатором обнаружения Eureka — 404

Я настраиваю приложение на основе микросервисов, используя Spring Cloud Gateway с клиентом обнаружения Eureka.

Я настроил серверное приложение Eureka, приложение Gateway и обычный сервис.

Я установил для spring.cloud.gateway.discovery.locator.enabled и spring.cloud.gateway.discovery.locator.lower-case-service-id значение true в файле Gateway application.yml.

Все три приложения запускаются правильно, однако, когда я пытаюсь получить доступ к микросервису через шлюз, я получаю ошибку 404, отправляя запрос GET на localhost:8080/event.

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

Что мне не хватает?

Приложение Eureka Server.yml

spring:
    application:
        name: registry
server:
    port: 8081

eureka:
    client:
        register-with-eureka: false
        fetch-registry: false
        service-url:
            defaultZone: http://localhost:${server.port}/eureka/
    instance:
        hostname: localhost
        prefer-ip-address: true

Приложение Spring Cloud Gateway.yml

spring:
    application:
        name: api-gateway
    cloud:
        gateway:
            discovery:
                locator:
                    enabled: true
                    lower-case-service-id: true
    main:
        web-application-type: reactive

server:
    port: 8080

eureka:
    client:
        service-url:
            defaultZone: http://localhost:8081/eureka/
        fetch-registry: true
        register-with-eureka: true
    instance:
        hostname: localhost
        prefer-ip-address: true

management:
  endpoint:
    gateway:
      enabled: true
  endpoints:
    web:
      exposure:
        include:
        - "*"

Сервисное приложение.yml

server:
  port: 8082

spring:
  application:
    name: event

eureka:
    client:
        service-url:
            defaultZone: http://localhost:8081/eureka/
        fetch-registry: true
        register-with-eureka: true
    instance:
        hostname: localhost
        prefer-ip-address: true

Я включил необходимые аннотации как в серверное приложение Eureka, так и в классы приложений службы Gateway и Event. Я получаю следующий ответ при запросе http://localhost:8080/actuator/gateway/routes:

[{"predicate":"Paths: [/api-gateway/**], match trailing slash: true","metadata":{"jmx.port":"55939","management.port":"8080"},"route_id":"ReactiveCompositeDiscoveryClient_API-GATEWAY","filters":["[[RewritePath /api-gateway/?(?<remaining>.*) = '/${remaining}'], order = 1]"],"uri":"lb://API-GATEWAY","order":0},{"predicate":"Paths: [/event/**], match trailing slash: true","metadata":{"jmx.port":"55880","management.port":"8082"},"route_id":"ReactiveCompositeDiscoveryClient_EVENT","filters":["[[RewritePath /event/?(?<remaining>.*) = '/${remaining}'], order = 1]"],"uri":"lb://EVENT","order":0}]

Контроллер событий

package example.event.endpoint.controller;

import static org.springframework.http.HttpStatus.OK;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import example.event.endpoint.service.EventService;
import example.core.model.Event;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

@RestController
@RequestMapping("/v1/event")
@Slf4j
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class EventController {
    private final EventService eventService;

    @GetMapping
    public ResponseEntity<Iterable<Event>> listAll(Pageable pageable) {
        log.info("Retrieving all events");
        return new ResponseEntity<>(eventService.list(pageable), OK);
    }
}

Какой путь вы пытаетесь получить доступ? На основе маршрутов служба событий должна быть доступна через шлюз с чем-то вроде - localhost: 8080/event/someurl Это перенаправит /someurl в службу событий при условии, что служба имеет конечную точку someurl

Dhananjay 19.04.2023 00:30

Просто localhost:8080/event . EventController имеет только одно сопоставление с пустым путем

rcirne 19.04.2023 00:34

Я отредактировал вопрос, добавив класс контроллера и URL-адрес, который я пытаюсь нажать.

rcirne 19.04.2023 00:43

Если localhost:8082/v1/event возвращает желаемый результат, я ожидаю того же от шлюза localhost:8080/event/v1/event для маршрутизации на основе вашей конфигурации.

Dhananjay 19.04.2023 23:54

@Dhananjay, твой ответ разгадал загадку. localhost:8080/event/v1/event дал ожидаемый ответ. Поскольку цель состоит в том, чтобы использовать шлюз для доступа ко всем службам, я удалю пути из классов контроллера, чтобы можно было получить доступ к службе событий, как localhost:8080/v1/event. Спасибо за отзыв.

rcirne 23.04.2023 23:07

Круто, я опубликую это как ответ

Dhananjay 24.04.2023 00:32
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
6
208
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Если localhost:8082/v1/event возвращает желаемый результат, я ожидаю того же от шлюза localhost:8080/event/v1/event для маршрутизации на основе вашей конфигурации.

Первый /event — это имя вашей службы, используемое облачным шлюзом Spring для определения того, какую службу ему нужно направить. По умолчанию имя службы обрезается, а путь /v1/event вместе с любой другой частью запроса направляется в вашу службу событий.

Другие вопросы по теме