Spring Cloud Gateway与NetflixEureka 之间的服务器端负载平衡行为异常

h43kikqp  于 2022-12-28  发布在  Spring
关注(0)|答案(1)|浏览(112)

I'm trying to implement server side LB with SpringCloudGateway and Eureka. I have microservices ABC (abc.test.com) and gateway (gateway.test.com) register in eureka (eureka.test.com) by hostname.
If I send request from postman on local machine to gateway.test.com/test/owned then I see in postman console 2 requests instead of 1. Even though I don't have a dependency: spring-cloud-starter-loadbalancer It is look like spring doing client side load balancing instead of server side. Also, not all headers are probably passed through this redirect (like Authorization, which caused final 401).
网关路由:

- id: ABC
  uri: lb://ABC
  predicates:
    - Path=/test/**

第一:

GET / HTTP/1.1
Authorization: Bearer ****
User-Agent: PostmanRuntime/7.28.2
Accept: */*
Host: gateway.test.com
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
 
HTTP/1.1 301
location: https://abc.test.com/test/owned
date: Mon, 26 Dec 2022 13:00:54 GMT
server: ******
content-length: 0
cache-control: no-cache, no-store, max-age=0, must-revalidate
pragma: no-cache
expires: 0
x-content-type-options: nosniff
x-frame-options: DENY
x-xss-protection: 1 ; mode=block
referrer-policy: no-referrer
x-envoy-upstream-service-time: 12

第二:

GET /test/owned HTTP/1.1
User-Agent: PostmanRuntime/7.28.2
Accept: */*
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
Referer: https://gateway.test.com/test/owned
Host: abc.test.com
Cookie: JSESSIONID=720********
 
HTTP/1.1 401 Unauthorized
vary: Origin,Access-Control-Request-Method,Access-Control-Request-Headers
www-authenticate: Bearer
x-content-type-options: nosniff
x-xss-protection: 1; mode=block
cache-control: no-cache, no-store, max-age=0, must-revalidate
pragma: no-cache
expires: 0
x-frame-options: DENY
content-length: 0
date: Mon, 26 Dec 2022 13:00:59 GMT
x-envoy-upstream-service-time: 5
server: *******

POM:

<?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>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-parent</artifactId>
      <version>2.7.4</version>
      <relativePath/> <!-- lookup parent from repository -->
   </parent>
   <groupId>com.test</groupId>
   <artifactId>testGateway</artifactId>
   <version>0.0.1-SNAPSHOT</version>
   <properties>
      <java.version>18</java.version>
      <spring-cloud.version>2021.0.1</spring-cloud.version>
   </properties>
   <dependencies>
      <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-oauth2-client</artifactId>
      </dependency>
      <dependency>
         <groupId>org.springframework.cloud</groupId>
         <artifactId>spring-cloud-starter-gateway</artifactId>
      </dependency>
      <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
         <scope>compile</scope>
      </dependency>
      <dependency>
         <groupId>org.springframework.cloud</groupId>
         <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
      </dependency>
   </dependencies>

   <dependencyManagement>
      <dependencies>
         <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>${spring-cloud.version}</version>
            <type>pom</type>
            <scope>import</scope>
         </dependency>
      </dependencies>
   </dependencyManagement>

   <build>
      <plugins>
         <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
         </plugin>
      </plugins>
   </build>

</project>

当我在localhost中运行服务时-比如说网关8080,abc 8081,eureka 8082,然后通过网关发送请求,它似乎在工作(只有1个请求在 Postman 控制台中,没有客户端可见的重定向)。
当我将网关路由从lb://ABC直接更改为https://abc.test.com时,它似乎工作正常-但此变通方案无法接受,因为它会取消微服务责任。
我想要实现的是完全的服务器端负载平衡-〉每个通过网关发出请求的客户端都不应该知道网关服务调用了什么/在哪里。

k5ifujac

k5ifujac1#

对于未来的求职者:此行为是由于http -〉https重定向。我的服务在Eureka 中注册为http -〉spring云网关负载平衡器从eureka获取http地址并执行请求-〉然后PAAS(我使用的是www.example.com)执行重定向railway.app到https域(这会导致丢失标头并强制在客户端执行)。
修正:在Eureka 中正确注册微服务(前四个是最重要的):

eureka.instance.nonSecurePort=80
eureka.instance.nonSecurePortEnabled=false
eureka.instance.securePortEnabled=true
eureka.instance.securePort=443
eureka.instance.preferIpAddress=false
eureka.instance.hostname=abc.test.com
eureka.instance.statusPageUrl='https://abc.test.com/info'
eureka.instance.healthCheckUrl='https://abc.test.com/health'
eureka.instance.homePageUrl='https://abc.test.com/'

相关问题