1. 程式人生 > >微服務閘道器解決方案和使用總結

微服務閘道器解決方案和使用總結

一.什麼是閘道器

1.1 什麼是閘道器

API Gateway(APIGW / API 閘道器),顧名思義,是出現在系統邊界上的一個面向API的、序列集中式的強管控服務,這裡的邊界是企業IT系統的邊界,可以理解為企業級應用防火牆,主要起到隔離外部訪問與內部系統的作用。在微服務概念的流行之前,API閘道器就已經誕生了,例如銀行、證券等領域常見的前置機系統,它也是解決訪問認證、報文轉換、訪問統計等問題的。API閘道器的流行,源於近幾年來,移動應用與企業間互聯需求的興起。移動應用、企業互聯,使得後臺服務支援的物件,從以前單一的Web應用,擴充套件到多種使用場景,且每種使用場景對後臺服務的要求都不盡相同。這不僅增加了後臺服務的響應量,還增加了後臺服務的複雜性。

隨著微服務架構概念的提出,API閘道器成為了微服務架構的一個標配元件

1.2 閘道器應該具有的功能

如上圖所示:閘道器該具備的最基本的四大功能:統一接入,流量管控,協議適配轉發,安全防護。

二.目前閘道器解決方案

2.1 Nginx+ Lua

Nginx是由IgorSysoev為俄羅斯訪問量第二的Rambler.ru站點開發的,一個高效能的HTTP和反向代理伺服器。Ngnix一方面可以做反向代理,另外一方面做可以做靜態資源伺服器。

但是準確的來說,在我看來,這種方案不是真正意義上的閘道器,而且即使自研閘道器的目標也是幹掉Ngnix。

2.2 Kong

Kong是Mashape提供的一款API管理軟體,它本身是基於Ngnix+lua的,但比nginx提供了更簡單的配置方式,資料採用了 ApacheCassandra/PostgreSQL儲存,並且提供了一些優秀的外掛,比如驗證,日誌,呼叫頻次限制等。
Kong的一個非常誘人的地方就是提供了大量的外掛來擴充套件應用,通過設定不同的外掛可以為服務提供各種增強的功能。Kong預設外掛外掛包括:

身份認證:Kong提供了Basic Authentication、Key authentication、OAuth2.0authentication、HMAC authentication、JWT、LDAP authentication認證實現。

安全:ACL(訪問控制)、CORS(跨域資源共享)、動態SSL、IP限制、爬蟲檢測實現。

流量控制:請求限流(基於請求計數限流)、上游響應限流(根據upstream響應計數限流)、請求大小限制。限流支援本地、Redis和叢集限流模式。

分析監控:Galileo(記錄請求和響應資料,實現API分析)、Datadog(記錄API Metric如請求次數、請求大小、響應狀態和延遲,視覺化API Metric)、Runscope(記錄請求和響應資料,實現API效能測試和監控)。

轉換:請求轉換、響應轉換

優點:Kong本身也是基於Nginx的,所以在效能和穩定性上都沒有問題。Kong作為一款商業軟體,在Nginx上做了很擴充套件工作,而且還有很多付費的商業外掛。Kong本身也有付費的企業版,其中包括技術支援、使用培訓服務以及API 分析外掛。

缺點:Kong的缺點就是,如果你使用Spring Cloud,Kong如何結合目前已有的服務治理體系?

2.3 Spring Cloud Zuul

Zuul 是Netflix公司開源的一個API閘道器元件,Spring Cloud對其進行二次基於Spring Boot的註解式封裝做到開箱即用。目前來說,結合Sring Cloud提供的服務治理體系,可以做到請求轉發,根據配置的或者預設的路由規則進行路由和Load Balance,整合Hystrix。詳細可以參考Spring Cloud Zuul的URL轉發和路由規則。

Spring Cloud Zuul處理每個請求的方式是針對每個請求是用一個執行緒來處理。PS,根據統計資料目前Zuul最多能達到(1000-2000)QPS。使用過Netty的都知道,一般都會使用Boos組和work組,通常情況下,為了提高效能,所有請求會被放到處理佇列中,從執行緒池中選取空閒執行緒來處理該請求。

Spring Cloud Zuul需要做一些灰度,降級,標籤路由,限流,WAF封禁,需要自定義Filter去或者做一些定製化實現。詳細文章可以參考在Spring Cloud中實現降級之權重路由和標籤路由

雖然可以通過自定義Filter實現,我們想要的功能,但是由於Zuul本身的設計和基於單執行緒的接收請求和轉發處理,在我看來目前來看Zuul 就顯得很雞肋,隨著Zuul2一直跳票,Spring Cloud推出自己的Spring Cloud Gateway.

The API Gateway is Dead! Long Live the API Gateway!

大意:Zuul已死,Spring Cloud Gateway永生。

2.4 Spring Cloud Gateway

A Gateway built on Spring Framework 5.0 and Spring Boot 2.0 providing routing and more。

Spring Cloud Gateway是基於Spring 框架5.0版本和Spring Boot 2.0的版本構建,提供路由等功能。

Spring Cloud GateWay具有以下特徵

  • Java 8/Spring 5/Boot 2

  • WebFlux/Reactor

  • HTTP/2 and Websockets

  • Finchley Release Train (Q4 2017)

