日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁(yè)技術(shù)文章
文章詳情頁(yè)

Java源碼解析之Gateway請(qǐng)求轉(zhuǎn)發(fā)

瀏覽:28日期:2022-08-09 18:29:26
Gateway請(qǐng)求轉(zhuǎn)發(fā)

本期我們主要還是講解一下Gateway,上一期我們講解了一下Gateway中進(jìn)行路由轉(zhuǎn)發(fā)的關(guān)鍵角色,過(guò)濾器和斷言是如何被加載的,上期鏈接://www.jb51.net/article/211824.htm

好了我們廢話不多說(shuō),開(kāi)始今天的Gateway請(qǐng)求轉(zhuǎn)發(fā)流程講解,為了在講解源碼的時(shí)候,以防止大家可能會(huì)迷糊,博主專門(mén)畫(huà)了一下源碼流程圖,鏈接地址://www.jb51.net/article/211824.htm

上一期我們已經(jīng)知道了相關(guān)類的加載,今天直接從源碼開(kāi)始,大家可能不太了解webflux和reactor這種響應(yīng)式編程,畢竟不是主流,我們一直用的都是spring MVC,沒(méi)事,我們主要講解流程,不做過(guò)多的講解。

大家先看下面的代碼,我們今天主要的代碼入口就是這里:

public Mono<Void> handle(ServerWebExchange exchange) {if (logger.isDebugEnabled()) { ServerHttpRequest request = exchange.getRequest(); logger.debug('Processing ' + request.getMethodValue() + ' request for [' + request.getURI() + ']');}if (this.handlerMappings == null) { return Mono.error(HANDLER_NOT_FOUND_EXCEPTION);}return Flux.fromIterable(this.handlerMappings).concatMap(mapping -> mapping.getHandler(exchange)).next().switchIfEmpty(Mono.error(HANDLER_NOT_FOUND_EXCEPTION)).flatMap(handler -> invokeHandler(exchange, handler)).flatMap(result -> handleResult(exchange, result)); }

第一步,我們先來(lái)看一看幾個(gè)主要的類及其方法,F(xiàn)lux 表示的是包含 0 到 N 個(gè)元素的異步序列,Mono 表示的是包含 0 或者 1 個(gè)元素的異步序列,記住Flux是多個(gè)元素集合,Mono 是單個(gè)元素集合就很好理解以后的源碼了,以下方法注釋是博主為了大家好理解而寫(xiě)的,具體實(shí)際的意義還是需要大家自行Google學(xué)習(xí)了。

Mono.empty();創(chuàng)建一個(gè)空Mono對(duì)象;

Mono.just(**);創(chuàng)建一個(gè)**元素的對(duì)象;

Mono.then(**);在最后執(zhí)行,相當(dāng)于spring的aop后置通知一樣

開(kāi)始我們的第一步解析:mapping.getHandler(exchange);本方法主要做的是獲取路由,我們繼續(xù)看一看底層源碼:

Java源碼解析之Gateway請(qǐng)求轉(zhuǎn)發(fā)getHandler

Java源碼解析之Gateway請(qǐng)求轉(zhuǎn)發(fā)getHandlerInternal

//這里返回的是單個(gè)對(duì)象 protected Mono<Route> lookupRoute(ServerWebExchange exchange) {return this.routeLocator//我們一會(huì)主要看一下這個(gè)方法.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()); //只返回一個(gè)符合斷言的路由配置,所以整個(gè)流程先匹配斷言 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;}); }

我們現(xiàn)在看看Route對(duì)象是怎么在getRoutes()創(chuàng)建的。

