1. 程式人生 > >微服務 - 服務網關

微服務 - 服務網關

回調方法 並不是 聚合 屬於 例如 rift 兩個 rod llb

客戶端直接訪問微服務帶來的問題

1、客戶端的需求量與每個微服務暴露的細粒度API數量的不匹配。

2、亞馬遜的產品最終頁要請求數百個微服務。雖然一個客戶端可以通過LAN發起很多個請求,但是在公網上這樣會很沒有效率,這個問題在移動互聯網上尤為突出。這個方案同時會導致客戶端代碼非常復雜。

3、另一個存在的問題是客戶端直接請求微服務的協議可能並不是web友好型。一個服務可能是用Thrift的RPC協議,而另一個服務可能是用AMQP消息協議。它們都不是瀏覽或防火墻友好的,並且最好是內部使用。應用應該在防火墻外采用類似HTTP或者WEBSocket協議。

4、另一個缺點是它很難重構微服務。隨著時間的推移,我們可能需要改變系統微服務目前的切分方案。例如,我們可能需要將兩個服務合並或者將一個服務拆分為多個。但是,如果客戶端直接與微服務交互,那麽這種重構就很難實施。

由於上述問題的原因,客戶端直接與服務器端通信的方式很少在實際中使用。

使用API Gateway

API Gateway是一個服務器,也可以說是進入系統的唯一節點。這跟面向對象設計模式中的Facet模式很像。API Gateway封裝內部系統的架構,並且提供API給各個客戶端。它還可能有其他功能,如授權、監控、負載均衡、緩存、請求分片和管理、靜態響應處理等。

API Gateway負責請求轉發、合成和協議轉換。所有來自客戶端的請求都要先經過API Gateway,然後路由這些請求到對應的微服務。API Gateway將經常通過調用多個微服務來處理一個請求以及聚合多個服務的結果。它可以在web協議與內部使用的非Web友好型協議間進行轉換,如HTTP協議、WebSocket協議。

API Gateway可以提供給客戶端一個定制化的API。它暴露一個粗粒度API給移動客戶端。以產品最終頁這個使用場景為例。API Gateway提供一個服務提供點(/productdetails?productid=xxx)使得移動客戶端可以在一個請求中檢索到產品最終頁的全部數據。API Gateway通過調用多個服務來處理這一個請求並返回結果,涉及產品信息、推薦、評論等。

API Gateway的優點和缺點

API Gateway的一個最大好處是封裝應用內部結構。相比起來調用指定的服務,客戶端直接跟gatway交互更簡單點。API Gateway提供給每一個客戶端一個特定API,這樣減少了客戶端與服務器端的通信次數,也簡化了客戶端代碼。 API Gateway也有一些缺點。它是一個高可用的組件,必須要開發、部署和管理。還有一個問題,它可能成為開發的一個瓶頸。開發者必須更新API Gateway來提供新服務提供點來支持新暴露的微服務。更新API Gateway時必須越輕量級越好。否則,開發者將因為更新Gateway而排隊列。但是,除了這些缺點,對於大部分的應用,采用API Gateway的方式都是有效的。

實現一個API Gateway 需要考慮哪些

性能和可擴展性 只有少數公司需要處理像Netflix那樣的規模,每天需要處理數十億的請求。但是,對於大多數應用,API Gateway的性能和可擴展性也是非常重要的。因此,創建一個支持同步、非阻塞I/O的API Gateway是有意義的。已經有不同的技術可以用來實現一個可擴展的API Gateway。在JVM上,采用基於NIO技術的框架,如Netty,Vertx,Spring Reactor或者JBoss Undertow。Node.js是一個非JVM的流行平臺,它是一個在Chrome的JavaScript引擎基礎上建立的平臺。一個可選的方案是NGINX Plus。NGINX Plus提供一個成熟的、可擴展的、高性能web服務器和反向代理,它們均容易部署、配置和二次開發。NGINX Plus可以管理授權、權限控制、負載均衡、緩存並提供應用健康檢查和監控。 采用反應性編程模型

