java - Spring Cloud Gateway:不路由请求,最终遇到413请求实体太大
问题描述
我正在尝试设置一个简单的 Spring Cloud Gateway 示例。
我有 2 个在本地运行的 docker 容器,它们会在命中以下端点时AAA
做出响应ZZZ
http://localhost:2000/restmessage
http://localhost:2001/restmessage
我正在尝试制作一个简单的网关,它将路由到这些服务之一。最终会有实际的逻辑来做出这个决定,但现在我只想看到一些工作并且已经硬编码到第一个实例。
这是我的GlobalFilter
@Component
public class MacFilter implements GlobalFilter {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerWebExchange modifiedExchange = exchange.mutate()
.request(rq -> rq.uri(
UriComponentsBuilder.fromUri(exchange.getRequest().getURI())
.host("localhost")
.port(2000)
.build()
.toUri()
))
.build();
// ServerWebExchangeUtils.setAlreadyRouted(modifiedExchange);
return chain.filter(modifiedExchange);
}
}
和属性
spring.cloud.gateway.routes[0].id=routezero
spring.cloud.gateway.routes[0].uri=http://localhost:8081
spring.cloud.gateway.routes[0].predicates[0]=Path=/restmessage
每次我使用 restmessage ( http://localhost:8080/restmessage
) 访问网关时,此过滤器都会运行。但是如果被注释的setAlreadyRouted
方法被注释掉了,它会命中数百次。最终 curl 命令失败并显示413 REQUEST ENTITY TOO LARGE
. 通过查看 docker 服务的日志,我可以看出它们从未被击中。
$ curl localhost:8080/restmessage -i
HTTP/1.1 413 Request Entity Too Large
content-length: 0
如果我取消注释该setAlreadyRouted
方法,它不再调用数百次并且请求立即返回,但响应为空,并且不再调用 docker 容器。
$ curl localhost:8081/restmessage -i
HTTP/1.1 200 OK
content-length: 0
我也用 aFilterFactory
和RouteLocator
Bean 尝试过这个,但它们都表现出相同的行为。
我一直在搜寻所有文档,但我能找到的一切似乎都表明这应该可以工作。有人可以帮帮我吗?
解决方案
您要做的是定义后端服务的路由。在您当前的设置中,您正在创建到在端口 8081 上运行的服务的路由,据我在您的描述中所读到的,该端口上没有运行任何服务。
因此,换句话说,如果您有 2 个相同的服务,一个在 localhost:2000 上运行,另一个在 localhost:2001 上运行,您将需要 2 个路由,一个用于一个服务,一个用于另一个。当然,由于服务公开了相同的端点,您将需要一些东西来区分您要路由到哪个服务。例如,这可以通过在您的请求中添加标头来完成。
示例设置可能是这样的。在您的 application.yaml 中(所以不在您的 application.properties 中,也可以在属性文件中完成,但 yaml 更适合此目的),输入如下内容:
spring:
application:
name: gateway-service
cloud:
gateway:
routes:
- id: 2000service
uri: http://localhost:2000
predicates:
- Path=/restmessage
- Header=route, service-one
- id: 2001service
uri: https://localhost:2001
predicates:
- Path=/restmessage
- Header=route, service-two
您可以摆脱 GlobalFilter 和您定义的属性。现在启动您的应用程序:
mvn spring-boot:run
然后对您的服务进行 curl(假设您的网关在端口 8080 上运行):
curl http://localhost:8080/restmessage -H "route: service-one"
您现在应该看到您的请求被路由到在端口 2000 上运行的服务。
希望这可以帮助!
推荐阅读
- c# - 使用存储文件夹播放 .mp3 UWP
- https - HTTPS 负载均衡器,用于在 Google Kubernetes 上公开工作负载
- java - NoSuchMethodError:org.apache.poi.ss.usermodel.Font.getIndexAsInt()
- matrix - sympy 矩阵元素圆?
- sass - 我可以在 sass 中创建我的类名变量吗?
- frisby.js - Frisby.js 循环运行测试
- excel - 比较 PSCustomObjects 的所有属性(Excel 工作表数据)
- html - 不透明度属性在 css 中没有给出预期的结果
- angular - Highcharts Sunburst 在水平变化时改变颜色
- c# - MigraDoc:如何在奇数页的部分之后添加空白页?