Soul 网关源码阅读(三)请求处理概览

本文详细记录了Soul网关请求处理的流程,从HttpServerOperations的请求接收,经过过滤器、WebHandler、插件调用链,到DividePlugin的路由匹配,再到WebClientPlugin的后台请求及WebClientResponsePlugin的响应返回。通过对源码的逐步debug,揭示了Soul网关处理请求的关键步骤和核心组件。
摘要由CSDN通过智能技术生成

Soul 源码阅读(三)请求处理概览


简介

    基于上篇:Soul 源码阅读(二)代码初步运行的配置,这次debug下请求处理的大致路径,验证网关模型的路径

详细流程记录

查看运行日志,寻找切入点

    上篇中我们配置了 Divide 插件,让 http://localhost:9195 ,转发到了后台服务器 http://localhost:8082 上,首先不打断点运行,查看运行日志,找一个切入点:

o.d.soul.plugin.base.AbstractSoulPlugin  : divide selector success match , selector name :neety8082
o.d.soul.plugin.base.AbstractSoulPlugin  : divide selector success match , selector name :neety8082
o.d.s.plugin.httpclient.WebClientPlugin  : The request urlPath is http://localhost:8082, retryTimes is 1

    上面的日志中一个比较明显的 divide 相关的日志,是 AbstractSoulPlugin 打印出来的,win下双击shift,搜索 AbstractSoulPlugin 进入,发现是一个接口,IDEA左边向下的箭头查看它的实现,发现有一个熟系的 DividePlugin 实现类,点击进入,在一个明显的 doExecute 函数上打上断点,发起请求:http://localhost:9195

    通过函数调用栈,发送调用的是 SoulWebHandler ,从下面的函数中可以大致看出这是一个循环遍历,遍历 plugins 进行操作

    public Mono<Void> execute(final ServerWebExchange exchange) {
   
            return Mono.defer(() -> {
   
                if (this.index < plugins.size()) {
   
                    SoulPlugin plugin = plugins.get(this.index++);
                    Boolean skip = plugin.skip(exchange);
                    if (skip) {
   
                        return this.execute(exchange);
                    }
                    return plugin.execute(exchange, this);
                }
                return Mono.empty();
            });
        }
跟踪调用栈

    再次往前看调用栈,发送 SoulWebHandler 调用了 SoulWebHandler 的 execute

    public Mono<Void> handle(@NonNull final ServerWebExchange exchange) {
   
        MetricsTrackerFacade.getInstance().counterInc(MetricsLabelEnum.REQUEST_TOTAL.getName());
        Optional<HistogramMetricsTrackerDelegate> startTimer = MetricsTrackerFacade.getInstance().histogramStartTimer(MetricsLabelEnum.REQUEST_LATENCY.getName());
        // new DefaultSoulPluginChain(plugins).execute(exchange) 明显的调用关系
        return new DefaultSoulPluginChain(plugins).execute(exchange).subscribeOn(scheduler)
                .doOnSuccess(t -> startTimer.ifPresent(time -> MetricsTrackerFacade.getInstance().histogramObserveDuration(time)));
    }

    再往前发现看不懂了,没用明显的函数传递关系,我们在上面的函数打上端口,重启程序,再次发送请求

    断点进来后,查看调用栈,发送调用上面函数的是 DefaultWebFilterChain

    public Mono<Void> filter(ServerWebExchange exchange) {
   
        return Mono.defer(() -> {
   
            // 当下面都为null的时候进行调用
            return this.currentFilter != null && this.chain != null ? this.invokeFilter(this.currentFilter, this.chain, exchange) : this.handler.handle(exchange);
        });
    }

    再往前查看,调用栈又看不懂了,再次在上面的函数打上断点,重启,发请求,下面就直接写类和相关函数,有特别的地方就叫点说明

    来到 FilteringWebHandler

    public Mono<Void> handle(ServerWebExchange exchange) {
   
        return this.chain.filter(exchange);
    }

    继续来到 WebHandlerDecorator

    public Mono<Void> handle(ServerWebExchange exchange) {
   
        return this.delegate.handle(exchange);
    }

    来到 ExceptionHandlingWebHandler

public Mono<Void> handle(ServerWebExchange exchange) {
   
        Mono completion;
        try {
   
            // 在这进行调用
            completion = super.handle(exchange);
        } catch (Throwable var5) {
   
            completion = Mono.error(var5);
        }

        WebExceptionHandler handler;
        for(Iterator var3 = this.exceptionHandlers.iterator(); var3.hasNext(); completion = completion.onErrorResume((ex) -> {
   
            return handler.handle(exchange, ex);
        })) {
   
            handler = (WebExceptionHandler)var3.next();
        }

        return completion;
    }

    继续来到 HttpWebHandlerAdapter ,这个类有点关键,看到在前面一直传递的变量:exchange,exchange在这个类中生成,传递给后面的函数进行调用,而且是使用response和request生成的

    public Mono<Void> handle(ServerHttpRequest request, ServerHttpResponse response) {
   
        if (this.forwardedHeaderTransformer != null) {
   
            request = this.forwardedHeaderTransformer.apply(request);
        }

        // 重点变量 exchange 的生成
        ServerWebExchange exchange = this.createExchange(request, response);
        LogFormatUtils.traceDebug(logger, (traceOn) -> {
   
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值