public Flux<Route> getRoutes() {return this.routeDefinitionLocator.getRouteDefinitions() //這一步是從配置文件中讀取我們配置的路由定義.map(this::convertToRoute)//這一步會(huì)加載我們配置給路由的斷言與過(guò)濾器形成路由對(duì)象//TODO: error handling.map(route -> { if (logger.isDebugEnabled()) {logger.debug('RouteDefinition matched: ' + route.getId()); } return route;}); }

//關(guān)鍵的代碼在這里 private Route convertToRoute(RouteDefinition routeDefinition) { //這兩步才會(huì)跟上一章節(jié)講解的如何加載斷言與過(guò)濾器有關(guān)聯(lián),大家可以自行查看底層源碼是如何查出來(lái)的對(duì)象的AsyncPredicate<ServerWebExchange> predicate = combinePredicates(routeDefinition);List<GatewayFilter> gatewayFilters = getFilters(routeDefinition); //終于生成了路由對(duì)象return Route.async(routeDefinition).asyncPredicate(predicate).replaceFilters(gatewayFilters).build(); }

這里大家要記住getHandlerInternal方法,生成了Mono.just(webHandler),仔細(xì)看webHandler是FilteringWebHandler對(duì)象,以后用到這個(gè)WebHandler,好了路由生成也選擇完畢了,我們應(yīng)該知道改請(qǐng)求是否符合我們配置的過(guò)濾器了,因?yàn)檫^(guò)濾器還沒(méi)用上,斷言只負(fù)責(zé)了選擇哪一個(gè)路由生效。

//我們看下一個(gè)主流程的方法 private Mono<HandlerResult> invokeHandler(ServerWebExchange exchange, Object handler) {if (this.handlerAdapters != null) { for (HandlerAdapter handlerAdapter : this.handlerAdapters) {if (handlerAdapter.supports(handler)) {//這里走的是SimpleHandlerAdapter,可以自己debug發(fā)現(xiàn),也可以去找自動(dòng)配置類找,這里就不講解了 return handlerAdapter.handle(exchange, handler);} }}return Mono.error(new IllegalStateException('No HandlerAdapter: ' + handler)); }

public Mono<HandlerResult> handle(ServerWebExchange exchange, Object handler) {WebHandler webHandler = (WebHandler) handler;//讓大家記住的那個(gè)FilteringWebHandler類,終于在這里起作用了。我們這回可以看看過(guò)濾器是如何起作用的Mono<Void> mono = webHandler.handle(exchange); return mono.then(Mono.empty());//過(guò)濾器處理完后,開(kāi)始處理mono.then方法 }

public Mono<Void> handle(ServerWebExchange exchange) {Route route = exchange.getRequiredAttribute(GATEWAY_ROUTE_ATTR);List<GatewayFilter> gatewayFilters = route.getFilters();//我們路由自己配置的過(guò)濾器//加載全局過(guò)濾器List<GatewayFilter> combined = new ArrayList<>(this.globalFilters);combined.addAll(gatewayFilters);//TODO: needed or cached?AnnotationAwareOrderComparator.sort(combined);//排序if (logger.isDebugEnabled()) { logger.debug('Sorted gatewayFilterFactories: '+ combined);}//形成過(guò)濾器鏈,開(kāi)始調(diào)用filter進(jìn)行過(guò)濾。這里剩下的我們就不講解,跟spring配置的過(guò)濾器鏈調(diào)用流程是一樣的return new DefaultGatewayFilterChain(combined).filter(exchange); }

至此,我們的請(qǐng)求流程基本完事了,我們?cè)賮?lái)看看幾個(gè)主要的全局過(guò)濾器配置。LoadBalancerClientFilter:負(fù)責(zé)獲取服務(wù)器ip的過(guò)濾器,NettyRoutingFilter:負(fù)責(zé)轉(zhuǎn)發(fā)我們請(qǐng)求的過(guò)濾器。

這里主要講解Gateway流程,關(guān)于Ribbon的代碼我們就不做主要講解了

