You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Cloud Gateway集成Eureka服务发现出现404问题求助

问题

我正在搭建基于Spring Cloud Gateway与Eureka发现客户端的微服务应用,已完成Eureka服务端、Gateway网关以及event业务服务的配置。网关的application.yml中已开启spring.cloud.gateway.discovery.locator.enabled并设置spring.cloud.gateway.discovery.locator.lower-case-service-id为true。三个应用均可正常启动,但向localhost:8080/event发送GET请求通过网关访问微服务时,出现404错误。已配置Actuator查看网关暴露的端点,确认存在该服务的路由条目。请问我遗漏了什么配置?

相关配置

Eureka Server application.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 application.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:
        - "*"

Event Service application.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

网关路由端点响应(Actuator)

[{"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}]

EventController代码

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

问题分析与解决方案

核心原因

网关自动生成的路由规则和业务服务的接口路径不匹配:

  • 网关通过服务发现生成的event服务路由是/event/**,并附带默认路径重写规则:将/event/?(?<remaining>.*)重写为/${remaining}。当你请求localhost:8080/event时,网关会将路径转发为/到event服务。
  • 但你的EventController的请求映射是@RequestMapping("/v1/event"),@GetMapping对应的接口路径是/v1/event,服务端不存在/路径的接口,因此返回404。

解决方案(任选其一即可)

方案1:使用正确的请求路径

直接访问匹配接口的路径:localhost:8080/event/v1/event。此时网关会将路径重写为/v1/event,正好匹配Controller的接口。

方案2:修改业务服务的Controller路径

将EventController的@RequestMapping改为根路径,让网关转发的/路径能匹配到接口:

@RestController
@RequestMapping("/") // 修改为根路径
@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);
    }
}

方案3:自定义网关路由重写规则

如果希望保持Controller的/v1/event路径,同时用localhost:8080/event就能访问,可以在网关配置中添加自定义路由,覆盖自动生成的规则:

spring:
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true
          lower-case-service-id: true
      routes:
        - id: event-service-route
          uri: lb://event
          predicates:
            - Path=/event/**
          filters:
            - RewritePath=/event/?(?<remaining>.*), /v1/event/${remaining}

配置后,请求localhost:8080/event会被网关重写为/v1/event,转发到event服务即可匹配接口。


内容的提问来源于stack exchange,提问作者rcirne

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 09:07:13