由於Spring 5.0支援Netty,Http2,而Spring Boot 2.0支援Spring 5.0,因此Spring Cloud Gateway支援Netty和Http2順理成章。至於2017年Q4季度是否釋出完整的Spring Cloud Gateway我們拭目以待,但是至於最終落地看最終使用情況

詳細資訊可以參考:Spring Cloud Gateway離開孵化器的變化

2.5 Kong+Zuul的閘道器方案

如上圖所示:Kong+Zuul實現的閘道器方案,在加上阿里雲的SLB,整個呼叫鏈路多了好幾層,為什麼要這麼做呢?發揮Kong+Spring Cloud Zuul各自的優點形成“聚合閘道器”。個人不建議這樣使用閘道器,因此自研閘道器中介軟體,顯得尤其重要。

三.基於Spring Cloud Zuul構建閘道器

用Spring Cloud Zuul構建閘道器其實相當雞肋,比如動態Filter,比如標籤路由,降級,比如動態Filter,比如帶管控審計流程,易操作的UI介面等。

zuul是netfix的api 閘道器,主要特色有:filter的PRPE(pre,route,post,error)模型、groovy的fitler機制,其中spring cloud對其有比較好的擴充套件,但是spring cloud對其的擴充套件感覺不是很完美,存在路由規則無法只能是通過配置檔案來儲存,而無法動態配置的目的,其中有一個人寫了一個starter外掛來解決路由規則配置到Cassandra的問題,詳細請看:將路由規則配置到KV分散式儲存系統Cassandra

3.1 定義自己的Filter機制

這裡主要是做了流控及協議轉化的工作,這裡主要是http->grpc的轉換;
LimitAccessFilter:利用redis令牌桶演算法進行流控
GrpcRemoteRouteFilter:http轉化為grpc的協議轉換

3.2 路由資料變更基於事件通知路由規則重新整理

實現動態路由有兩種實現方式:
1.第一是DiscoveryClientRouteLocator的重新覆蓋,推薦是,Spring Cloud整合GRPC,REST協議適配轉發為內部GRPC服務時採用此種方法擴充套件修改。

2.第二是實現了RefreshableRouteLocator介面,能夠實現動態重新整理,可以參考 spring cloud Zuul動態路由

3.2.1 基於事件更新原始碼分析

為什麼要基於事件更新,原理如下所示:
在org.springframework.cloud.netflix.zuul.ZuulConfiguration.java中228-250行

如上所示,當使用ApplicationEventPublisher傳送的Event為ContextRefreshedEvent,RefreshScopeRefreshedEvent,RoutesRefreshedEvent才會通知Zuul去重新整理路由。

3.3 基於事件更新實現方式處理方式-DiscoveryClientRouteLocator

3.3.1 處理思路

此外掛針對的spring cloud zuul版本比較老,因此需要對其進行改進,將路由配置可以配置到mysql這樣的關係型資料庫中。

3.3.2 對DiscoveryClientRouteLocator的重新覆蓋

對DiscoveryClientRouteLocator的重新覆蓋,該類的作用就是從yml或屬性檔案中讀取路由規則;
具體參看原始碼org.springframework.cloud.netflix.zuul.filters.discovery.DiscoveryClientRouteLocator,主要方法如下,淺顯易懂,就不做多餘解釋。

3.3.3 生產者產生事件通知

資料變更對閘道器的穩定性來說,也是一個很大的挑戰。當對路由資訊進行CRUD操作之後,需要Spring Cloud Zuul重新重新整理路由規則,實現方式通過spring的event來實現。

1.實現基於ApplicationEventPublisherAware的事件生產者的程式碼片段

private ApplicationEventPublisher publisher;
publisher.publishEvent(new InstanceRegisteredEvent<>(this, this.environment));

2.Spring Cloud netflix內部的事件消費者

org.springframework.cloud.netflix.zuul.RoutesRefreshedEvent

@SuppressWarnings("serial")
public class RoutesRefreshedEvent extends ApplicationEvent {    
private RouteLocator locator;    
public RoutesRefreshedEvent(RouteLocator locator) {     super(locator);        
   this.locator = locator; }    
public RouteLocator getLocator() {        
   return this.locator; } }
四.基於Spring Cloud Gateway構建閘道器

由於Spring Cloud Gateway未完全成熟,而且效能,穩定性等,現在無從考證,沒有使用案例,基於Spring Cloud Gateway方案構建自己的閘道器風險比較大,而且PS不知道到年底是否成熟可用。故在這裡不做過多說明。

五.基於Netty自研閘道器中介軟體

5.1 架構圖

可以參考架構圖如下:

5.2 設計原則

  • 1.每個Filter基於責任鏈,只做專一的一件事

  • 2.每個Filter有各自獨立的資料

  • 3.損耗效能的Filter順序往後放

  • 4.啟動讀取配置順序,先遠端,若遠端失敗,則讀取本地。

  • 5.叢集閘道器,要注意資料的diff和灰度

  • 6.儘量做到和服務治理框架解耦,易於接入,易於升級

來源:

http://www.cnblogs.com/softidea/p/7261095.html