Spring Boot 2.5.6 API 网关 + Eureka Server = 404
Posted
技术标签:
【中文标题】Spring Boot 2.5.6 API 网关 + Eureka Server = 404【英文标题】:Spring Boot 2.5.6 API Gateway + Eureka Server = 404 【发布时间】:2021-12-24 10:14:09 【问题描述】:我正在使用 Spring API 网关、Eureka Server 和 WebFlux 创建一个项目。
借助 spring 文档,我启动了 3 项服务:
localhost:3761 - 尤里卡 localhost:4001 - 服务 localhost:8080 - Api 网关Eureka 列出了 2 个服务(网关和我的服务) 我的服务在浏览器上运行良好 我的网关只有在我的路由 uri 是 localhost 并且我真的不知道如何解决它时才会响应。
网关 application.yml - 不工作
server:
port: 8080
eureka:
instance:
hostname: localhost
non-secure-port: 8761
prefer-ip-address: true
client:
service-url:
defaultZone: http://$eureka.instance.hostname:$eureka.instance.non-secure-port/eureka/
spring:
application:
name: GATEWAY-SERVER
cloud:
gateway:
discovery:
locator:
enabled: true
routes:
- id: my-service-route
uri: lb://MY-SERVICE
predicates:
- Path=/api/my/service/**
网关 application.yml - 工作
server:
port: 8080
eureka:
instance:
hostname: localhost
non-secure-port: 8761
prefer-ip-address: true
client:
service-url:
defaultZone: http://$eureka.instance.hostname:$eureka.instance.non-secure-port/eureka/
spring:
application:
name: GATEWAY-SERVER
cloud:
gateway:
discovery:
locator:
enabled: true
routes:
- id: my-service-route
uri: http://localhost:4001
predicates:
- Path=/api/my/service/**
请注意,唯一的区别是 URI 不是在寻找服务名称。
【问题讨论】:
请显示您的依赖关系。顺便说一句,你的尤里卡实例设置是错误的。这些是要注册的实例,而不是 eureka 服务器。 【参考方案1】:@spencergibb
这里是依赖项:
父级(物料清单)
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.6</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<groupId>com.site</groupId>
<artifactId>parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<name>Parent POM</name>
<properties>
<java.version>11</java.version>
<encoding>UTF-8</encoding>
<spring-cloud.version>2020.0.4</spring-cloud.version>
<spring-native.version>0.10.3</spring-native.version>
<feign.reactor.version>3.1.1</feign.reactor.version>
<maven.release.version>3.0.0-M4</maven.release.version>
<lombok.mapstruct.binding.version>0.2.0</lombok.mapstruct.binding.version>
<org.mapstruct.version>1.4.2.Final</org.mapstruct.version>
<org.springdoc.version>1.5.11</org.springdoc.version>
<project.build.sourceEncoding>$encoding</project.build.sourceEncoding>
<project.reporting.outputEncoding>$encoding</project.reporting.outputEncoding>
<project.resources.sourceEncoding>$encoding</project.resources.sourceEncoding>
<archetype.encoding>$encoding</archetype.encoding>
<maven.compiler.source>$java.version</maven.compiler.source>
<maven.compiler.target>$java.version</maven.compiler.target>
</properties>
<dependencyManagement>
<dependencies>
<!-- Develop -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok-mapstruct-binding</artifactId>
<version>$lombok.mapstruct.binding.version</version>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
<version>$org.mapstruct.version</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>$spring-cloud.version</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>com.playtika.reactivefeign</groupId>
<artifactId>feign-reactor-spring-cloud-starter</artifactId>
<version>3.1.1</version>
<type>pom</type>
</dependency>
<!-- Documentation -->
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-webflux-ui</artifactId>
<version>$org.springdoc.version</version>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<!-- DevOps -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
</dependencies>
<build>
<resources>
<resource>
<directory>$basedir/src/main/resources</directory>
<filtering>true</filtering>
<includes>
<include>**/application*.yml</include>
</includes>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<layers>
<enabled>true</enabled>
<includeLayerTools>true</includeLayerTools>
</layers>
<image>
<name>$project.artifactId:$project.version</name>
</image>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>$java.version</source> <!-- depending on your project -->
<target>$java.version</target> <!-- depending on your project -->
<annotationProcessorPaths>
<path>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>$org.mapstruct.version</version>
</path>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>$lombok.version</version>
</path>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok-mapstruct-binding</artifactId>
<version>$lombok.mapstruct.binding.version</version>
</path>
</annotationProcessorPaths>
<compilerArgs>
<compilerArg>-Amapstruct.defaultComponentModel=spring</compilerArg>
</compilerArgs>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-release-plugin</artifactId>
<version>$maven.release.version</version>
<configuration>
<allowTimestampedSnapshots>true</allowTimestampedSnapshots>
<tagNameFormat>@project.version</tagNameFormat>
</configuration>
</plugin>
</plugins>
</build>
</project>
尤里卡
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.site</groupId>
<artifactId>parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<artifactId>eureka</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>eureka-server</name>
<description>eureka-server</description>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>
网关
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.site</groupId>
<artifactId>parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<artifactId>gateway-server</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>gateway-server</name>
<description>gateway-server</description>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>
我的服务
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.site</groupId>
<artifactId>parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<artifactId>service</artifactId>
<version>0.1.1-SNAPSHOT</version>
<name>my-service</name>
<description>my-service</description>
<dependencies>
<!-- Web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
<groupId>com.playtika.reactivefeign</groupId>
<artifactId>feign-reactor-spring-cloud-starter</artifactId>
<type>pom</type>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<!-- Database -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb-reactive</artifactId>
</dependency>
<!-- Developer -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok-mapstruct-binding</artifactId>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
</dependency>
<!-- Documentation -->
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-webflux-ui</artifactId>
</dependency>
<!-- Validation -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<!-- Tests -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>de.flapdoodle.embed</groupId>
<artifactId>de.flapdoodle.embed.mongo</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.projectreactor</groupId>
<artifactId>reactor-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>
这里还有服务的 yaml。我想我在网关或尤里卡做错了什么。
尤里卡
server:
port: 8761
spring:
application:
name: EUREKA-SERVER
eureka:
instance:
hostname: localhost
prefer-ip-address: true
client:
register-with-eureka: false
fetch-registry: false
use-dns-for-fetching-service-urls: false
service-url:
defaultZone: http://$eureka.instance.hostname:$server.port/eureka/
logging:
level:
com:
netflix:
eureka: off
discovery: off
网关
server:
port: 8080
eureka:
instance:
hostname: localhost
non-secure-port: 8761
prefer-ip-address: true
client:
service-url:
defaultZone: http://$eureka.instance.hostname:$eureka.instance.non-secure-port/eureka/
spring:
application:
name: GATEWAY-SERVER
cloud:
gateway:
discovery:
locator:
enabled: true
routes:
- id: my-service-route
uri: lb://MY-SERVICE
predicates:
- Path=/api/v1/**
我的服务
server:
port: 4001
spring:
application:
name: MY-SERVICE
data:
mongodb:
uri: mongodb://localhost:27017/service
eureka:
instance:
hostname: localhost
non-secure-port: 8761
prefer-ip-address: true
client:
service-url:
defaultZone: http://$eureka.instance.hostname:$eureka.instance.non-secure-port/eureka/
springdoc:
api-docs:
enabled: true
path: /api-docs
swagger-ui:
path: /index.html
【讨论】:
【参考方案2】:在 GATEWAY-SERVICE 上做一些测试。我注意到一些奇怪的事情:
我已经列出了网关上的服务:
网关服务器应用程序
@EnableEurekaClient
@EnableDiscoveryClient
@SpringBootApplication
public class GatewayServerApplication implements CommandLineRunner
@Autowired
private DiscoveryClient discoveryClient;
public static void main(String[] args)
SpringApplication.run(GatewayServerApplication.class, args);
@Override
public void run(String... args) throws Exception
System.out.println("LIST INSTANCES");
List<String> list = discoveryClient.getServices();
list.forEach(item ->
System.out.println("Service: " + item);
List<ServiceInstance> instances = this.discoveryClient.getInstances(item);
instances.forEach(instance ->
System.out.println("URI: " + instance.getUri());
System.out.println("HOST: " + instance.getHost());
System.out.println("PORT: " + instance.getPort());
System.out.println("INSTANCE ID: " + instance.getInstanceId());
System.out.println("SERVICE ID: " + instance.getServiceId());
);
);
2021-11-13 09:24:35.633 INFO 1547 --- [ main] b.c.f.gateway.GatewayServerApplication : Started GatewayServerApplication in 3.576 seconds (JVM running for 4.419)
LIST INSTANCES
Service: my-service
URI: http://192.168.0.103:8761
HOST: 192.168.0.103
PORT: 8761
INSTANCE ID: mbp-of-rafael:MY-SERVICE:4001
SERVICE ID: MY-SERVICE
URI 和 Port 定义为 8761(eureka 服务器端口)。但我认为应该是 4001(我的服务端口)。我错了吗?!
【讨论】:
以上是关于Spring Boot 2.5.6 API 网关 + Eureka Server = 404的主要内容,如果未能解决你的问题,请参考以下文章
在 Spring Boot 应用程序中使用 API 网关时,HATEOAS 路径无效
如何在 Spring Boot 应用程序中从 Api 网关(Zuul)调用外部服务(非 MSA)
Spring Boot + Spring Cloud 构建微服务系统:API服务网关(Zuul)
Spring Boot API Gateway 无法解析名称