zoukankan      html  css  js  c++  java
  • Spring Cloud Gateway 请求报文获取 高性能实现方法

    1 简介

    本文使用的spring cloud版本:2020.0.1

    关于Spring Cloud Gateway报文获取,网上写法较多参考ModifyRequestBodyGatewayFilterFactory,经过非严谨测试其性能下降剧烈。

    本文同样参考Spring Cloud Gateway源码,只不过参考的是ReadBodyRoutePredicateFactory,经过非严谨测试该方式性能相较上述方案有了巨大提升。

    2 写法核心逻辑(直接仿写ReadBodyRoutePredicateFactory,定义一个Filter)

    @Override
        public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {//WebFilterChain GatewayFilterChain
            ServerHttpRequest currentHttpRequest = exchange.getRequest();
            if(logReqRespUtils.needGenerateSn(currentHttpRequest.getMethod())){
    return ServerWebExchangeUtils.cacheRequestBodyAndRequest(exchange,(serverHttpRequest) ->
                        ServerRequest
                                .create(exchange.mutate().request(serverHttpRequest).build(), messageReaders)
                                .bodyToMono(String.class)
                                .defaultIfEmpty("")
                                .doOnNext(objectValue -> {
    //objectValue即为请求Body内容 }) .flatMap(bodyString
    ->{ if (serverHttpRequest == exchange.getRequest()) { return chain.filter(exchange); } //ServerWebExchangeUtils.cacheRequestBodyAndRequest中已经缓存了可重复读的request 并且request也已经转换成了可重复读Body的request ServerHttpRequest cacheRequest = (ServerHttpRequest)exchange.getAttributes().get(ServerWebExchangeUtils.CACHED_SERVER_HTTP_REQUEST_DECORATOR_ATTR); return chain.filter(exchange.mutate().request(cacheRequest).build()); }) ); } return chain.filter(exchange); }

    3 源码简析

    ReadBodyRoutePredicateFactory可用来对请求体内容进行判断。

    如此其中一定会获取请求体。

    该文件短短一百多行代码,很快就可以定位到其核心部分:

    在完成request和requestBody的缓存之后,通过ServerHttpRequest创建了一个ServerRequest ,拿到请求体的字符串,之后进行判断。

     查看 ServerWebExchangeUtils相关代码,显然可见:

     获取了body(Flux<DataBuffer>),之后装饰了一个新的Request,在exchange中将dataBuffer(请求体)和装饰后的Request进行缓存。之后交由我们自定义的逻辑进行处理。

     上图的 decorate方法中有一处 用到了Netty的retainedSlice方法:

     大意就是创建了一个ByteBuf的副本,不过是同源的,改内容会彼此影响,操作索引不会彼此影响。因此可以重复读,不需要我们手动释放,最后交由Spring去释放掉。




    --------------------------------------------------------
    本文发表于:https://www.cnblogs.com/flying607/
  • 相关阅读:
    Visual Studio 2019 使用 Web Deploy 发布远程站点到IIS服务器
    postman下载地址
    ASP.NET Core开发-Docker部署运行
    C# ffmpeg 视频处理格式转换具体案例
    C# ffmpeg 视频处理格式转换和添加水印
    C# ffmpeg 视频处理
    Tomcat 安装与配置
    Maven 快速入门
    Jenkins 快速搭建
    Google SRE 读书笔记 扒一扒SRE用的那些工具
  • 原文地址:https://www.cnblogs.com/flying607/p/15273330.html
Copyright © 2011-2022 走看看