您的位置:首页 > 文旅 > 旅游 > 浙江有限公司网站_郑州公司网页_网络推广学校_搜索引擎快速排名推广

浙江有限公司网站_郑州公司网页_网络推广学校_搜索引擎快速排名推广

2025/2/12 23:45:23 来源:https://blog.csdn.net/qq_47741012/article/details/145554483  浏览:    关键词:浙江有限公司网站_郑州公司网页_网络推广学校_搜索引擎快速排名推广
浙江有限公司网站_郑州公司网页_网络推广学校_搜索引擎快速排名推广

在构建微服务架构时,API网关是一个关键组件,它负责路由、负载均衡、安全验证等多种功能。Spring Cloud Gateway提供了强大的扩展能力,允许开发者通过自定义过滤器来增强其功能。本文将详细介绍如何实现一个自定义过滤器,用于记录响应时间超过指定阈值的请求,并展示如何支持微服务的自定义配置。

首先,我们需要创建一个自定义的Gateway过滤器工厂类。这个类将负责缓存请求体,并在请求处理完成后检查响应时间是否超过了设定的阈值。如果超过了,则记录一条警告日志。

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.core.io.buffer.DataBufferUtils;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;import java.nio.charset.StandardCharsets;
import java.util.Map;@Slf4j
@Component
public class SlowLoggingGatewayFilterFactory extends AbstractGatewayFilterFactory<SlowLoggingGatewayFilterFactory.Config> {public SlowLoggingGatewayFilterFactory() {super(SlowLoggingGatewayFilterFactory.Config.class);log.info("Loaded GatewayFilterFactory [RequestTimeoutLog]");}@Overridepublic GatewayFilter apply(SlowLoggingGatewayFilterFactory.Config config) {return (exchange, chain) -> {long startTime = System.currentTimeMillis();// 缓存请求体,避免因请求体被消费导致读取不到数据// 使用DataBufferUtils.join将请求体的所有数据缓冲区合并为一个DataBufferreturn DataBufferUtils.join(exchange.getRequest().getBody()).flatMap(dataBuffer -> {// 将合并后的DataBuffer转换为字节数组,并将其转换为字符串byte[] bytes = new byte[dataBuffer.readableByteCount()];dataBuffer.read(bytes);DataBufferUtils.release(dataBuffer);// 释放资源String cachedBody = new String(bytes, StandardCharsets.UTF_8);// 将缓存的请求体存储在ServerWebExchange的属性中,键名为"cachedRequestBody"exchange.getAttributes().put("cachedRequestBody", cachedBody);return chain.filter(exchange);// 继续处理请求链}).doOnSuccessOrError((response, ex) -> {// 计算耗时并记录long duration = System.currentTimeMillis() - startTime;if (config.isEnabled() && duration > config.getTimeout()) {ServerHttpRequest request = exchange.getRequest();String cachedBody = exchange.getAttributeOrDefault("cachedRequestBody", "");Map<String, String> queryParams = request.getQueryParams().toSingleValueMap();log.warn("Slow Request Detected: Method={}, Path={}, QueryParams={}, Body={}, Duration={}ms",request.getMethodValue(), request.getPath(), queryParams, cachedBody, duration);}});};}@Data@AllArgsConstructor@NoArgsConstructorpublic static class Config {// 控制是否超时日志打印private boolean enabled;// 超时阈值,单位毫秒,默认1000毫秒private long timeout = 1000L;}
}

原理很简单,使用 DataBufferUtils.join 将请求体的所有数据缓冲区合并为一个 DataBuffer,然后将其转换为字符串并缓存到 exchange 的属性中。调用 chain.filter(exchange) 继续处理请求链,确保请求可以正常传递到下游微服务。在请求处理完成后(无论成功还是失败),计算请求处理的总耗时。如果配置启用了日志记录并且耗时超过了设定的阈值,则记录一条警告日志。

接下来,需要在 application.yml 文件中配置路由并应用自定义过滤器。

spring:cloud:gateway:routes:- id: api_route_1uri: http://service1.example.compredicates:- Path=/api/v1/**filters:- name: SlowLoggingargs:enabled: truetimeout: 1500- id: api_route_2uri: http://service2.example.compredicates:- Path=/api/v2/**filters:- name: SlowLoggingargs:enabled: falsetimeout: 1000- id: default_routeuri: http://default-service.example.compredicates:- Path=/**filters:- name: SlowLoggingargs:enabled: truetimeout: 2000
  • id: 每个路由的唯一标识符。

  • uri: 目标服务的URI。

  • predicates: 定义路由匹配条件,这里是匹配路径以 /api/ 开头的请求。

  • filters
    定义应用于该路由的过滤器列表。
    • name: 过滤器名称,应与自定义过滤器类名中的 GatewayFilterFactory 前缀部分一致(去掉后缀)。例如,SlowLoggingGatewayFilterFactory 对应的过滤器名称为 SlowLogging
    • args: 过滤器的具体参数,这些参数将传递给过滤器的配置类。

启动Spring Boot应用 和 Gateway网关,并发送请求到不同的路由,观察日志输出。例如,如果你发送一个请求到 http://localhost/api/v1/test 并且响应时间超过1500毫秒,你会看到类似以下的日志记录:

WARN  Slow Request Detected: Method=GET, Path=/api/v1/test, QueryParams={}, Body=..., Duration=1600ms

通过实现自定义的Spring Cloud Gateway过滤器,我们可以灵活地监控和记录响应时间超过指定阈值的请求。这不仅有助于我们更好地了解系统的性能瓶颈,还可以帮助我们在生产环境中快速定位问题。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com