大概三年前的這個時候,開始負責一個項目斧拍,是一個 P2P 產品的客戶端的開發(fā)雀扶。需求很常見,基本就是需要 手機App(iOS, Android) 和 移動 H5頁面肆汹。當時的一個項目背景是愚墓,已經存在多個由后端團隊使用 Java 開發(fā)的微服務,承載著產品的核心業(yè)務邏輯昂勉,以及主數(shù)據(jù)的管理浪册。這些已經存在的微服務,基本是按照領域模型劃分岗照,如會員服務村象,標的服務,賬務服務攒至,充值支付服務等厚者,每個服務基本還提供相應的查詢服務,另外還有一些實用工具類的迫吐,如短信服務库菲。可以預見志膀,在微服務架構下熙宇,一個尋常的 UI 頁面,往往需要調用多個服務溉浙。而這僅僅是問題的一個方面烫止。
讓我們看看在微服務架構下,關于提供給客戶端的 API 的設計放航,都有哪些方面的問題需要考慮
- 微服務暴露的 API 粒度烈拒,通常不同于客戶端的需求。微服務通常暴露細粒度的 API
- 不同的客戶端可能需要不同的數(shù)據(jù)
- 不同客戶端的網絡性能可能不同广鳍。典型的如服務端渲染的 Web 應用程序,相較于移動客戶端吓妆,可以在不影響用戶體驗的情況下赊时,發(fā)起更多的請求,而區(qū)別就在于行拢,LAN 比起移動網絡祖秒,更快并且延遲低
- 服務的實例數(shù)量和位置可能發(fā)生變化
- 服務的劃分可能隨時間推移而變化
- 服務可能使用多種協(xié)議,其中一些可能不是對 Web 友好的
考慮到這些因素,便很自然地考慮竭缝,引入一個中間層房维,服務于客戶端,按需定制 API抬纸,減少請求次數(shù)咙俩,同時隱藏不必要的細節(jié)。
引入這一層抽象之后湿故,前述問題的化解阿趁,都找到一個好的抓手
- 客戶端可以不受服務劃分的變化的影響
- 客戶端可以不受服務的實例數(shù)量和位置變化的影響
- 不同的客戶端,可以有專屬的 API坛猪,同時又共享底層的服務陣列和基礎設施
- 減少客戶端發(fā)起請求的數(shù)量脖阵,進而提升了用戶體驗
- 客戶端不必調用多個服務而只需要與調用 API gateway
- 協(xié)議轉換,將任何內部的通訊協(xié)議墅茉,轉換為 Web 友好的 API 協(xié)議
在前述的項目中命黔,微服務之間使用了 Hessian 和 SOAP 協(xié)議,經過 API gateway 的協(xié)議轉換就斤,最終只以 REST 的方式暴露 API 給客戶端悍募。
這一層的引入,顯然也有一些代價
- 增加了系統(tǒng)復雜性战转。API gateway 作為一個代碼工程搜立,必然需要投入開發(fā)、部署和維護
- 增加了響應時間槐秧。但對于大多數(shù)應用而言啄踊,LAN 網絡中一個額外往返的成本是微不足道的
回到當時的項目中,那時還未了解到 API gateway 作為一種架構模式的存在刁标,代碼項目的名稱是 web-api
颠通,但這個項目完整的承擔了 API gateway 扮演的職責,有效地化解了微服務架構下膀懈,降低客戶端的整體開發(fā)維護成本顿锰。
在技術選型上,實現(xiàn) API gateway 常見的是采用事件驅動或者響應式的編程框架启搂,當需要擴容應對高負載時硼控,這是推薦的方式。在 JVM 上胳赌,可以考慮基于 NIO 的庫牢撼,如 Netty,Spring Reactor 等疑苫。Node.js 也是個常見選擇熏版。
引入一點題外話纷责,我當時對降低客戶端的整體開發(fā)維護成本,還有另外一些思考撼短,是關于溝通再膳。日常的 UI 需求中,有不少其實是對后端微服務沒有變更要求的曲横,簡單的比如喂柒,多顯示一個字段,格式化顯示金額胜榔,稍復雜的比如胳喷,頁面呈現(xiàn)需要多組合一個既有的微服務,表單提交需要將部分信息反饋到另一個微服務等夭织。對于這類需求吭露,如果由后端團隊來支持,一是會分散他們對領域服務和主數(shù)據(jù)管理的專注尊惰,二是考慮到 API gateway 這層比較薄的路由層/裝配層讲竿,動態(tài)語言相比 Java 是更高效的選擇。
再結合當時團隊的情況弄屡,Java 開發(fā)人員普遍缺少基于 NIO 的庫的開發(fā)經驗题禀,而且開發(fā)任務/風險已經偏重。而前端開發(fā)人員在編寫前端組件以及實現(xiàn)前端構建時膀捷,都是在使用 Node.js迈嘹,因此對于他們而言,使用 Node.js 上手 API gateway 的開發(fā)全庸,門檻較低并且普遍有學習意愿秀仲。前端開發(fā)人員又是 UI 需求的直接受命人,對于前述的一大類 UI 變更需求壶笼,他們可以以最少的溝通成本神僵,最少的信息傳遞失誤,來高效的完成覆劈。
由此我組建了當時公司內第一個大前端部門保礼,將前端團隊和移動端團隊納入,將 API gateway 的實現(xiàn)和文檔管理的職責納入责语,大家共同圍繞客戶端的需求炮障,保持較高的整體開發(fā)維護效率。此后坤候,還在 API gateway 的基礎上陸續(xù)添加了 API 版本管理铝阐,移動設備管理,客戶端統(tǒng)計铐拐,緩存等一系列服務徘键。
API gateway 還有很多的擴展點,試舉一些例子
- 客戶端多協(xié)議遍蟋。之前在攜程做 App 時吹害,客戶端就是同時支持 HTTP 和 TCP 兩種協(xié)議
- 面向客戶端支持 HTTP DNS / Direct IP。這個也是常見的客戶端優(yōu)化手段
- 客戶端的流控
- 客戶端認證和鑒權
- 響應數(shù)據(jù)的脫敏
- 客戶端密鑰管理
- 客戶端緩存協(xié)商
- 客戶端調用計量或計費虚青。典型如 Open API
在 API gateway 這個領域它呀,也有一些開源框架在活躍,如 Netflix Zuul棒厘,基于 Nginx 的 Kong 等纵穿,目前關注較少,就不展開介紹了奢人。