国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

【深入解析spring cloud gateway】06 gateway源碼簡要分析

這篇具有很好參考價(jià)值的文章主要介紹了【深入解析spring cloud gateway】06 gateway源碼簡要分析。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

上一節(jié)做了一個(gè)很簡單的示例,微服務(wù)通過注冊到eureka上,然后網(wǎng)關(guān)通過服務(wù)發(fā)現(xiàn)訪問到對(duì)應(yīng)的微服務(wù)。本節(jié)將簡單地對(duì)整個(gè)gateway請(qǐng)求轉(zhuǎn)發(fā)過程做一個(gè)簡單的分析。

一、核心流程

【深入解析spring cloud gateway】06 gateway源碼簡要分析,深入解析析SpringCloud Gateway,gateway

主要流程:

  • Gateway Client向 Spring Cloud Gateway 發(fā)送請(qǐng)求
  • 請(qǐng)求首先會(huì)被HttpWebHandlerAdapter 進(jìn)行提取組裝成網(wǎng)關(guān)上下文
  • 然后網(wǎng)關(guān)的上下文會(huì)傳遞到DispatcherHandler ,它負(fù)責(zé)將請(qǐng)求分發(fā)給 RoutePredicateHandlerMapping
  • RoutePredicateHandlerMapping負(fù)責(zé)路由查找,并根據(jù)路由斷言判斷路由是否可用
  • 如果過斷言成功,由FilteringWebHandler 創(chuàng)建過濾器鏈并調(diào)用
  • 通過特定于請(qǐng)求的 Fliter 鏈運(yùn)行請(qǐng)求,F(xiàn)ilter 被虛線分隔的原因是Filter可以在發(fā)送代理請(qǐng)求之前(pre)和之后(post)運(yùn)行邏輯
  • 執(zhí)行所有pre過濾器邏輯。然后進(jìn)行代理請(qǐng)求。發(fā)出代理請(qǐng)求后,將運(yùn)行“post”過濾器邏輯。
  • 處理完畢之后將 Response 返回到 Gateway 客戶端

二、具體分析

請(qǐng)求過來,會(huì)經(jīng)過HttpWebHandlerAdapter.handle方法,可以理解為這就是請(qǐng)求的主入口

@Override
public Mono<Void> handle(ServerHttpRequest request, ServerHttpResponse response) {
    if (this.forwardedHeaderTransformer != null) {
        try {
            request = this.forwardedHeaderTransformer.apply(request);
        }
        catch (Throwable ex) {
            if (logger.isDebugEnabled()) {
                logger.debug("Failed to apply forwarded headers to " + formatRequest(request), ex);
            }
            response.setStatusCode(HttpStatus.BAD_REQUEST);
            return response.setComplete();
        }
    }
 //組裝上下文
    ServerWebExchange exchange = createExchange(request, response);

    LogFormatUtils.traceDebug(logger, traceOn ->
            exchange.getLogPrefix() + formatRequest(exchange.getRequest()) +
                    (traceOn ? ", headers=" + formatHeaders(exchange.getRequest().getHeaders()) : ""));
//委派給delegate來處理
    return getDelegate().handle(exchange)
            .doOnSuccess(aVoid -> logResponse(exchange))
            .onErrorResume(ex -> handleUnresolvedError(exchange, ex))
            .then(Mono.defer(response::setComplete));
}

這一個(gè)delegate是個(gè)啥,看一下接口定義:
就是一個(gè)處理器,所有參數(shù)封裝在上下文exchange中

public interface WebHandler {

    /**
     * Handle the web server exchange.
     * @param exchange the current server exchange
     * @return {@code Mono<Void>} to indicate when request handling is complete
     */
    Mono<Void> handle(ServerWebExchange exchange);

}

最終會(huì)調(diào)到DispatcherHandler

@Override
public Mono<Void> handle(ServerWebExchange exchange) {
    if (this.handlerMappings == null) {
        return createNotFoundError();
    }
    if (CorsUtils.isPreFlightRequest(exchange.getRequest())) {
        return handlePreFlight(exchange);
    }
    return Flux.fromIterable(this.handlerMappings)
            .concatMap(mapping -> mapping.getHandler(exchange))
            .next()
            .switchIfEmpty(createNotFoundError())
            .flatMap(handler -> invokeHandler(exchange, handler))
            .flatMap(result -> handleResult(exchange, result));
}