public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {URI url = exchange.getAttribute(GATEWAY_REQUEST_URL_ATTR);String schemePrefix = exchange.getAttribute(GATEWAY_SCHEME_PREFIX_ATTR);//所以要加上lb前綴,才會(huì)走該過(guò)濾器if (url == null || (!'lb'.equals(url.getScheme()) && !'lb'.equals(schemePrefix))) { return chain.filter(exchange);}//preserve the original urladdOriginalRequestUrl(exchange, url);log.trace('LoadBalancerClientFilter url before: ' + url);//選擇實(shí)例final ServiceInstance instance = choose(exchange);......return chain.filter(exchange); }

看主要代碼即可,非必要的看了也暈。

public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {.......//通過(guò)httpClient發(fā)送請(qǐng)求獲取響應(yīng)Mono<HttpClientResponse> responseMono = this.httpClient.request(method, url, req -> { final HttpClientRequest proxyRequest = req.options(NettyPipeline.SendOptions::flushOnEach) .headers(httpHeaders) .chunkedTransfer(chunkedTransfer) .failOnServerError(false) .failOnClientError(false); if (preserveHost) {String host = request.getHeaders().getFirst(HttpHeaders.HOST);proxyRequest.header(HttpHeaders.HOST, host); } if (properties.getResponseTimeout() != null) {proxyRequest.context(ctx -> ctx.addHandlerFirst(new ReadTimeoutHandler(properties.getResponseTimeout().toMillis(), TimeUnit.MILLISECONDS))); } return proxyRequest.sendHeaders() //I shouldn’t need this .send(request.getBody().map(dataBuffer -> ((NettyDataBuffer) dataBuffer).getNativeBuffer()));});return responseMono.doOnNext(res -> {...} }

我們今天主要看的是Gateway的主要請(qǐng)求轉(zhuǎn)發(fā)的流程,像webflux這種我們沒(méi)有精力學(xué)習(xí)的,可以暫時(shí)略過(guò),畢竟也不是主流。我們今天最后總結(jié)一下。首先在Gateway這兩章的點(diǎn),項(xiàng)目啟動(dòng)時(shí)加載斷言與過(guò)濾器->接收請(qǐng)求時(shí)添加配置文件中的路由配置并生成路由對(duì)象->找到符合斷言的路由->除了個(gè)人配置的過(guò)濾器聯(lián)合全局過(guò)濾器生成過(guò)濾器鏈,并逐步過(guò)濾知道所有調(diào)用完成。

其中我們主要分析了兩個(gè)主要的全局過(guò)濾器:LoadBalancerClientFilter:負(fù)責(zé)獲取服務(wù)器ip的過(guò)濾器,NettyRoutingFilter:負(fù)責(zé)轉(zhuǎn)發(fā)我們請(qǐng)求的過(guò)濾器。

到此這篇關(guān)于Java源碼解析之Gateway請(qǐng)求轉(zhuǎn)發(fā)的文章就介紹到這了,更多相關(guān)Gateway請(qǐng)求轉(zhuǎn)發(fā)內(nèi)容請(qǐng)搜索好吧啦網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持好吧啦網(wǎng)!

標(biāo)簽: Java
相關(guān)文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
四虎在线精品| 亚洲高清不卡| 日韩成人午夜精品| 三级一区在线视频先锋| 丝袜脚交一区二区| 日韩有吗在线观看| 欧美在线看片| 免费一区二区三区在线视频| 精品视频一区二区三区在线观看| 奇米色欧美一区二区三区| 国产私拍福利精品视频二区| 国产精品美女午夜爽爽| 久久三级毛片| 成人羞羞在线观看网站| 免费视频国产一区| 99riav1国产精品视频| 蜜桃久久精品一区二区| 欧美一级二区| 国产v日韩v欧美v| 亚洲国产专区| 一区二区精品| 国产精品大片| 黑人精品一区| 99在线观看免费视频精品观看| 蜜臀久久99精品久久一区二区| 99视频在线精品国自产拍免费观看| 久久午夜精品一区二区| 欧美私人啪啪vps| 国产成人精品三级高清久久91 | 麻豆久久一区| 日韩欧美综合| 亚洲激情五月| 中文字幕日韩亚洲| 国产精品xxxav免费视频| 国产一区二区三区久久| 99久久久久久中文字幕一区| 在线亚洲精品| 国产精品久久久久久久久久久久久久久 | 日韩av在线免费观看不卡| 国产精品亚洲欧美| 日韩精品欧美激情一区二区| 午夜在线精品| 久久在线91| 亚洲在线网站| 国产极品嫩模在线观看91精品| 色88888久久久久久影院| 国产亚洲毛片在线| 国产精品第一| 日韩一级欧洲| 麻豆视频一区| 亚洲欧美日韩一区在线观看| 精品亚洲免a| 人人精品人人爱| 黑森林国产精品av| 日本亚洲不卡| 成人av动漫在线观看| 国产伦精品一区二区三区视频 | 少妇久久久久| 91亚洲无吗| 激情欧美国产欧美| 国产精品66| 噜噜噜久久亚洲精品国产品小说| 丰满少妇一区| 日本成人在线不卡视频| 欧美日韩视频免费观看| 久久国产精品色av免费看| 国产99精品一区| 国产精品qvod| 视频一区免费在线观看| 91嫩草亚洲精品| 最新国产精品久久久| 裤袜国产欧美精品一区| 日本不卡一二三区黄网| 免费av一区| 91亚洲人成网污www| 日韩av影院| 国产视频亚洲| 欧美二三四区| 精品亚洲自拍| 欧美在线看片| 亚洲日本免费电影| 欧美日韩黑人| 久久蜜桃精品| 激情不卡一区二区三区视频在线| 日韩av一区二区在线影视| 尤物在线精品| 日韩一区二区中文| 鲁大师精品99久久久| 日本中文字幕一区二区| 99riav国产精品| 久久在线电影| 亚洲精品一级二级| 黑森林国产精品av| 久久精品五月| 国产精品第一| 国产毛片久久久| 日韩精品一区二区三区av| 99国产成+人+综合+亚洲欧美| av亚洲一区二区三区| 国产一区二区三区天码| 欧美在线黄色| 亚洲一级大片| 免费久久99精品国产自在现线| 欧美gv在线| 日韩中文字幕高清在线观看| 国产一区一一区高清不卡| 国产极品久久久久久久久波多结野| 亚洲精品自拍| 亚洲一二av| 蜜桃传媒麻豆第一区在线观看| 久久国产成人| 久久午夜视频| 亚洲小说春色综合另类电影| 国产婷婷精品| 噜噜噜久久亚洲精品国产品小说| 99久久亚洲精品蜜臀| 午夜精品久久久久久久久久蜜桃| bbw在线视频| 成人va天堂| 亚洲夜间福利| 亚洲一区久久| 亚洲精选成人| 日韩av午夜在线观看| 国产欧美91| 国产一区国产二区国产三区| 国产在线看片免费视频在线观看| 福利视频一区| xxxxx性欧美特大| 久久夜夜操妹子| 国产精品av久久久久久麻豆网| 久久五月天小说| 91精品精品| 亚洲免费黄色| 亚洲精品麻豆| 国产日韩欧美中文在线| 久久字幕精品一区| 日韩国产综合| 午夜日韩av| 亚洲免费毛片| 国产精品色在线网站| 日韩av有码| 成人日韩在线| 最新亚洲激情| 日本免费一区二区视频| 久久爱www成人| 波多野结衣久久精品| 久久免费国产| 美美哒免费高清在线观看视频一区二区| 日韩欧美中文字幕电影| 欧美国产不卡| 麻豆免费精品视频| 日韩精品一区二区三区免费观影| 中文久久精品| 欧美日韩调教| 麻豆视频在线看| 日韩视频免费| 欧美日本精品| 国产精品伦理久久久久久| 美女亚洲一区| 日本久久一区| 色婷婷色综合| 婷婷精品进入| 欧美亚洲tv| 国产亚洲一区二区手机在线观看| 亚洲尤物在线| 久久免费福利| 亚洲女同中文字幕| 青青国产精品| 一区二区三区四区日本视频| 在线亚洲自拍| 国产乱码精品一区二区亚洲| 欧美不卡高清一区二区三区| 在线精品亚洲| 久久久久久婷| 蜜桃av一区二区三区电影| 精品日韩在线| 影音国产精品| 久久亚洲国产精品尤物| 国产视频一区三区| 久久精品资源| 丝袜美腿亚洲一区| 91综合网人人| 婷婷久久免费视频| 久久久久91| 国产欧美另类| 一区在线免费观看| 欧美激情aⅴ一区二区三区 | 日韩精品久久理论片| 欧产日产国产精品视频| 亚洲v天堂v手机在线| 97精品中文字幕| 亚洲精品人人| 久久久国产亚洲精品| 7777精品| 99综合视频| 樱桃视频成人在线观看| 青青草国产精品亚洲专区无| 欧美在线资源| 国际精品欧美精品| 色8久久久久|