在微服務架構中,不同的微服務可以有不同的網路位址,各個微服務之間通過互相呼叫完成使用者請求,客戶端可能通過呼叫n個微服務的介面完成乙個使用者請求。因此,在客戶端和服務端之間增加乙個api閘道器成為多數微服務架構的必然選擇。
在個推的微服務實踐中,api閘道器也起著至關重要的作用。一方面,api閘道器是個推微服務體系對外的唯一入口;另一方面,api閘道器中實現了很多後端服務的共性需求,避免了重複建設。
**個推微服務主要是基於docker和kubernetes進行實踐的。**在整個微服務架構中,最底層的是個推私有部署的kubernetes集群,在集群之上,部署了應用服務。
**個推的應用服務體系共分為三層,最上一層是閘道器層,接著是業務層,最下面是基礎層服務。**在部署應用服務時,我們使用了kubernetes的命名空間對不同產品線的產品進行隔離。除了應用服務外, kubernetes集群上還部署了consul來實現配置的管理、kube-dns實現服務註冊與發現,以及一些輔助系統來進行應用和集群的管理。
下圖是個推微服務體系的架構圖。
個推對api閘道器的功能需求主要有以下幾方面:
要支援配置多個產品,為不同的產品提供不同的埠;
動態路由;
uri的重寫;
服務的註冊與發現;
負載均衡;
安全相關的需求,如session校驗等;
流量控制;
鏈路追蹤;
a/b testing。
在對市面上已有的閘道器產品進行調研後,我們的技術團隊發現,它們並不太適合應用於個推的微服務體系。第一,個推配置的管理都是基於consul實現的,而大部分閘道器產品都需要基於一些db儲存,來進行配置的管理;第二,大部分的閘道器產品提供的功能比較通用,也比較完善,這同時也降低了配置的複雜度以及靈活性;第三,大部分的閘道器產品很難直接融入到個推的微服務架構體系中。
最終,個推選擇使用了operresty和lua進行自研閘道器,在自研的過程中,我們也借鑑了其他閘道器產品的一些設計,如kong和orange的外掛程式機制等。
個推的api閘道器的外掛程式設計如下圖所示。
openresty對請求的處理分為多個階段。個推api閘道器的外掛程式主要是在set、rewrite、access、header_filter、body_filter、log這六個階段做相應的處理,其中,每乙個外掛程式都可以在乙個或多個階段起到相應的作用。在乙個請求到達api閘道器之後,閘道器會根據配置為該請求選擇外掛程式,然後根據每個外掛程式的規則,進一步過濾出匹配規則的外掛程式,最後對外掛程式進行例項化,對流量進行相應的處理。
我們可以通過舉例來理解這個過程,如上圖所示,localhost:8080/api/demo/test/hello這個請求到達閘道器後,閘道器會根據host和埠確定產品資訊,並提取出uri(/api/demo/test/hello),然後根據產品的具體配置,篩選出需要使用的外掛程式——rewrite_uri、dyups和auth,接下來根據每個外掛程式的規則配置進行過濾,過濾後,只有rewrite_uri和dyups兩個外掛程式被選中。之後例項化這兩個外掛程式,在各個階段對請求進行處理。請求被**到後端服務時,uri就被rewrite為「/demo/test/hello」,upstream也被設定為「prod1-svc1」。請求由後端服務處理之後,響應會經閘道器返回給客戶端,這就是整個外掛程式的設計和工作的流程。為了優化效能,我們將外掛程式的例項化延緩到了請求真正開始處理時,在此之前,閘道器會通過產品配置和規則,過濾掉不需要執行的外掛程式。從圖中也可以看出,每個外掛程式的規則配置都很簡單,並且沒有統一的格式,這也確保了外掛程式配置的簡單靈活。
閘道器的配置均為熱更新,通過consul和consul-template來實現,配置在consul上進行更新後,consul-template會將其實時地拉取下來,然後通過以下兩種方式進行更新。
(1)通過呼叫update api,將配置更新到shared-dict中。
(2)更新配置檔案,利用reload openresty實現配置檔案的更新。
動態路由主要涉及到三個方面:服務註冊、服務發現和請求**。
如下圖所示,服務的註冊和發現是基於kubernetes的service和kube-dns實現的,在consul中,會維持乙個服務的對映表,應用的每乙個微服務都對應kubernetes上的乙個service,每建立乙個service都會在consul上的服務對映表中新增一項(會被實時更新到閘道器的共享記憶體中)。閘道器每收到乙個請求都會從服務對映表中查詢到具體的後端服務(即kubernetes中的service名),並進行動態路由。kube-dns可以將service的網域名稱解析成kubernetes內部的clusterip,而service**了多個pod,會將流量均衡地**到不同的pod上。
流量控制主要是通過乙個名為「counter」的後端服務和閘道器中的流控外掛程式實現的。**counter負責儲存請求的訪問次數和限值,並且支援按時間維度進行計數。**流控外掛程式負責攔截流量,呼叫counter的介面進行超限查詢,如果counter返回請求超限,閘道器就會直接拒絕訪問,實現限次的功能,再結合時間維度就可以實現限頻的需求。同時流控外掛程式通過輸出日誌資訊到fluent-bit,由fluent-bit聚合計次來更新counter中的計數。
整個微服務體系的鏈路追蹤是基於分布式的鏈路追蹤系統zipkin來實現的。通過在閘道器安裝zipkin外掛程式和在後端服務中引入zipkin中介軟體,實現最終的鏈路追蹤功能。具體架構如下圖所示。
在a/b測試的實現中,有以下幾個關鍵點:
(1)所有的策略資訊都配置在consul上,並通過consul-template實時生效到各個微服務的記憶體中;
(2)每條策略均有指明,呼叫乙個微服務時應呼叫a還是b(預設為a);
(3)閘道器中實現a/b外掛程式,在請求到達閘道器時,通過a/b外掛程式配置的規則,即可確定請求適用的a/b策略;
(4)閘道器會將請求適用的a/b策略通過url引數傳遞下去;
(5)每個微服務通過傳遞下來的策略,選擇正確的服務進行訪問。
下圖給出了兩種場景下的呼叫鏈路。
以上就是個推微服務閘道器的設計和主要功能的實現。之後,個推的技術團隊會不斷提公升api閘道器的彈性設計,使其能夠在故障出現時,縮小故障的影響範圍;同時,我們也會繼續將閘道器與devops平台做進一步地結合,以確保閘道器在迭代更新時,能夠有更多的自動化測試來保證質量,實現更快速地部署。
個推微服務閘道器架構實踐
在微服務架構中,不同的微服務可以有不同的網路位址,各個微服務之間通過互相呼叫完成使用者請求,客戶端可能通過呼叫n個微服務的介面完成乙個使用者請求。因此,在客戶端和服務端之間增加乙個api閘道器成為多數微服務架構的必然選擇。在個推的微服務實踐中,api閘道器也起著至關重要的作用。一方面,api閘道器是...
django 整合個推 個推微服務閘道器架構實踐
在微服務架構中,不同的微服務可以有不同的網路位址,各個微服務之間通過互相呼叫完成使用者請求,客戶端可能通過呼叫n個微服務的介面完成乙個使用者請求。因此,在客戶端和服務端之間增加乙個api閘道器成為多數微服務架構的必然選擇。在個推的微服務實踐中,api閘道器也起著至關重要的作用。一方面,api閘道器是...
微服務 閘道器
3 很難重構 二 定義 三 閘道器的用途 四 優缺點 缺點 五 實現 採用反應性程式設計模型 服務呼叫 服務發現 處理部分失敗 netflix hysrix 對於實現遠端服務呼叫 來說是乙個非常好用的庫。hystrix記錄那些超過預設定的極限值的呼叫。它實現了circuit break模式,使得可以...