天天看點

如何用代理平台解決微服務的一些痛點

為什麼要做代理平台

微服務架構越來越流行,在一個上百号人開發的項目中,使用微服務的方式,大量子產品之間通過接口調用,随之也帶來了許多問題:

  • 接口不能及時提供造成阻塞:往往用戶端需要等待背景接口進入測試階段,才能開始進行開發。一些剛入門的用戶端開發(如web前端開發),并沒有自行僞造接口資料的能力。
  • 通信資料格式混亂:json、xml、protobuf等各種方式都有,方式相同而資料結構又不統一,主調和被調方都需要自行封裝和解析不同格式的資料
  • 日志未收斂彙集 : 日志分散在各個子產品,未跟請求鍊路綁定,異常發生時的故障現場不好還原
  • 各子產品重複造輪子:各接口需要自己實作鑒權、限頻、驗證調用者等通用能力

為解決上述問題,我們約定一套調用規範,并将所有調用收歸一處進行代理中轉。是以,需要實作一套高可用的代理平台。

代理平台特性

先說一下幾個角色

  • 第三方(服務) -- 接口提供方,被調方
  • 調用方(應用) -- 主調方 ,它可以是一個用戶端如浏覽器、手機APP,也可以是另一個接口提供方(第三方、服務)。
  • 代理平台 -- 請求轉發平台。
  • 代理管理平台 -- 可視化配置及查詢調用方、第三方、請求日志等資料,
  • 鑒權平台 -- 基于 cookie、token等方式的含登入、權限控制的使用者中心

代理平台主要有以下特性

松耦合、消除用戶端開發等待。

代理平台除可以正常轉發請求外,還可以僞裝響應,即代理平台直接按預定規則随機生成響應給調用方,并不請求第三方。

統一輸入輸出格式

嚴格控制輸入格式、标準化輸出結構。第三方可以不按結構響應,但是需要在代理管理平台定義轉換規則。如果很多事情按照約定來,可以少很多工作。這也是許多架構所倡導的約定優于配置。

規範CGI文檔

通過統一的頁面,統一錄入接口說明、參數說明、響應頭及字段說明等等。用戶端開發甚至不需要跟背景開發溝通,即可完成開發任務。同時也提高接口的複用性。可以提供相應的注解和注釋包,開發者在代碼中引入注解或者注釋,可以自動完成接口資料在平台上的錄入、更新等操作。

輸入初步驗證

在代理平台定義好入參規則,代理平台在收到請求時,統一對輸入參數進行格式驗證、必填驗證等等。對惡意輸入請求進行攔截并記錄。

頻率控制

代理平台對每個接口提供基于分鐘頻次或者超頻驗證碼的調用頻率控制能力

接口性能統計

統計從平台向第三方發起請求,到平台完全收到第三方的響應的時間,做為第三方接口的性能。

請求日志

目标請求接口,來源ip、請求封包、響應封包、成功狀态、耗時、所屬的調用樹等等整個請求完整的上下文資料,都記錄在案。并且,請求到達接口提供方之後,如果第三方處理出現異常,可以将異常日志反向上報到代理平台,由代理平台來關聯這次請求的日志。

還原調用樹(調用鍊路)

一個調用方請求到達第三方後,有可能級聯發起更多的請求。如果這些請求全部經過代理平台。那麼代理平台可以記錄鍊路資料,後續在代理管理平台上可視化的還原、呈現整個調用鍊路,清楚辨別每個被調節點的耗時、是否成功等資料,有助于排查故障、性能瓶頸等問題

統一鑒權

登入态檢查和接口權限控制可以全部收歸代理平台。如果請求轉發到了第三方接口,說明使用者已登入并對此接口有權限,第三方開發者隻需要從頭部取封裝好的userkey,到統一鑒權中心換取使用者資訊即可.

協定頭規範化及過濾

為防止背景響應一些不規範的頭,或者一些危險的頭進行過濾。并且平台可以統一處理OPTIONS請求,将預定的協商頭響應給用戶端,可以靈活配置跨域需求。

來源IP過濾

對接口可以提供IP白名單或者黑名單的功能,合法來源ip的請求才能被轉發到背景

多協定支援

需要能夠支援多種接口協定,如HTTP、FTP、SMTP等等應用層協定,也需要能直接支援TCP長連接配接、UDP資料報等協定。并能做到部分協定轉換,調用方無感覺的使用跟第三方接口不同的協定通信。

關聯測試用例

每個接口可以內建測試用例,類似于Advance REST Client或PostMan,定時以用例對接口進行輸入輸出調用測試。這可能需要接口提供方提供專門的測試接口。

服務存活檢查,多server時提供負載均衡

第三方可以提供部署服務的多個server ip,由代理管理平台來進行存活檢查,但server不可用時從緩存中踢掉此server,代理平台對多個server ip實作負載均衡。server故障時向真實接口方發出告警。

對第三方接口壓測

代理平台本身需要具備較強的并發能力。但更重要的是接口本身支援高吞吐量通路。代理平台可以對第三方接口進行壓測,以推進第三方優化接口性能及并發能力。

實作方式

nginx+lua+confd + etcd

confd + etcd 用來實作實時動态更新nginx配置,當有接口新增或修改時,動态生成server或者location配置。nginx來實作請求轉發。lua腳本來實作一些諸如日志上報、鑒權檢查、協定頭檢查等等邏輯。

這種方式在接口量較小時是個不錯的選擇。但是當接口數量達到成千上萬的級别後,動态生成的nginx配置會非常大,不利于問題排查,且容易生成沖突、錯誤的nginx配置,緻使nginx程序異常。并且上面提到的一些複雜的目标,如還原調用鍊路、輸入參數驗證、關聯測試用例等,此方式也很難實作。

camel

apache camel是一個協定轉換的架構,可以很友善實作協定轉換、請求路由轉發。下面是代理平台及代理管理平台的架構及請求處理過程示意。

如何用代理平台解決微服務的一些痛點

其中

clinet 即為調用方,使用平台提供的各種語言(js、c、java、php、python等)的sdk,可以對調用方無感覺的包裝一些驗證、辨別頭部。這也是還原調用鍊路的基礎。如果不使用sdk,同樣可以向代理平台發起請求。SDK主要做提供兩個功能:1、透傳辨別頭、來源路徑頭資訊等等。2、向代理管理平台上報此次請求處理出現的異常日志。

cgi_proxy 即是基于camel開發的代理平台。主要實作驗證請求合法性(appkey)、登入态驗證與權限控制、協定轉換、參數驗證、請求轉發、頭部特殊字段處理、格式化響應、請求日志記錄等等。日志由異步線程寫入到消息隊列。轉發請求需要的資料從redis中擷取,redis中存儲了接口提供方真實接口位址、參數規則、合法appkey等資訊。因為在client看來,請求的處理時間是平台處理時間+真實接口處理時間,隻有平台處理足夠快,才能減少性能損失,是以cgi_proxy 不從任何接口查詢資料,也不直接操作db,隻從redis查詢資料,這樣可以很好的減少性能損失。

log_coll收集消息隊列中的請求日志落地存儲,并按時對全平台接口調用情況進行統計,生成營運資料。當每日的調用量達到百萬、千萬級别時,比db分表更好的手段是由此程序定時遷移舊的資料。

manager 即代理管理平台。定義一套接口模型,将各種背景接口按模型規範并存儲至db。将核心的資料緩存到redis。在頁面實作可視的接口編輯、日志查詢等能力

繼續閱讀