微服務架構愈來愈流行,在一個上百號人開發的項目中,使用微服務的方式,大量模塊之間經過接口調用,隨之也帶來了許多問題:php
爲解決上述問題,咱們約定一套調用規範,並將全部調用收歸一處進行代理中轉。所以,須要實現一套高可用的代理平臺。前端
先說一下幾個角色java
代理平臺主要有如下特性python
代理平臺除能夠正常轉發請求外,還能夠假裝響應,即代理平臺直接按預約規則隨機生成響應給調用方,並不請求第三方。nginx
嚴格控制輸入格式、標準化輸出結構。第三方能夠不按結構響應,可是須要在代理管理平臺定義轉換規則。若是不少事情按照約定來,能夠少不少工做。這也是許多框架所倡導的約定優於配置。web
經過統一的頁面,統一錄入接口說明、參數說明、響應頭及字段說明等等。客戶端開發甚至不須要跟後臺開發溝通,便可完成開發任務。同時也提升接口的複用性。能夠提供相應的註解和註釋包,開發者在代碼中引入註解或者註釋,能夠自動完成接口數據在平臺上的錄入、更新等操做。redis
在代理平臺定義好入參規則,代理平臺在收到請求時,統一對輸入參數進行格式驗證、必填驗證等等。對惡意輸入請求進行攔截並記錄。apache
代理平臺對每一個接口提供基於分鐘頻次或者超頻驗證碼的調用頻率控制能力json
統計從平臺向第三方發起請求,到平臺徹底收到第三方的響應的時間,作爲第三方接口的性能。跨域
目標請求接口,來源ip、請求報文、響應報文、成功狀態、耗時、所屬的調用樹等等整個請求完整的上下文數據,都記錄在案。而且,請求到達接口提供方以後,若是第三方處理出現異常,能夠將異常日誌反向上報到代理平臺,由代理平臺來關聯此次請求的日誌。
一個調用方請求到達第三方後,有可能級聯發起更多的請求。若是這些請求所有通過代理平臺。那麼代理平臺能夠記錄鏈路數據,後續在代理管理平臺上可視化的還原、呈現整個調用鏈路,清楚標識每一個被調節點的耗時、是否成功等數據,有助於排查故障、性能瓶頸等問題
登陸態檢查和接口權限控制能夠所有收歸代理平臺。若是請求轉發到了第三方接口,說明用戶已登陸並對此接口有權限,第三方開發者只須要從頭部取封裝好的userkey,到統一鑑權中心換取用戶信息便可.
爲防止後臺響應一些不規範的頭,或者一些危險的頭進行過濾。而且平臺能夠統一處理OPTIONS請求,將預約的協商頭響應給客戶端,能夠靈活配置跨域需求。
對接口能夠提供IP白名單或者黑名單的功能,合法來源ip的請求才能被轉發到後臺
須要可以支持多種接口協議,如HTTP、FTP、SMTP等等應用層協議,也須要能直接支持TCP長鏈接、UDP數據報等協議。並能作到部分協議轉換,調用方無感知的使用跟第三方接口不一樣的協議通訊。
每一個接口能夠集成測試用例,相似於Advance REST Client或PostMan,定時以用例對接口進行輸入輸出調用測試。這可能須要接口提供方提供專門的測試接口。
第三方能夠提供部署服務的多個server ip,由代理管理平臺來進行存活檢查,但server不可用時從緩存中踢掉此server,代理平臺對多個server ip實現負載均衡。server故障時向真實接口方發出告警。
代理平臺自己須要具有較強的併發能力。但更重要的是接口自己支持高吞吐量訪問。代理平臺能夠對第三方接口進行壓測,以推動第三方優化接口性能及併發能力。
confd + etcd 用來實現實時動態更新nginx配置,當有接口新增或修改時,動態生成server或者location配置。nginx來實現請求轉發。lua腳原本實現一些諸如日誌上報、鑑權檢查、協議頭檢查等等邏輯。
這種方式在接口量較小時是個不錯的選擇。可是當接口數量達到成千上萬的級別後,動態生成的nginx配置會很是大,不利於問題排查,且容易生成衝突、錯誤的nginx配置,導致nginx進程異常。而且上面提到的一些複雜的目標,如還原調用鏈路、輸入參數驗證、關聯測試用例等,此方式也很難實現。
apache camel是一個協議轉換的框架,能夠很方便實現協議轉換、請求路由轉發。下面是代理平臺及代理管理平臺的架構及請求處理過程示意。
其中
clinet 即爲調用方,使用平臺提供的各類語言(js、c、java、php、python等)的sdk,能夠對調用方無感知的包裝一些驗證、標識頭部。這也是還原調用鏈路的基礎。若是不使用sdk,一樣能夠向代理平臺發起請求。SDK主要作提供兩個功能:一、透傳標識頭、來源路徑頭信息等等。二、向代理管理平臺上報這次請求處理出現的異常日誌。
cgi_proxy 便是基於camel開發的代理平臺。主要實現驗證請求合法性(appkey)、登陸態驗證與權限控制、協議轉換、參數驗證、請求轉發、頭部特殊字段處理、格式化響應、請求日誌記錄等等。日誌由異步線程寫入到消息隊列。轉發請求須要的數據從redis中獲取,redis中存儲了接口提供方真實接口地址、參數規則、合法appkey等信息。由於在client看來,請求的處理時間是平臺處理時間+真實接口處理時間,只有平臺處理足夠快,才能減小性能損失,因此cgi_proxy 不從任何接口查詢數據,也不直接操做db,只從redis查詢數據,這樣能夠很好的減小性能損失。
log_coll收集消息隊列中的請求日誌落地存儲,並按時對全平臺接口調用狀況進行統計,生成運營數據。當每日的調用量達到百萬、千萬級別時,比db分表更好的手段是由此進程定時遷移舊的數據。
manager 即代理管理平臺。定義一套接口模型,將各類後臺接口按模型規範並存儲至db。將核心的數據緩存到redis。在頁面實現可視的接口編輯、日誌查詢等能力