handlerMappings是啥
是一個(gè)列表,HandlerMapping可以根據(jù)當(dāng)前請(qǐng)求,找到對(duì)應(yīng)的處理器
如果當(dāng)前請(qǐng)求比如/hello/world,在gateway服務(wù)上是一個(gè)controller對(duì)應(yīng)的接口,那這個(gè)就可以通過RequestMappingHandlerMapping找到一個(gè)RequestMappingHandlerAdapter。
如果當(dāng)前請(qǐng)求,是需要轉(zhuǎn)發(fā)給下游微服務(wù)的,則找到RoutePredicateHandlerMapping
【深入解析spring cloud gateway】06 gateway源碼簡要分析,深入解析析SpringCloud Gateway,gateway
RoutePredicateHandlerMapping查找路由主要邏輯

@Override
protected Mono<?> getHandlerInternal(ServerWebExchange exchange) {
    // don't handle requests on management port if set and different than server port
    if (this.managementPortType == DIFFERENT && this.managementPort != null
            && exchange.getRequest().getLocalAddress() != null
            && exchange.getRequest().getLocalAddress().getPort() == this.managementPort) {
        return Mono.empty();
    }
    exchange.getAttributes().put(GATEWAY_HANDLER_MAPPER_ATTR, getSimpleName());

    return lookupRoute(exchange)
            // .log("route-predicate-handler-mapping", Level.FINER) //name this
            .flatMap((Function<Route, Mono<?>>) r -> {
                exchange.getAttributes().remove(GATEWAY_PREDICATE_ROUTE_ATTR);
                if (logger.isDebugEnabled()) {
                    logger.debug("Mapping [" + getExchangeDesc(exchange) + "] to " + r);
                }
                                //把找到的路由放到exchange上下文中
                exchange.getAttributes().put(GATEWAY_ROUTE_ATTR, r);
                                //返回的handler實(shí)際上是webHandler
                return Mono.just(webHandler);
            }).switchIfEmpty(Mono.empty().then(Mono.fromRunnable(() -> {
                exchange.getAttributes().remove(GATEWAY_PREDICATE_ROUTE_ATTR);
                if (logger.isTraceEnabled()) {
                    logger.trace("No RouteDefinition found for [" + getExchangeDesc(exchange) + "]");
                }
            })));
}

看下查找路由的具體方式:原來是將所有的路由,用predicate作一下匹配,找出符合當(dāng)前請(qǐng)求的路由

protected Mono<Route> lookupRoute(ServerWebExchange exchange) {
    return this.routeLocator.getRoutes()
            // individually filter routes so that filterWhen error delaying is not a
            // problem
            .concatMap(route -> Mono.just(route).filterWhen(r -> {
                // add the current route we are testing
                exchange.getAttributes().put(GATEWAY_PREDICATE_ROUTE_ATTR, r.getId());
                //用predicate作一下匹配,找出符合當(dāng)前請(qǐng)求的路由
                        return r.getPredicate().apply(exchange);
            })
                    // instead of immediately stopping main flux due to error, log and
                    // swallow it
                    .doOnError(e -> logger.error("Error applying predicate for route: " + route.getId(), e))
                    .onErrorResume(e -> Mono.empty()))
            // .defaultIfEmpty() put a static Route not found
            // or .switchIfEmpty()
            // .switchIfEmpty(Mono.<Route>empty().log("noroute"))
            .next()
            // TODO: error handling
            .map(route -> {
                if (logger.isDebugEnabled()) {
                    logger.debug("Route matched: " + route.getId());
                }
                validateRoute(route, exchange);
                return route;
            });

    /*
     * TODO: trace logging if (logger.isTraceEnabled()) {
     * logger.trace("RouteDefinition did not match: " + routeDefinition.getId()); }
     */
}

routeLocator包含了哪些路由,Debug看一下
【深入解析spring cloud gateway】06 gateway源碼簡要分析,深入解析析SpringCloud Gateway,gateway

