隨著微服務的不斷增多,不同的微服務一般會有不同的網路地址,而外部客戶端可能需要呼叫多個服務的接口才能完成一個業務需求,如果讓客戶端直接與各個微服務通訊可能出現:
客戶端會多次請求不同的微服務,增加了客戶端的複雜性存在跨域請求,在一定場景下處理相對複雜身份認證問題,每個微服務需要獨立身份認證難以重構,隨著專案的迭代,可能需要重新劃分微服務某些微服務可能使用了防火牆/瀏覽器不友好的協議,直接訪問會有一定的困難針對這些問題,API閘道器順勢而生。
API 閘道器直面意思是將所有 API 呼叫統一接入到 API 閘道器層,由閘道器層統一接入和輸出。一個閘道器的基本功能有:統一接入、安全防護、協議適配、流量管控、長短連線支援、容錯能力。有了閘道器之後,各個 API 服務提供團隊可以專注於自己的的業務邏輯處理,而 API 閘道器更專注於安全、流量、路由等問題。
服務呼叫在微服務架構中,通常存在多個服務之間的遠端呼叫的需求。目前主流的遠端呼叫技術有基於 HTTP 的 RESTful 介面和基於 TCP 的 RPC 協議。以上兩種都屬於同步通訊,還有基於佇列模式的非同步通訊。
REST(Representational State Transfer):一種 HTTP 呼叫的格式,更標準,更通用,無論哪種語言都支援 http 協議。RPC(Remote Promote Call):一種程序間通訊方式,允許像呼叫本地服務一樣呼叫遠端服務。RPC 框架的主要目標就是讓遠端服務呼叫更簡單、透明。RPC 框架負責遮蔽底層的傳輸方式、序列化方式和通訊細節。開發人員在使用的時候只需要瞭解誰在什麼位置提供了什麼樣的遠端服務介面即可,並不需要關心底層通訊細節和呼叫過程。比較項RESTRPC通訊協議HTTP一般使用 TCP效能略低較高靈活度高低應用微服務架構SOA 架構
服務治理服務治理就是進行服務的自動化管理,其核心是服務的自動註冊與發現。
服務註冊:服務例項將自身服務資訊註冊到註冊中心。服務發現:服務例項透過註冊中心,獲取註冊到其中的服務例項的資訊,透過這些資訊去請求它們提供的服務。服務剔除:服務註冊中心將出問題的服務自動剔除到可用列表之外,使其不會被呼叫到。負載均衡服務高可用的保證手段,為了保證高可用,每一個微服務都需要部署多個服務例項來提供服務,此時就需要根據不同的負載均衡策略對服務進行呼叫。
負載均衡策略輪詢策略實現原理:輪詢策略表示每次都順序取下一個 provider,比如一共有 5 個 provider,第 1 次取第 1 個,第 2 次取第 2 個,第 3 次取第 3 個,以此類推。
權重輪詢策略實現原理:
根據每個 provider 的響應時間分配一個權重,響應時間越長,權重越小,被選中的可能性越低。原理:一開始為輪詢策略,並開啟一個計時器,每 30 秒收集一次每個 provider 的平均響應時間,當資訊足夠時,給每個 provider 附上一個權重,並按權重隨機選擇 provider,高權越重的 provider 會被高機率選中。隨機策略實現原理:從 provider 列表中隨機選擇一個。
最少併發數策略實現原理:選擇正在請求中的併發數最小的 provider,除非這個 provider 在熔斷中。
重試策略實現原理:其實就是輪詢策略的增強版,輪詢策略服務不可用時不做處理,重試策略服務不可用時會重新嘗試叢集中的其他節點。
可用性敏感策略實現原理:過濾效能差的 provider
第一種:過濾掉在 Eureka 中處於一直連線失敗的 provider。第二種:過濾掉高併發(繁忙)的 provider。區域敏感性策略實現原理:
以一個區域為單位考察可用性,對於不可用的區域整個丟棄,從剩下區域中選可用的 provider。如果這個 ip 區域內有一個或多個例項不可達或響應變慢,都會降低該 ip 區域內其他 ip 被選中的權 重。服務容錯在微服務中,一個請求經常會涉及到呼叫多個服務,如果其中某個服務不可用,沒有做服務容錯的話,極有可能會造成一連串的服務不可用,這就是雪崩效應。最終的結果就是:一個服務不可用,導致一系列服務的不可用。
造成雪崩的原因可以歸結為以下三點:
服務提供者不可用(硬體故障,程式 BUG,快取擊穿,使用者大量請求等)重試加大流量(使用者重試,程式碼邏輯重試)服務消費者不可用(同步等待造成的資源耗盡)我們沒法預防雪崩效應的發生,只能儘可能去做好容錯。服務容錯的三個核心思想是:
不被外界環境影響不被上游請求壓垮不被下游響應拖垮鏈路追蹤隨著微服務架構的流行,服務按照不同的維度進行拆分,一次請求往往需要涉及到多個服務。網際網路應用構建在不同的軟體模組集上,這些軟體模組,有可能是由不同的團隊開發、可能使用不同的程式語言來實現、有可能布在了幾千臺伺服器,橫跨多個不同的資料中心。因此,就需要對一次請求涉及的多個服務鏈路進行日誌記錄,效能監控等等。單純的理解鏈路追蹤,就是指一次任務的開始到結束,期間呼叫的所有系統及耗時(時間跨度)都可以完整記錄下來。
鏈路追蹤系統做好了,鏈路資料有了,藉助前端解析和渲染工具,可以達到下圖中的效果:
配置中心配置檔案是我們再熟悉不過的,在微服務系統中,每個微服務不僅僅只有程式碼,還需要連線其他資源,例如資料庫的配置或功能性的開關 MySQL、Redis 、Security 等相關的配置。除了專案執行的基礎配置之外,還有一些配置是與我們業務有關係的,比如說七牛儲存、簡訊和郵件相關,或者一些業務上的開關。
但是隨著微服務系統的不斷迭代,整個微服務系統可能會成為一個網狀結構,這個時候就要考慮整個微服務系統的擴充套件性、伸縮性、耦合性等等。其中一個很重要的環節就是配置管理的問題。
常規配置管理解決方案缺點:
硬編碼(需要修改程式碼、繁瑣、風險大)properties 或者 yml(叢集環境下需要替換和重啟)xml(重新打包和重啟)由於常規配置管理有很大的缺點,所以採用 Spring Cloud Config 或 Consul 或 Apollo 或 Nacos 等配置中心集中式的來管理每個服務的配置資訊。
安全認證從單體應用架構到分散式應用架構再到微服務架構,應用的安全訪問在不斷的經受考驗。為了適應架構的變化、需求的變化,身份認證與鑑權方案也在不斷的變革。面對數十個甚至上百個微服務之間的呼叫,如何保證高效安全的身份認證?面對外部的服務訪問,該如何提供細粒度的鑑權方案?
David Borsos 在倫敦的微服務大會上提出了四種解決方案:
單點登入(SSO)這種方案意味著每個面向使用者的服務都必須與認證服務互動,這會產生大量非常瑣碎的網路流量和重複的工作,隨著微服務應用的增多,這種方案的弊端會更加明顯。
分散式 Session 方案分散式會話方案原理主要是將關於使用者認證的資訊儲存在共享儲存中,且通常由使用者會話作為 Key 來實現的簡單分散式雜湊對映。當用戶訪問微服務時,使用者資料可以從共享儲存中獲取。這種方案的缺點在於共享儲存需要一定保護機制,因此需要透過安全連線來訪問,這時解決方案的實現就通常具有相當高的複雜性了。
客戶端 Token 方案令牌在客戶端生成,由身份驗證服務進行簽名,並且必須包含足夠的資訊,以便可以在所有微服務中建立使用者身份。令牌會附加到每個請求上,為微服務提供使用者身份驗證,這種解決方案的安全性相對較好,但身份驗證登出是一個大問題,緩解這種情況的方法可以使用短期令牌和頻繁檢查認證服務等。對於客戶端令牌的編碼方案,David Borsos 更喜歡使用 JSON Web Tokens(JWT),它足夠簡單且庫支援程度也比較好。
客戶端 Token 與 API 閘道器結合這個方案意味著所有請求都透過閘道器,從而有效地隱藏了微服務。 在請求時,閘道器將原始使用者令牌轉換為內部會話 ID 令牌。在這種情況下,登出就不是問題,因為閘道器可以在登出時撤銷使用者的令牌。
總結在微服務架構下,我們更傾向於 David Borsos 所建議的 JWT 方案,將 OAuth2 和 JWT 結合使用,OAuth2 一般用於第三方接入的場景,管理對外的許可權,所以比較適合和 API 閘道器結合,針對於外部的訪問進行鑑權(當然,底層 Token 標準採用 JWT 也是可以的)。
JWT 更加輕巧,在微服務之間進行認證&鑑權已然足夠,並且可以避免和身份認證服務直接打交道。當然,從能力實現角度來說,類似於分散式 Session 在很多場景下也是完全能滿足需求,具體怎麼去選擇鑑權方案,還是要結合實際的需求來。