SpringCloud Gateway 网关获取或修改接口响应数据

前言

      我们的网关在之前只记录了接口请求日志,响应日志是没有做记录的,在后续别人对接我们开放平台时出现了一些问题没法确认当时的一个数值状态,照成了很多不必要的麻烦,后来决定在网关添加上响应日志记录。

一、获取响应数据并打印

import lombok.extern.slf4j.Slf4j;
import org.reactivestreams.Publisher;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.core.io.buffer.DataBufferFactory;
import org.springframework.core.io.buffer.DataBufferUtils;
import org.springframework.core.io.buffer.DefaultDataBufferFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.http.server.reactive.ServerHttpResponseDecorator;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import java.nio.charset.Charset;

@Slf4j
@Component
public class ResponseLogGlobalFilter implements GlobalFilter, Ordered {

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        try {
            ServerHttpResponse originalResponse = exchange.getResponse();
            DataBufferFactory bufferFactory = originalResponse.bufferFactory();
            ServerHttpResponseDecorator decoratedResponse = new ServerHttpResponseDecorator(originalResponse) {
                @Override
                public Mono<Void> writeWith(Publisher<? extends DataBuffer> body) {
                    if (body instanceof Flux) {
                        Flux<? extends DataBuffer> fluxBody = Flux.from(body);

                        return super.writeWith(fluxBody.buffer().map(dataBuffers -> {
                            // 合并多个流集合,解决返回体分段传输
                            DataBufferFactory dataBufferFactory = new DefaultDataBufferFactory();
                            DataBuffer buff = dataBufferFactory.join(dataBuffers);
                            byte[] content = new byte[buff.readableByteCount()];
                            buff.read(content);
                            DataBufferUtils.release(buff);//释放掉内存

                            //排除Excel导出,不是application/json不打印
                            MediaType contentType = originalResponse.getHeaders().getContentType();
                            if (!MediaType.APPLICATION_JSON.isCompatibleWith(contentType)) {
                                return bufferFactory.wrap(content);
                            }

                            // 想要关联请求和响应日志可以添加自定义请求头(我这里会在打印请求日志的过滤器中添加REUQEST_ID头来关联响应日志)
                            String reuqestId = exchange.getRequest().getHeaders().getFirst("REUQEST_ID");
                            // content就是response的值,可以查看和修改
                            String contentStr = new String(content, Charset.forName("UTF-8"));
                            log.info("reuqestId={} contentStr={}",reuqestId,contentStr);

                            getDelegate().getHeaders().setContentLength(contentStr.getBytes().length);
                            return bufferFactory.wrap(contentStr.getBytes());
                        }));
                    } else {
                        log.error("<-- {} 响应code异常", getStatusCode());
                    }
                    return super.writeWith(body);
                }
            };
            return chain.filter(exchange.mutate().response(decoratedResponse).build());

        } catch (Exception e) {
            log.error("gateway log exception e={}", e);
            return chain.filter(exchange);
        }
    }

    @Override
    public int getOrder() {
        return -1;
    }
}

### 回答1: Spring Cloud Gateway Sentinel是Spring Cloud Gateway的一个扩展,用于提供应用程序的流量限制和熔断功能。 首先,Spring Cloud Gateway是一个基于Spring Boot的API网关,用于构建微服务架构中的API服务网关。它提供了路由和过滤功能,能够处理HTTP请求并进行相应的转发、过滤和路由。 而Sentinel是阿里巴巴开源的一种流量控制组件,它具备实时监控、熔断降级、系统自适应、热点参数限流等功能。通过Sentinel,可以实现对流量的实时控制和管理,在高并发请求的情况下,可以有效地保护应用系统,避免雪崩效应的发生。 Spring Cloud Gateway Sentinel将Sentinel的流量控制和熔断能力集成到了Spring Cloud Gateway中。它可以通过配置规则来限制每个API接口的访问流量,并在流量超出限制时,进行限流处理,保护应用程序的稳定性。同时,它还可以根据实际情况对请求进行熔断,从而避免请求过多导致服务不可用。 通过使用Spring Cloud Gateway Sentinel,我们可以灵活地对API接口进行流量控制和熔断处理,提高系统的稳定性和可用性。它的配置简单灵活,集成了Spring Cloud Gateway和Sentinel的优势,可以帮助我们更好地构建和管理微服务架构中的API服务网关。 ### 回答2: Spring Cloud Gateway Sentinel是一种基于Sentinel的流量控制和故障熔断的解决方案。Spring Cloud Gateway是一个轻量级的网关服务组件,而Sentinel是一个开源的流量控制和故障熔断框架。通过将两者结合使用,可以实现在网关层面对流量进行实时控制和保护。 Spring Cloud Gateway Sentinel提供了一系列的规则和策略,可以根据业务的需要进行配置。可以通过设置流量控制规则,限制某个接口的访问频率,防止过多的请求导致系统崩溃。另外,还可以设置熔断规则,当某个接口出现异常或者响应时间过长时,可以自动开启熔断策略,避免影响到其他正常的请求。 使用Spring Cloud Gateway Sentinel可以提高系统的可靠性和稳定性。当系统的流量过大或者出现异常时,会自动触发流量控制和熔断策略,保护系统的正常运行。同时,通过监控和日志记录,可以实时了解系统的运行状态和性能指标,方便进行故障排查和性能优化。 总之,Spring Cloud Gateway Sentinel是一个强大的流量控制和故障熔断的组件,可以保护系统免受异常流量的影响,确保系统的稳定性和可靠性。在微服务架构中,它发挥着重要的作用,对于系统的安全和性能优化有着重要的意义。 ### 回答3: Spring Cloud GatewaySpring Cloud生态系统中的一个开源网关项目,它提供了一种统一的的API管理方式,用于处理所有请求并将它们路由到适当的服务上。而Sentinel是一个开源的流量控制和熔断降级的框架,它提供了实时的监控和控制,以保护分布式系统免受故障的影响。 Spring Cloud Gateway集成了Sentinel用于增强网关的功能。它可以通过使用Sentinel进行流量控制和熔断降级,以确保服务的可用性和稳定性。可以根据业务需求,配置规则来限制请求的频率,避免由于高并发造成的系统崩溃,同时还能通过熔断降级机制来防止请求被无效的服务占用,提高整个系统的可靠性。 Spring Cloud Gateway使用Sentinel可以提供实时的流量监控和控制功能,可以根据实时的请求情况对服务进行动态调整。Sentinel可以监控各个服务的QPS(每秒请求数),RT(响应时间)和异常比例等指标,并通过自定义的规则进行实时的流量控制和限制。当某个服务出现异常或超过设定的阈值时,Sentinel可以及时触发熔断降级策略,将请求快速失败,避免传递到后端服务,保护整个系统免受故障的影响。 总之,Spring Cloud Gateway集成Sentinel可以通过流量控制和熔断降级来提高系统的可用性和稳定性,保证服务的高效运行。它能够实时监控服务的运行指标,并根据实时的情况对流量进行动态调整,保护系统免受故障的影响。这是一个非常强大和有用的功能,可以帮助开发人员构建可靠和鲁棒的微服务架构。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值