可以看到,用了服務(wù)注冊和發(fā)現(xiàn)后,實(shí)際上,一個(gè)微服務(wù)會(huì)自動(dòng)注冊一個(gè)路由,比如上面的hello-service,自動(dòng)注冊了一個(gè)路徑為:/hello-service/**的路由。這就是為什么我們yml配置文件中明明什么路由也沒有配置,也能自動(dòng)轉(zhuǎn)發(fā)hello-service的請(qǐng)求。
同時(shí),可以看到,這個(gè)路由下面有一個(gè)ReWritePathFilter,會(huì)自動(dòng)去掉服務(wù)名,將請(qǐng)求轉(zhuǎn)發(fā)給下游微服務(wù)。
【深入解析spring cloud gateway】06 gateway源碼簡要分析,深入解析析SpringCloud Gateway,gateway

下一步再看看FilteringWebHandler中的處理邏輯

@Override
public Mono<Void> handle(ServerWebExchange exchange) {
//從上下文中取出路由,路由中包含filters
    Route route = exchange.getRequiredAttribute(GATEWAY_ROUTE_ATTR);
    List<GatewayFilter> gatewayFilters = route.getFilters();
//spring容器中的Global Filter也取出來
    List<GatewayFilter> combined = new ArrayList<>(this.globalFilters);
    combined.addAll(gatewayFilters);
    // TODO: needed or cached?
 //做個(gè)排序
    AnnotationAwareOrderComparator.sort(combined);

    if (logger.isDebugEnabled()) {
        logger.debug("Sorted gatewayFilterFactories: " + combined);
    }
//后面就是filter鏈?zhǔn)秸{(diào)用了
    return new DefaultGatewayFilterChain(combined).filter(exchange);
}

可以看到代碼中主要有兩個(gè)邏輯:
1、從上下文中取出路由,路由中包含filters
2、spring容器中的Global Filter也取出來
3、合并上面的兩種filter,并且排序
4、filters列表組裝成責(zé)任鏈來進(jìn)行調(diào)用
可以通過源碼,再來看看核心流程的那個(gè)圖,這樣就比較清楚了。
總結(jié)了另一個(gè)稍微詳細(xì)一點(diǎn)的圖:
【深入解析spring cloud gateway】06 gateway源碼簡要分析,深入解析析SpringCloud Gateway,gateway

個(gè)人看這塊源碼的體會(huì):整個(gè)核心流程并不復(fù)雜,難點(diǎn)大概是reactor響應(yīng)式編程,如果之前沒接觸過這一塊,那么看著會(huì)有種不知道下一步往哪里的困惑!所以要學(xué)習(xí)這塊源碼,還得學(xué)習(xí)reactor。文章來源地址http://www.zghlxwxcb.cn/news/detail-695942.html

到了這里,關(guān)于【深入解析spring cloud gateway】06 gateway源碼簡要分析的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 【深入解析spring cloud gateway】08 Reactor 知識(shí)掃盲

    【深入解析spring cloud gateway】08 Reactor 知識(shí)掃盲

    1.1 背景知識(shí) 為了應(yīng)對(duì)高并發(fā)服務(wù)器端開發(fā)場景,在2009 年,微軟提出了一個(gè)更優(yōu)雅地實(shí)現(xiàn)異步編程的方式——Reactive Programming,我們稱之為響應(yīng)式編程。隨后,Netflix 和LightBend 公司提供了RxJava 和Akka Stream 等技術(shù),使得Java 平臺(tái)也有了能夠?qū)崿F(xiàn)響應(yīng)式編程的框架。 在2017 年9 月

    2024年02月09日
    瀏覽(14)
  • 【深入解析spring cloud gateway】07 自定義異常返回報(bào)文

    【深入解析spring cloud gateway】07 自定義異常返回報(bào)文

    Servlet的HttpResponse對(duì)象,返回響應(yīng)報(bào)文,一般是這么寫的,通過輸出流直接就可以將返回報(bào)文輸出。 在filter中如果發(fā)生異常(例如請(qǐng)求參數(shù)不合法),拋出異常信息的時(shí)候,調(diào)用方收到的返回碼和body都是Spring Cloud Gateway框架處理來處理的。這一節(jié)我們分析一下,gateway的異常返

    2024年02月10日
    瀏覽(26)
  • 【源碼】Spring Cloud Gateway 是在哪里匹配路由的?

    【源碼】Spring Cloud Gateway 是在哪里匹配路由的?

    我們知道,經(jīng)過網(wǎng)關(guān)的業(yè)務(wù)請(qǐng)求會(huì)被路由到后端真實(shí)的業(yè)務(wù)服務(wù)上去,假如我們使用的是Spring Cloud Gateway,那么你知道Spring Cloud Gateway是在哪一步去匹配路由的嗎? 源碼之下無秘密,讓我們一起從源碼中尋找答案。 Spring Cloud Gateway 的入口為 DispatcherHandler 的 handle 方法,其中主

    2023年04月24日
    瀏覽(26)
  • Spring Cloud - 手寫 Gateway 源碼,實(shí)現(xiàn)自定義局部 FilterFactory

    Spring Cloud - 手寫 Gateway 源碼,實(shí)現(xiàn)自定義局部 FilterFactory

    目錄 一、FilterFactory 分析 1.1、前置知識(shí) 1.2、分析源碼 1.2.1、整體分析 1.2.2、源碼分析 1.3、手寫源碼 1.3.1、基礎(chǔ)框架 1.3.2、實(shí)現(xiàn)自定義局部過濾器 1.3.3、加參數(shù)的自定義局部過濾器器 前面的學(xué)習(xí)我們知道,GatewayFilter是網(wǎng)關(guān)中提供的一種過濾器,可以對(duì)進(jìn)入網(wǎng)關(guān)的請(qǐng)求和微服

    2024年02月03日
    瀏覽(13)
  • 細(xì)到不能再細(xì)的 Spring Cloud Gateway 原理分析(內(nèi)含多張圖片講解)

    細(xì)到不能再細(xì)的 Spring Cloud Gateway 原理分析(內(nèi)含多張圖片講解)

    本文會(huì)通過圖文的方式由淺入深的描述 Spring Cloud Gateway (以下簡稱 gateway)的基本原理。 本文不涉及 gateway 的任何示例代碼, 如有需要請(qǐng)參考官網(wǎng) sample 。 閱讀前, 需要讀者提前掌握 gateway 的基本使用。至少要能讀懂如下配置的含義: 一、Gateway 在微服務(wù)中的作用 當(dāng) 請(qǐng)求方

    2023年04月09日
    瀏覽(16)
  • 【Spring Cloud】深入探索統(tǒng)一網(wǎng)關(guān) Gateway 的搭建,斷言工廠,過濾器工廠,全局過濾器以及跨域問題

    【Spring Cloud】深入探索統(tǒng)一網(wǎng)關(guān) Gateway 的搭建,斷言工廠,過濾器工廠,全局過濾器以及跨域問題

    在微服務(wù)架構(gòu)中,網(wǎng)關(guān)是至關(guān)重要的組件,具有多重職責(zé),為整個(gè)系統(tǒng)提供了一系列關(guān)鍵功能。從下面的微服務(wù)結(jié)構(gòu)圖中,我們可以明確網(wǎng)關(guān)的幾項(xiàng)主要作用: 微服務(wù)結(jié)構(gòu)圖: 請(qǐng)求過濾與安全: 用戶的所有請(qǐng)求首先經(jīng)過網(wǎng)關(guān),這使得網(wǎng)關(guān)成為系統(tǒng)的第一道防線。通過對(duì)傳入

    2024年02月07日
    瀏覽(24)
  • 云原生之深入解析K8S Istio Gateway服務(wù)的架構(gòu)分析與實(shí)戰(zhàn)操作

    Istio 提供一種簡單的方式來為已部署的服務(wù)建立網(wǎng)絡(luò),該網(wǎng)絡(luò)具有負(fù)載均衡、服務(wù)間認(rèn)證、監(jiān)控、網(wǎng)關(guān)等功能,而不需要對(duì)服務(wù)的代碼做任何改動(dòng)。 istio 適用于容器或虛擬機(jī)環(huán)境(特別是 k8s),兼容異構(gòu)架構(gòu); istio 使用 sidecar(邊車模式)代理服務(wù)的網(wǎng)絡(luò),不需要對(duì)業(yè)務(wù)代

    2024年02月13日
    瀏覽(99)
  • 【深入Spring源碼解析:解密Bean的生命周期】

    Spring是Java企業(yè)級(jí)應(yīng)用開發(fā)領(lǐng)域的一顆明星,它提供了很多方便開發(fā)人員的工具和思想。在分布式系統(tǒng)中,Spring的分布式遠(yuǎn)程協(xié)作方案,比如REST、Web服務(wù)以及消息傳遞等,也是不可或缺的。 你知道嗎?在我們使用Spring時(shí),容器中存放的所有對(duì)象,在Spring啟動(dòng)的時(shí)候就完成了實(shí)

    2024年02月05日
    瀏覽(28)
  • spring cloud gateway中出現(xiàn)503 spring cloud gateway中出現(xiàn)503

    當(dāng)搭建網(wǎng)關(guān)模塊的時(shí)候出現(xiàn)503的錯(cuò)誤的最大的可能就是沒有設(shè)置負(fù)載均衡的依賴包 ?原先搭建的時(shí)候采用的是下面的方式進(jìn)行設(shè)置的 上面的這種方式可以直接進(jìn)行注冊和發(fā)現(xiàn),但是要求必須導(dǎo)入下面的依賴 希望簡單的隨筆能夠幫助你!

    2024年02月11日
    瀏覽(88)
  • 【Spring Cloud 八】Spring Cloud Gateway網(wǎng)關(guān)

    【Spring Cloud 八】Spring Cloud Gateway網(wǎng)關(guān)

    【Spring Cloud一】微服務(wù)基本知識(shí) 【Spring Cloud 三】Eureka服務(wù)注冊與服務(wù)發(fā)現(xiàn) 【Spring Cloud 四】Ribbon負(fù)載均衡 【Spring Cloud 五】OpenFeign服務(wù)調(diào)用 【Spring Cloud 六】Hystrix熔斷 【Spring Cloud 七】Sleuth+Zipkin 鏈路追蹤 在項(xiàng)目中是使用了Gateway做統(tǒng)一的請(qǐng)求的入口,以及統(tǒng)一的跨域處理以及

    2024年02月12日
    瀏覽(28)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包