public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
Flux<DataBuffer> body = exchange.getRequest().getBody();
//Return different according to body content...
if (condition) {
return chain.filter(exchange);
} else {
return Mono.empty();
}
}
Run Code Online (Sandbox Code Playgroud)
用spring 5在spring-webflux中如何获取请求的body做一些自定义判断?
我在 AWS 负载均衡器后面运行 spring cloud gateway(我理解它是在 Spring Webflux 上构建的),并且我收到间歇性 502 错误。经过调查,问题似乎与负载均衡器和我的节点之间的连接超时有关。从一些调查来看,底层 netty 服务器的默认超时时间为 10 秒。我使用以下命令确定了这一点...
time nc -vv 10.10.xx.xxx 5100
Connection to 10.10.xx.xxx 5100 port [tcp/*] succeeded!
real 0m10.009s
user 0m0.000s
sys 0m0.000s
Run Code Online (Sandbox Code Playgroud)
虽然我可以将负载均衡器上的 idleTimeout 设置在 10 秒以内,但这感觉非常低效。如果可能,我想将其保持在 30 秒以上。相反,我想增加 netty 服务器上的连接超时。我试图在我的 application.yml 中设置 server.connection-timeout 属性...
server:
connection-timeout: 75000
Run Code Online (Sandbox Code Playgroud)
也通过指定秒...
server:
connection-timeout: 75s
Run Code Online (Sandbox Code Playgroud)
但是当我运行 time 命令以查看我的连接持续多长时间时,超时没有变化,它仍然以 10 秒结束......
time nc -vv 10.10.xx.xxx 5100
Connection to 10.10.xx.xxx 5100 port [tcp/*] succeeded!
real 0m10.009s
user 0m0.000s
sys 0m0.000s
Run Code Online (Sandbox Code Playgroud)
我在这里缺少什么?
我正在使用Spring 5,Netty和Spring webflux开发API网关。有时我希望该请求由网关停止,但我也想读取请求的主体以将其记录下来,例如,将错误返回给客户端。
我尝试通过订阅主体在WebFilter中执行此操作。
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
if (enabled) {
logger.debug("gateway is enabled. The Request is routed.");
return chain.filter(exchange);
} else {
logger.debug("gateway is disabled. A 404 error is returned.");
exchange.getRequest().getBody().subscribe();
exchange.getResponse().setStatusCode(HttpStatus.NOT_FOUND);
return exchange.getResponse().writeWith(Mono.just(exchange.getResponse().bufferFactory().allocateBuffer(0)));
}
}
Run Code Online (Sandbox Code Playgroud)
当我这样做时,当身体的内容很小时,它就会起作用。但是,当我有一个很大的跳闸时,只读取磁通量的第一个元素,因此无法获得整个人体。任何想法如何做到这一点?
假设我的用户订阅了一个计划。那么是否可以使用 Spring Cloud Gateway 根据订阅计划对用户请求进行速率限制?鉴于有 Silver 和 Gold 计划,是否会让 Silver 订阅具有 5/10 的补货率/突发容量和 50/100 的 Gold 订阅?
我天真地想到将 RedisRateLimiter 的新实例(见下文,我构造了一个具有 5/10 设置的新实例)传递给过滤器,但我需要以某种方式从请求中获取有关用户的信息,以便能够找出是否这是银和金计划。
@Bean
public RouteLocator myRoutes(RouteLocatorBuilder builder) {
return builder.routes()
.route(p -> p
.path("/get")
.filters(f ->
f.requestRateLimiter(r -> {
r.setRateLimiter(new RedisRateLimiter(5, 10))
})
.uri("http://httpbin.org:80"))
.build();
}
Run Code Online (Sandbox Code Playgroud)
我是否试图通过 Spring Cloud Gateway 实现一些甚至可能实现的目标?如果有的话,你会推荐哪些其他产品来检查这个目的?
谢谢!
Spring Cloud Greenwich 进入spring-cloud-netflix-zuul维护模式,因此我尝试从 Zuul 迁移到 Spring Cloud Gateway。
使用 Zuul 我有一条类似的路线
zuul:
routes:
masterplan_match:
path: /**/masterplans/**
serviceId: api-masterplan
Run Code Online (Sandbox Code Playgroud)
我在那里所做的基本上是忽略masterplan接收路径中之前或之后的所有内容并重定向到api-masterplan. 例如, 和/some/path/to/masterplans都/masterplans使用相同的 api(原因是masterplans它们是一个更大实体的子资源,负责创建新的masterplans,但随后masterplans可以被视为完整的资源,用于设置GET详细信息、更新、删除等目的)。
我可以将此配置映射到 Spring Cloud Gateway 吗?查看predicates,可行的似乎是path predicate,但看起来所有匹配器都适用于单个路径元素(除了WildcardTheRestPathElement,但它只能用作最后一个元素 - 我认为),即:我需要写就像是
spring
cloud:
gateway:
routes:
- id: masterplan_match
uri: lb://api-masterplan # Coming from discovery client
predicates:
- Path=/some/path/to/masterplans/**, /masterplans/**
Run Code Online (Sandbox Code Playgroud)
我是否遗漏了一些东西,两条路径可以浓缩为一条吗?
SESSION我在调用资源服务器后遇到 Spring Cloud Gateway 重置 cookie 的问题。
我有一个 Angular 应用程序、一个 Spring Cloud Gateway 应用程序、一个外部授权服务器和一个我自己的资源服务器。
Angular 应用程序首先通过 Spring Cloud Gateway 应用程序进行授权(该应用程序使用 OAuth2 将这项工作委托给外部授权服务器)并接收 cookie SESSION。此时,用户已通过身份验证,并且Authentication对象在 Spring Cloud Gateway 应用程序中可用。
接下来,Angular应用程序调用Spring Cloud Gateway应用程序的端点,该端点实际上将调用转发到资源服务器(并在调用中包含承载令牌,因此调用工作正常),资源服务器返回一些结果,成功通过 Spring Cloud Gateway 应用程序发送回 Angular 应用程序。但除了成功响应之外,Spring Cloud Gateway 应用程序还会发送以下标头:
set-cookie: SESSION=; Max-Age=0; Expires=Sat, 17 Aug 2019 20:39:44 GMT; Path=/; HTTPOnly
这会杀死客户端的 cookie 并使后续调用变得不可能,即使该Authentication对象仍然存在并且会话看起来也很好。
有谁知道这种行为的原因是什么?
cookies session session-cookies spring-cloud spring-cloud-gateway
在 RequestRateLimiter 的 Redis 实现中,我们必须指定两个属性redis-rate-limiter.replenishRate并redis-rate-limiter.burstCapacity作为 RequestRateLimiter 过滤器的参数。
根据文档,
这
redis-rate-limiter.replenishRate是您希望用户每秒允许执行多少请求,而没有任何丢弃的请求。这是令牌桶填充的速率。的
redis-rate-limiter.burstCapacity是允许用户在一个单一的第二做请求的最大数目。这是令牌桶可以容纳的令牌数量。将此值设置为零将阻止所有请求。
从我看来,replenishRate是发出请求的速率,以及可以发出burstCapacity的最大请求数(均在一秒内)。但是,在实际场景中,我似乎无法理解两者之间的区别。
我的网关会将流量重定向到许多不同的服务(在不同的域名下)。如何测试网关的配置?只需一项服务,我就可以设置模拟服务器(如 httpbin)并测试响应。对于多个服务,我宁愿避免启动整个 docker 网络或更改 locak dns 别名。spring 是否提供了任何轻量级的测试网关的方法?
我在 Spring Boot 微服务中为其他微服务提供了一个 api,并且我想在这个微服务前面放置一个 spring-cloud-gateway。
我已经查看了著名的 spring 文档(https://spring.io/guides/gs/gateway/),但据我了解,它要求我在单独的项目中启动云网关。但我想在我的微服务中运行 RouteLocator bean。不是在单独的项目中,而是在同一个项目中。
当我在同一个项目中使用它时,我收到这样的警告
“在类路径中发现 Spring MVC,目前与 Spring Cloud Gateway 不兼容。请删除 spring-boot-starter-web 依赖项。”
后来,正如他在警告中所说,我删除了 spring-boot-starter-web 依赖项,甚至进入了其他项目,将它们从那里排除,如下所示
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web-services</artifactId>
<exclusions>
<exclusion>
<artifactId>spring-boot-starter-web</artifactId>
<groupId>org.springframework.boot</groupId>
</exclusion>
</exclusions>
</dependency>
Run Code Online (Sandbox Code Playgroud)
这次我逻辑上得到了错误
“org.springframework.beans.factory.BeanDefinitionStoreException:无法处理配置类 [com.company Operations.Service OperationsApplication] 的导入候选者;嵌套异常为 org.spring..core.NestedIOException:无法加载类 [javax.servlet. Filter];嵌套异常是java.lang.ClassNotFoundException: javax.servlet.Filter”。
我们从应该提供Web api服务的项目中删除了核心库:D
如果不可能在同一个项目中使用它,那么众所周知的网关实践应该如何,我应该在每个 api 微服务前面放置一个网关,还是应该在我的项目中拥有一个由多个 api 微服务组成的网关一个微服务?
spring spring-boot microservices api-gateway spring-cloud-gateway
我正在开发一个分布式应用程序项目,其中需要根据在 api 网关上使用服务的客户端进行速率限制和身份验证。我想知道设计网关的最佳解决方案。
我应该使用 Spring Cloud gateway 还是 Spring Cloud function/AWS Lambda 来创建网关服务?
microservices aws-lambda aws-api-gateway spring-cloud-gateway spring-cloud-function
spring ×3
spring-boot ×2
spring-cloud ×2
api-gateway ×1
aws-lambda ×1
cookies ×1
java ×1
redis ×1
session ×1
spring-test ×1
testing ×1