摘要:將請求封裝成將請求封裝成的接口定義是但是最外層傳進來的參數是和,需要將他們封裝成,這個工作就是在中做的。其實主要任務就是將各種參數封裝成除了和本次請求相關的和,還有會話管理器,編碼解碼器配置,國際化配置還有用于擴展。
接下來,將進入我們升級之路的又一大模塊,即網關模塊。網關模塊我們廢棄了已經進入維護狀態的 zuul,選用了 Spring Cloud Gateway 作為內部網關。為何選擇 Spring Cloud Gateway 而不是 nginx 還有 Kong 的原因是:
因此,我們使用了 Spring Cloud Gateway 作為內部網關,接下來,我們就來依次實現上面說的這些功能。同時在本次升級使用過程中, Spring Cloud Gateway 也有一些坑,例如:
但是首先,我們需要簡單理解下 Spring Cloud Gateway 究竟包括哪些組件以及整個調用流程是什么樣子的。由于 Spring Cloud Gateway 基于 Spring-Boot 和 Spring-Webflux 實現,所以我們會從外層 WebFilter 開始說明,然后分析如何走到 Spring Cloud Gateway 的封裝邏輯,以及 Spring Cloud Gateway 包含的組件,請求是如何轉發出去,回來后又經過了哪些處理,這些我們都會逐一分析。
為了詳細分析流程,我們先來創建一個簡單的網關,用于快速上手并分析。
首先創建依賴:
pom.xml
spring-cloud-parent com.github.jojotech 2020.0.3-SNAPSHOT 4.0.0 spring-cloud-api-gateway com.github.jojotech spring-cloud-webflux ${project.version} org.springframework.cloud spring-cloud-starter-gateway
parent 指向了我們項目的 spring-cloud-parent,同時加入了上一節實現的 spring-cloud-webflux 依賴,同時還需要加入 spring-cloud-starter-gateway,由于在我們的 spring-cloud-parent 已經指定了 spring-cloud-parent 的版本依賴管理,所以這里不需要指定 spring-cloud-starter-gateway 的版本
然后,我們開始編寫配置文件:
application.yml
server: ##端口為 8181 port: 8181spring: application: # 微服務名稱是 apiGateway name: apiGateway cloud: gateway: httpclient: # 網關轉發到其他微服務的 HTTP 連接超時為 500ms connect-timeout: 500 # 網關轉發到其他微服務的 HTTP 響應超時為 500ms response-timeout: 60000 routes: # 編寫轉發規則 - id: first_route # 轉發到微服務 test-service uri: lb://test-service # 包含哪些路徑 predicates: - Path=/test-ss/** # 轉發到的微服務訪問路徑,去掉路徑中的第一塊,即去掉 /test-ss filters: - StripPrefix=1 loadbalancer: # 指定 zone,因為我們之前在負載均衡中加入了只有同一個 zone 的實例才能互相訪問的邏輯 zone: test ribbon: # 關閉ribbon enabled: false cache: # 本地微服務實例列表緩存時間 ttl: 5 # 緩存大小,你的微服務調用多少個其他微服務,大小就設置為多少,默認256 capacity: 256 discovery: client: simple: # 使用 spring-common 中的簡單 DiscoveryClient 服務發現客戶端,就是將微服務實例寫死在配置文件中 instances: # 指定微服務 test-service 的實例列表 test-service: - host: httpbin.org port: 80 metadata: # 指定該實例的 zone,因為我們之前在負載均衡中加入了只有同一個 zone 的實例才能互相訪問的邏輯 zone: testeureka: client: # 關掉 eureka enabled: false
最后編寫啟動入口類:
package com.github.jojotech.spring.cloud.apigateway;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication(scanBasePackages = "com.github.jojotech.spring.cloud.apigateway")public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); }}
啟動,訪問路徑: http://127.0.0.1:8181/test-ss/anything
,可以看到請求被發送到 httpbin.org 的 anything 路徑中,這個接口會返回請求中的所有信息。
這樣,我們就實現了一個簡單的網關。接下來我們來詳細分析其工作流程和源碼。
我們創建的簡易網關,外層的服務容器其實就是基于 Netty 和 Project Reactor 的容器,我們跳過這些,直接進入 Spring Boot 相關的處理邏輯。我們只需要知道,請求和其對應的響應,會被外層的容器封裝成為 ServerHttpRequest request
和 ServerHttpResponse response
(都在 org.springframework.http.server.reactive
這個包下)。
然后,會交由 WebHandler
進行處理。WebHandler
的實現,其實是一種責任鏈裝飾模式,如下圖所示。每一層的 WebHandler
會將 request
和 response
進行對應自己責任的裝飾,然后交給內層的 WebHandler
處理。
WebHandler
的接口定義是:
public interface WebHandler { Mono handle(ServerWebExchange exchange);}
但是最外層傳進來的參數是 request
和 response
,需要將他們封裝成 ServerWebExchange
,這個工作就是在 HttpWebHandlerAdapter 中做的。HttpWebHandlerAdapter 其實主要任務就是將各種參數封裝成 ServerWebExchange
(除了和本次請求相關的 request
和 response
,還有會話管理器 SessionManager,編碼解碼器配置,國際化配置還有 ApplicationContext 用于擴展)。
除了這些,處理 Forwarded
還有 X-Forwarded*
相關的 Header 的配置邏輯,也在這里進行。然后將封裝好的 ServerWebExchange
交給內層的 WebHandler
即 ExceptionHandlingWebHandler
繼續處理。同時,從源碼中可以看出,交給內層處理的 Mono 還加入了異常處理和記錄響應信息的邏輯:
//交給內層處理封裝好的 `ServerWebExchange`return getDelegate().handle(exchange) //記錄響應日志,trace 級別,一般用不上 .doOnSuccess(aVoid -> logResponse(exchange)) //處理內層沒有處理的異常,一般不會走到這里 .onErrorResume(ex -> handleUnresolvedError(exchange, ex)) //在所有處理完成后,將 response 設為 complete .then(Mono.defer(response::setComplete));
剩下的內層的 WebHandler
,我們將在下一節中繼續分析
微信搜索“我的編程喵”關注公眾號,每日一刷,輕松提升技術,斬獲各種offer:
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/125101.html
摘要:在這里,會將上下文中載入的拼接成,然后調用其方法的,它是的處理請求業務的起點。添加相關依賴之后,會有這個。路由權重相關配置功能相關實現類,這個我們這里不關心。本系列代碼地址:https://github.com/JoJoTec/spring-cloud-parent我們繼續分析上一節提到的 WebHandler,經過將請求封裝成 ServerWebExchange 的 HttpWebHand...
摘要:在這里,會將上下文中載入的拼接成,然后調用其方法的,它是的處理請求業務的起點。添加相關依賴之后,會有這個。路由權重相關配置功能相關實現類,這個我們這里不關心。 本系列代碼地址:??https://github.com/JoJoTec/spring-cloud-parent??我們繼續分析上一節提到的 ??WebHandle...
摘要:添加相關依賴之后,會有這個。接著,根據的源碼分析,會繼續鏈路,到達下一個,即。在中,我們會計算出路由并發送請求到符合條件的。這個是的,會讀取配置并生成路由。本系列代碼地址:https://github.com/JoJoTec/spring-cloud-parent我們繼續分析上一節提到的 WebHandler。加入 Spring Cloud Sleuth 以及 Prometheus 相關依賴...
摘要:升級之路版基本流程講解抽象類本系列代碼地址我們繼續分析上一節提到的。添加相關依賴之后,會有這個。路由權重相關配置功能相關實現類,這個我們這里不關心。這個是的,會讀取配置并生成路由。 本系列代碼地址:??https://github.com/JoJoTec/spring-cloud-parent??我們繼續分析上一節提到的 ...
摘要:對于異步的請求,使用的是異步客戶端即。要實現的配置設計以及使用舉例要實現的配置設計以及使用舉例首先,我們要實現的,其包含三個重試重試的要在負載均衡之前,因為重試的時候,我們會從負載均衡器獲取另一個實例進行重試,而不是在同一個實例上重試多次。 本系列代碼地址:https://github.com/JoJoTec/spring-cloud-parent 為何需要封裝異步 HT...
閱讀 3735·2023-01-11 11:02
閱讀 4244·2023-01-11 11:02
閱讀 3050·2023-01-11 11:02
閱讀 5180·2023-01-11 11:02
閱讀 4737·2023-01-11 11:02
閱讀 5534·2023-01-11 11:02
閱讀 5313·2023-01-11 11:02
閱讀 3990·2023-01-11 11:02