對於有些請求,API Gateway可以通過直接路由請求到對應的後端服務上的方式來處理。對於另外一些請求,它需要調用多個後端服務並合並結果來處理。對於一些請求,例如產品最終頁面請求,發給後端服務的請求是相互獨立的。為了最小化響應時間,API Gateway應該並發的處理相互獨立的請求。但是,有時候請求之間是有依賴的。API Gateway可能需要先通過授權服務來驗證請求,然後在路由到後端服務。類似的,為了獲得客戶的產品願望清單,需要先獲取該用戶的資料,然後返回清單上產品的信息。這樣的一個API 組件是Netflix Video Grid

利用傳統的同步回調方法來實現API合並的代碼會使得你進入回調函數的噩夢中。這種代碼將非常難度且難以維護。一個優雅的解決方案是采用反應性編程模式來實現。類似的反應抽象實現有Scala的Future,Java8的CompletableFuture和JavaScript的Promise。基於微軟.Net平臺的有Reactive Extensions(Rx)。Netflix為JVM環境創建了RxJava來使用他們的API Gateway。同樣地,JavaScript平臺有RxJS,可以在瀏覽器和Node.js平臺上運行。采用反應編程方法可以幫助快速實現一個高效的API Gateway代碼。

服務調用

一個基於微服務的應用是一個分布式系統,並且必須采用線程間通信的機制。有兩種線程間通信的方法。一種是采用同步機制,基於消息的方法。這類的實現方法有JMS和AMQP。另外的,例如Zeromq屬於服務間直接通信。還有一種線程間通信采用異步機制,例如Thrift和HTTP。事實上一個系統會同時采用同步和異步兩種機制。由於它的實現方式有很多種,因此API Gateway就需要支持多種通信方式。

服務發現

API Gateway需要知道每一個微服務的IP和端口。在傳統應用中,你可能會硬編碼這些地址,但是在現在雲基礎的微服務應用中,這將是個簡單的問題。基礎服務通常會采用靜態地址,可以采用操作系統環境變量來指定。但是,探測應用服務的地址就沒那麽容易了。應用服務通常動態分配地址和端口。同樣的,由於擴展或者升級,服務的實例也會動態的改變。因此,API Gateway需要采用系統的服務發現機制,要麽采用服務端發現,要麽是客戶端發現。後續的一篇文章將會更詳細的介紹這部分。如果采用客戶端發現服務,API Gateway必須要去查詢服務註冊處,也就是微服務實例地址的數據庫。

處理部分失敗

在實現API Gateway過程中,另外一個需要考慮的問題就是部分失敗。這個問題發生在分布式系統中當一個服務調用另外一個服務超時或者不可用的情況。API Gateway不應該被阻斷並處於無限期等待下遊服務的狀態。但是,如何處理這種失敗依賴於特定的場景和具體服務。例如,如果是在產品詳情頁的推薦服務模塊無響應,那麽API Gateway應該返回剩下的其他信息給用戶,因為這些信息也是有用的。推薦部分可以返回空,也可以返回固定的頂部10個給用戶。但是,如果是產品信息服務無響應,那麽API Gateway就應該給客戶端返回一個錯誤。

在緩存有效的時候,API Gateway應該能夠返回緩存。例如,由於產品價格變化並不頻繁,API Gateway在價格服務不可用時應該返回緩存中的數值。這類數據可以由API Gateway自身來緩存,也可以由Redis或Memcached這類外部緩存實現。通過返回緩存數據或者默認數據,API Gateway來確保系統錯誤不影響到用戶體驗。

Netflix Hystrix對於實現遠程服務調用代碼來說是一個非常好用的庫。Hystrix記錄那些超過預設定的極限值的調用。它實現了circuit break模式,使得可以將客戶端從無響應服務的無盡等待中停止。如果一個服務的錯誤率超過預設值,Hystrix將中斷服務,並且在一段時間內所有請求立刻失效。Hystrix可以為請求失敗定義一個fallback操作,例如讀取緩存或者返回默認值。如果你在用JVM,就應該考慮使用Hystrix。如果你采用的非JVM環境,那麽應該考慮采用類似功能的庫。

總結

對於大多數微服務基礎的應用,實現一個API Gateway都是有意義的,它就像是進入系統的一個服務提供點。API Gateway負責請求轉發、請求合成和協議轉換。它提供給應用客戶端一個自定義的API。API Gateway可以通過返回緩存或者默認值的方式來掩蓋後端服務的錯誤。

實踐

API Gateway 實現請求轉發、合成、協議轉換

鏈接

微服務實戰(二):構建微服務:使用API Gateway

微服務 - 服務網關