我正在尝试建立一个简单的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
每次我使用重新发送消息(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
我也使用FilterFactory
和RouteLocator
Bean进行了尝试,但是它们都表现出相同的行为。
我一直在搜寻所有文档,但是我发现的所有内容似乎都表明这应该起作用。有人可以帮我吗?
答案 0 :(得分:0)
也许像尤里卡这样的发现中心将解决您的问题。
此外,此期的帖子可以为您提供很多帮助:https://github.com/spring-cloud/spring-cloud-gateway/issues/383
答案 1 :(得分:0)
您要做的是定义到后端服务的路由。在您当前的设置中,您正在创建一条通往端口8081上运行的服务的路由,据我所知,在您的描述中,该端口上没有运行服务。
因此,换句话说,如果您有两个相同的服务,一个在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
然后卷曲您的服务(假设您的网关在端口8080上运行):
curl http://localhost:8080/restmessage -H "route: service-one"
现在您应该看到您的请求被路由到在端口2000上运行的服务。
希望这会有所帮助!