服務網(wǎng)關作為分布式系統(tǒng)對外服務的統(tǒng)一入口,設計功能上具有路由轉(zhuǎn)發(fā)、熔斷限流、安全認證以及監(jiān)控等功能。本文簡要介紹服務網(wǎng)關的基本概念,以及動態(tài)路由的實現(xiàn)方式,以加深了解。
1、什么是分布式服務網(wǎng)關
1.1 服務網(wǎng)關的基本概念
網(wǎng)關是客戶端訪問系統(tǒng)請求及系統(tǒng)響應所要經(jīng)過的網(wǎng)絡關口,網(wǎng)關封裝了系統(tǒng)內(nèi)部功能架構,為每個客戶端訪問提供不同的接口。網(wǎng)關在功能上主要是進行請求過濾,具體包括請求路由轉(zhuǎn)發(fā)、安全認證、流量控制、負載均衡、日志、監(jiān)控等功能。
在分布式系統(tǒng)尤其是微服務架構中,一個應用系統(tǒng)被拆分為多個服務,但是像路由請求、安全認證、流量控制、日志和監(jiān)控等功能對每個服務來說都是標準的功能模塊。如果沒有服務網(wǎng)關,那么每個服務就需要單獨實現(xiàn)一套這樣的模塊,功能重復并且不利于統(tǒng)一管理。另外,多個微服務可能部署在不同的服務器上,傳統(tǒng)的直接訪問應用服務的方式增加了客戶端的復雜度,因此需要一個統(tǒng)一的客戶端訪問入口進行標準化管理。
1.2 服務網(wǎng)關的作用及功能
服務網(wǎng)關作為客戶端請求的統(tǒng)一入口,具備以下功能:
- 動態(tài)路由 :根據(jù)請求路由到對應的服務上去,如果服務不可用還會有重試機制
- 負載均衡 :多服務器提供同一種服務,網(wǎng)關會從配置中心拉取各服務注冊信息,然后將請求負載到這些服務器進行處理
- 流量控制 :限制并發(fā)請求的流量,避免內(nèi)部系統(tǒng)受到?jīng)_擊
- 安全認證 :網(wǎng)關對相關權限驗證、脫敏和流量清洗、簽名和黑名單功能
- 熔斷降級 :當服務不可用或者訪問量過大,網(wǎng)關可以將請求做降級,將流量打到其他服務器或者做其他處理,提示用戶暫時不可用
- 灰度發(fā)布 :先進行小部分服務器升級,通過網(wǎng)關將少量的服務路由到已升級的服務器用來測試服務是否正常,大部分請求依舊在老版本服務器上處理
- 日志服務 :服務訪問情況監(jiān)控和統(tǒng)計報表,請求的吞吐量、并發(fā)數(shù)、流量監(jiān)控、性能監(jiān)控和日常告警等
1.3 常見的分布式服務網(wǎng)關
常見的分布式服務網(wǎng)關有以下幾種:
- Nginx+Lua :基于Nginx的服務端網(wǎng)關方案,實現(xiàn)web服務器、反向代理、負載均衡、動靜分離等功能;
- Kong :基于OpenResty實現(xiàn),是一款高性能、云原生、可擴展的網(wǎng)關系統(tǒng);
- SpringCloud Zuul :基于Netty實現(xiàn)了異步IO,可自定義過濾器來處理請求,同時提供了動態(tài)路由、監(jiān)控、彈性負載和安全功能
- SpringCloud Gateway :基于Spring WebFlux,提供統(tǒng)一的路由方式,并且基于Filter鏈的方式提供了網(wǎng)關的基本功能,如安全、限流、監(jiān)控等
1.3.1 Nginx+Lua實現(xiàn)
在《簡單聊聊Nginx實現(xiàn)原理》中對Nginx的功能做了簡單的介紹,可以實現(xiàn)反向代理、負載均衡、動靜分離等功能。
1.3.2 Kong
Kong基于OpenResty實現(xiàn) ,OpenResty是基于Nginx的庫,它將Nginx進行封裝,使用Lua腳本就可以對Nginx進行插件化管理。
- 使用PostgreSQL或Cassandra來對其配置文件進行持久化存儲,使得可以進行集群管理
- 提供了插件模型,使用 Lua腳本來對Nginx整個生命周期進行擴展 。實現(xiàn)了一些常用插件( 限流、熔斷、驗權等 )
- 提供了Http/Rest的接口來實現(xiàn)配置,使得其可以更簡單的構建圖形化界面進行動態(tài)配置
1.3.3 Spring Cloud Zuul
Zuul是來自Netflix的基于JVM的路由器和服務器端負載均衡器,為微服務架構提供了前門保護的作用,同時將權限控制這些較重的非業(yè)務邏輯內(nèi)容遷移到服務路由層面,使得服務集群主體能夠具備更高的可復用性和可測試性。官方定義如下:
Zuul是在云平臺上提供動態(tài)路由,監(jiān)控,彈性,安全等邊緣服務的框架。Zuul 相當于是設備和 Netflix 流應用的 Web 網(wǎng)站后端所有請求的前門。即Zuul為微服務集群提供代理、過濾和路由等功能。
Zuul會把外部的請求過程分為不同階段,每個階段提供一系列的過濾器。這些過濾器實現(xiàn)了以下功能:
- 身份驗證和安全性 :對需要身份驗證的資源進行過濾,拒絕處理不符合身份認證的請求。
- 觀察和監(jiān)控 :跟蹤重要的數(shù)據(jù),為我們展示準確的請求狀況
- 動態(tài)路由 :將請求動態(tài)路由到不同的服務集群
- 負載均衡 :設置每種請求的處理能力,刪除那些超出限制的請求
- 靜態(tài)響應處理 :提供靜態(tài)的過濾器,直接響應一些請求,而不將它們轉(zhuǎn)發(fā)到集群內(nèi)部
- 路由多樣化 :除了將請求路由到Spring Cloud集群內(nèi)部,還可以將請求路由到其他服務
Zuul的 核心原理是一系列filters ,在請求路由合并到用戶處理邏輯的過程中,這些過濾器參與驗證、加載等過濾處理。zul定義了四種標準過濾器類型,用于請求的典型生命周期。
- PRE:這樣的過濾器在請求被路由之前被調(diào)用 ??梢岳眠@樣的過濾器實現(xiàn)認證,選擇集群內(nèi)要求的微服務器,記錄調(diào)試信息。
- ROUTING:該過濾器將請求路由到微服務 。此過濾器用于生成發(fā)送到微服務的請求,并使用Apachehttp客戶端或Netfilx Ribbon請求微服務。
- POST:在路由到微服務之后執(zhí)行該過濾器 。使用此過濾器可以將標準HTTP Header添加到響應中,收集統(tǒng)計信息和指標,以及將響應從微服務器發(fā)送到客戶端。
- ERROR:如果在其他階段發(fā)生錯誤 ,則執(zhí)行該過濾器。
1.3.4 Spring Cloud Gateway
Spring Cloud Gateway是Spring官方基于Spring5.0,Spring Boot2.0和Project Reactor等技術開發(fā)的網(wǎng)關,Spring Cloud Gateway旨在為微服務架構提供簡單,有效且統(tǒng)一的API路由管理方式。 Spring Cloud Gateway作為Spring Cloud 生態(tài)系統(tǒng)中的網(wǎng)關 ,目標是替代Netflix Zuul,其不僅提供統(tǒng)一的路由方式,并且還基于Filter鏈的方式提供了網(wǎng)關基本的功能,例如:安全,監(jiān)控、埋點,限流等。
1)Spring Cloud Gateway特性
- 基于Spring Framework 5、Reactor和Spring Boot 2.0框架。
- 根據(jù)請求的屬性可以匹配對應的路由。
- 集成Hystrix。
- 集成Spring Cloud DiscoveryClient。
- 把易于編寫的Predicates和Filters作用于特定路由。
- 具備一些網(wǎng)關的高級功能,如動態(tài)路由、限流、路徑重寫。
2)Spring Cloud Gateway核心概念
- Filter(過濾器) :和Zuul的過濾器在概念上類似,可以使用Filter攔截和修改請求,實現(xiàn)對上游的響應,進行二次處理,實現(xiàn)橫切與應用無關的功能,如安全、訪問超時設置、限流等功能。
- Route(路由) :網(wǎng)關配置的基本組成模塊,和Zuul的路由配置模塊類似。一個Route模塊由一個ID、一個目標URI、一組斷言和一組過濾器組成。如果斷言為真,則路由匹配,目標URI會被訪問。
- Predicate(斷言) :Predicate來自Java 8的接口,它可以用來匹配來自HTTP請求的任何內(nèi)容,例如headers或參數(shù)。接口包含多種默認方法,并將Predicate組合成復雜的邏輯(與、或、非),可以用于接口參數(shù)校驗、路由轉(zhuǎn)發(fā)判斷等。
3)Spring Cloud Gateway核心處理流程
- Gateway的客戶端回向Spring Cloud Gateway發(fā)起請求
- 請求首先會被HttpWebHandlerAdapter進行 提取組裝成網(wǎng)關的上下文 ,然后網(wǎng)關的上下文會傳遞到DispatcherHandler。
- DispatcherHandler是所有請求的分發(fā)處理器,DispatcherHandler主要 負責分發(fā)請求對應的處理器 ,比如將請求分發(fā)到對應RoutePredicateHandlerMapping(路由斷言處理器映射器)。
- 路由斷言處理映射器 主要用于路由的查找 ,以及找到路由后返回對應的FilteringWebHandler。
- FilteringWebHandler主要 負責組裝Filter鏈表并調(diào)用Filter執(zhí)行一系列Filter處理 ,然后把請求轉(zhuǎn)到后端對應的代理服務處理,
- 處理完畢后,將Response 返回到Gateway客戶端 。
1.3.5 Zuul和Gateway對比
Spring cloud Zuul和Spring Cloud Gateway處理的都是http請求,底層是serverlet服務。不同之處有以下幾點:
- 內(nèi)部實現(xiàn)
- gateway對比zuul多依賴了spring-webflux,在spring的支持下,功能更強大,內(nèi)部實現(xiàn)了限流、負載均衡等,擴展性也更強,但同時也限制了僅適合于Spring Cloud套件
- zuul則可以擴展至其他微服務框架中,其內(nèi)部沒有實現(xiàn)限流、負載均衡等
- 是否支持異步
- Zuul 1.x只支持同步。Zuul 2.x基于Netty實現(xiàn)了異步IO
- Gateway支持異步。 理論上gateway則更適合于提高系統(tǒng)吞吐量(但不一定能有更好的性能),最終性能還需要通過嚴密的壓測來決定
- 擴展性
- Gateway具有更好的擴展性,穩(wěn)定性也是非常好的
- 性能
- Spring webflux 有一個全新的非堵塞的函數(shù)式 Reactive Web 框架,可以用來構建異步的、非堵塞的、事件驅(qū)動的服務,在伸縮性方面表現(xiàn)非常好
- Zuul 1.x,是一個基于阻塞io的API Gateway。Zuul已經(jīng)發(fā)布了Zuul 2.x,基于Netty,也是非阻塞的,支持長連接,但Spring Cloud暫時還沒有整合計劃
在實際生產(chǎn)使用中,Zuul 1.x雖然使用的是同步io,但是可以通過參數(shù)優(yōu)化提高性能理論上可以達到極限性能,而springcloud gateway使用的是異步io,不需優(yōu)化既可以達到接近極限的性能。
2、分布式網(wǎng)關動態(tài)路由實現(xiàn)
相比較靜態(tài)路由,動態(tài)路由的好處是對路由配置的修改、新增或者刪除,可以動態(tài)生效,不需要重啟網(wǎng)關服務。這里主要介紹 基于Spring Cloud Gateway的動態(tài)路由幾種實現(xiàn)方式 ,包括:
- 基于Nacos
- 基于數(shù)據(jù)庫
- 基于內(nèi)存
2.1 基于Nacos的動態(tài)路由
Nacos集成在Spring Cloud中,提供了快速實現(xiàn)動態(tài)服務發(fā)現(xiàn)、服務配置、服務元數(shù)據(jù)及流量管理等功能。基于Nacos動態(tài)路由是通過Nacos更新修改路由配置,通過接口調(diào)用動態(tài)更新到本地緩存中。
1)加載配置和監(jiān)聽路由
configInfo = configService.getConfig(NACOS_ROUTE_DATA_ID, NACOS_ROUTE_GROUP, DEFAULT_TIMEOUT);
configService.addListener(dataId, group, new Listener()
2)路由的動態(tài)添加和刪除
routeDefinitionWriter.delete(Mono.just(id)).subscribe()
routeDefinitionWriter.save(Mono.just(definition)).subscribe();
3)路由信息刷新到本地緩存
publisher.publishEvent(new RefreshRoutesEvent(this));
2.2 基于數(shù)據(jù)庫的動態(tài)路由
基于數(shù)據(jù)庫的動態(tài)路由實現(xiàn),是 將路由信息寫入數(shù)據(jù)庫中 ,再通過接口讀取路由配置信息以及更新路由信息,最后刷新到本地緩存中。
2.3 基于內(nèi)存的動態(tài)路由
基于本地內(nèi)存的方式比較簡單,Spring Boot已經(jīng)提供了兩個組件Spring Boot Admin和Spring Boot Actuator。 通過調(diào)用接口更新路由信息,再刷新即可完成路由更新 。
o.s.c.g.a.GatewayControllerEndpoint:
{GET /routes/{id}}: route(String)
{GET /routes}: routes()
{GET /routedefinitions}: routesdef()
{GET /globalfilters}: globalfilters()
{GET /routefilters}: routefilers()
{GET /routepredicates}: routepredicates()
{GET /routes/{id}/combinedfilters}: combinedfilters(String)
{DELETE /routes/{id}}: delete(String)
{POST /routes/{id}}: save(String,RouteDefinition)
{POST /refresh}: refresh()
-
網(wǎng)關
+關注
關注
9文章
6164瀏覽量
54736 -
路由
+關注
關注
0文章
282瀏覽量
43339
發(fā)布評論請先 登錄
分布式軟件系統(tǒng)
如何設計分布式干擾系統(tǒng)?
分布式系統(tǒng)的優(yōu)勢是什么?
HarmonyOS應用開發(fā)-分布式設計
如何高效完成HarmonyOS分布式應用測試?
分布式軟總線實現(xiàn)近場設備間統(tǒng)一的分布式通信管理能力如何?
基于ZigBee的分布式井蓋監(jiān)控系統(tǒng)
F0rCES路由器分布式事務研究

基于Dijkstra算法的分布式電能路由策略的實現(xiàn)

分布式無紙化交互系統(tǒng)的實現(xiàn)原理
springcloud如何實現(xiàn)分布式
如何實現(xiàn)Redis分布式鎖
分布式鎖的三種實現(xiàn)方式
Redis實現(xiàn)分布式多規(guī)則限流的方式介紹

評論