Chris Richardson微服務翻譯:構建微服務之使用API網(wǎng)關

Chris Richardson 微服務系列翻譯全7篇鏈接:

原文鏈接:Building Microservices: Using an API Gateway


介紹

假設我們?yōu)橐粋€商品應用開發(fā)一個移動APP陆错,我們應該提供一個產(chǎn)品詳情頁來展示指定產(chǎn)品的信息何缓。Amazon Android 應用在商品詳情頁展示的內容,如下圖所示:

盡管只是移動APP败明,商品詳情頁依然展示給我們很多信息,不僅包括基本信息(名稱太防、描述妻顶、價格),還包含如下內容:

  • 購物車中的商品數(shù)
  • 歷史訂單記錄
  • 買家評價
  • 低庫存預警
  • 送貨選項
  • 推薦:包括與此商品一起購買的其他商品蜒车、購買該商品的顧客還買的其他商品讳嘱、購買該商品的顧客還看過其他的商品
  • 其他購物選項

使用單體應用架構時,移動APP通過單一的 REST 請求(GET api.company.com/productdetails/productId)來獲取展示的數(shù)據(jù)酿愧。負載均衡會將請求路由到多個相同實例的其中一個沥潭,然后程序查詢各種數(shù)據(jù)庫表,返回數(shù)據(jù)給客戶端嬉挡。

對應如果采用微服務架構钝鸽,展示在產(chǎn)品詳情頁的數(shù)據(jù)會來自不同的微服務上汇恤。下面列舉一些微服務對應的展示數(shù)據(jù):

  • 購物車服務:購物車中的商品數(shù)
  • 訂單服務:訂單記錄
  • 目錄服務:商品基本信息,如名稱拔恰、圖片和價格
  • 評論服務:用戶評價
  • 庫存服務:低庫存預警
  • 配送服務:送貨選項因谎、期限和費用
  • 推薦服務:推薦商品

客戶端如何訪問這些服務,讓我們看看下面的方法颜懊。

客戶端與服務端直接通信

理論上客戶端可以直接請求每個微服務财岔,每個微服務都有一個公開的節(jié)點(https://serviceName.api.company.com),該 URL 映射到負載均衡河爹,然后被分發(fā)到可用的實例上處理匠璧,為了獲取產(chǎn)品詳情,移動客戶端需要向上述每個服務發(fā)送請求咸这。

遺憾的是夷恍,這種方法存在挑戰(zhàn)和局限:

1)客戶端需求和每個微服務暴露出的細粒度 API 不匹配。本例中客戶端需要發(fā)送7個不同的請求媳维,在一個復雜的應用中請求數(shù)甚至還要更多酿雪,例如亞馬遜在顯示他們的產(chǎn)品頁面時會調用數(shù)百個服務。這種方法還使得客戶端代碼非常復雜侨艾。

2)一些服務使用的協(xié)議對 web 并不友好执虹。一個服務可能使用 Thrift 的二進制 RPC,而另一個服務可能使用 AMQP 消息協(xié)議唠梨。這些協(xié)議不是瀏覽器和防火墻友好的袋励,最好在內部使用。而防火墻之外当叭,應用程序最好使用 HTTP 或 WebSocket 之類的協(xié)議茬故。

3)這種方法會使得微服務難以重構。隨著時間的推移蚁鳖,我們可能要重新規(guī)劃磺芭、合并或拆分微服務,如果客戶端直接與微服務通信的話醉箕,對這些微服務進行重構變得異常困難钾腺。

正是這些原因,采用客戶端直接調用微服務的方式并不明智讥裤。

使用 API 網(wǎng)關

通常更好的方式是使用 API 網(wǎng)關放棒,API 網(wǎng)關是提供系統(tǒng)唯一入口的服務器,他和設計模式中的 外觀模式 類似:API 網(wǎng)關封裝內部系統(tǒng)架構己英,并向客戶端提供 API间螟。它還可能負責諸如 用戶驗證、監(jiān)控、負載均衡厢破、緩存荣瑟、請求管理、靜態(tài)響應處理等功能摩泪。下圖展示了適應 API 網(wǎng)關的架構:

API 網(wǎng)關負責請求路由笆焰、組合和協(xié)議轉換。來自客戶端的所有請求都先經(jīng)過 API 網(wǎng)關加勤,然后被路由到對應的微服務中仙辟,API 網(wǎng)關通常調用多個微服務并聚合其結果來處理請求同波。它可以在 web 協(xié)議(如 HTTP 和 WebSocket)與內部使用的非 web 協(xié)議之間轉換鳄梅。

API 網(wǎng)關可以為每個客戶端提供定制的 API,它通常為移動客戶端暴露粗粒度的 API未檩。例如:商品詳情頁戴尸,API 網(wǎng)關提供 (/productdetails?productid=xxx) 節(jié)點使得移動客戶端單一請求可以獲取所有的產(chǎn)品明細。API 網(wǎng)關調用各個服務(商品信息冤狡、推薦孙蒙、評論等)合并結果并返回。

Netflix API網(wǎng)關 就是一個很好的 API 網(wǎng)關實例悲雳。Netflix 流媒體服務提供給成百上千的設備使用挎峦,包括電視、機頂盒合瓢、智能手機坦胶、游戲系統(tǒng)、平板電腦等晴楔。最初顿苇,Netflix 視圖為他們的流服務提供通用的 API,然而税弃,他們發(fā)現(xiàn)由于設備的獨特需求纪岁,這種設計方式不能很好的工作。如今他們使用 API 網(wǎng)關通過運行設備的適配器代碼為客戶端提供定制的 API则果,通常適配器為每個請求平均調用6~7個微服務幔翰,Netflix API網(wǎng)關每天處理數(shù)十億請求。

使用 API 網(wǎng)關的優(yōu)勢及劣勢

使用 API 網(wǎng)關有優(yōu)勢也有不足西壮。

最大優(yōu)點是:
1)它封裝了應用的內部結構遗增,客戶端只需要簡單的與 API 網(wǎng)關交互即可,而不用直接調用每個服務茸时。
2)API 網(wǎng)關為不同的客戶端提供定制的 API贡定,減少了客戶端和應用間的交互次數(shù),并大大簡化了客戶端的代碼可都。

API 網(wǎng)關也有其不足:
1)它本身增加了一個需要開發(fā)缓待、部署和維護的高可用組件蚓耽。
2) API 網(wǎng)關有時候變成了開發(fā)的瓶頸。開發(fā)者為了暴露新的微服務必須更新 API 網(wǎng)關旋炒。API 網(wǎng)關的更新流程要盡可能的簡單步悠,否則,開發(fā)人員不得不排隊等待瘫镇。盡管它有這些不足鼎兽,但對于大部分的應用程序而言,使用 API 網(wǎng)關是合理的铣除。

實現(xiàn)一個 API 網(wǎng)關

目前我們討論了 API 網(wǎng)關的動機和一些優(yōu)缺點谚咬。下面我們看一些需要考慮的一些設計問題。

性能與擴展性

只有少數(shù)公司擁有 Netflix 這樣的規(guī)模尚粘,每天需要處理數(shù)十億的請求择卦。對于大多數(shù)程序而言,API 網(wǎng)關的性能和可擴展性是非常重要的郎嫁。因此秉继,API 網(wǎng)關構建在一個支持異步、IO 非阻塞的平臺上是合理的泽铛。有多種不同的技術可參考:JVM 上尚辑,基于 NIO 的框架,比如 Netty盔腔、Vertx杠茬、 Spring Reactor 或 JBoss Undertow 等。一個流行的選項是 Node.js铲觉,他是構建于 Chrome JS 引擎的平臺澈蝙。另一個選項是 NGINX Plus,他提供了成熟撵幽、可擴展灯荧、高性能的 web 服務器和一個易于部署的、可配置可編程的反向代理盐杂。NGINX Plus 可以管理身份驗證逗载、權限控制、負載均衡链烈、緩存以及應用級別的健康檢查及監(jiān)控厉斟。

使用響應式編程模型

API 網(wǎng)關將請求路由到相應的多個微服務并合并處理結果,對于一些請求强衡,例如產(chǎn)品詳情頁擦秽,后端對應的服務是彼此獨立的,為了減少響應時間,API 網(wǎng)關應并行處理這些請求感挥。然而有時候缩搅,請求之間是有依賴關系的,在請求微服務之前触幼,API 網(wǎng)關需要調用身份驗證服務來驗證請求的合法性硼瓣。類似的,獲取用戶心愿單上的產(chǎn)品信息時置谦,API 網(wǎng)關需要先獲取包含這些信息的客戶資料堂鲤,然后再去獲取信息的詳情。另一個有趣的例子就是:Netflix Video Grid媒峡。

使用傳統(tǒng)的異步回調方式來寫 API 組合代碼會把你帶入地獄瘟栖。代碼會變的混亂、難以理解且容易出錯丝蹭。更好的方式是使用響應式方法慢宗,以一種聲明式樣式編寫 API 網(wǎng)關代碼坪蚁。例如:Scala中的 Future 奔穿、Java 8中的CompletableFuture 以及JavaScript中的Promise ,還有微軟為.NET開發(fā)的Reactive Extensions敏晤。Netflix 為他們的 API 網(wǎng)關創(chuàng)建了 RxJava for JVM贱田,此外還有 RxJS for JavaScript,既可以在瀏覽器中運行嘴脾,也可以在Node.js 中運行男摧。響應式風格將幫助你寫出簡潔高效的 API 網(wǎng)關代碼。

服務調用

微服務架構是一個進程間通信的分布式系統(tǒng)译打, 有兩種進程間通信方式:一種是采用異步耗拓、基于消息傳遞的機制。例如:JMS 或 AMQP 這樣的消息組件奏司;另一種是使用 HTTP 或 Thrfit 這種同步機制進行通信乔询。通常,一個系統(tǒng)會同時使用同步和異步方式韵洋,甚至還會使用同一類型的多種實現(xiàn)竿刁。總之搪缨,API 網(wǎng)關需要支持不同的通信機制食拜。

服務發(fā)現(xiàn)

API 網(wǎng)關需要知道和他通信的每個微服務的地址(IP和端口號)。傳統(tǒng)應用中副编,可以使用硬編碼的方式负甸,但是在現(xiàn)代基于云的微服務應用中,這不是一個容易解決的問題∩氪基礎架構服務(例如:消息組件)通常會有一個靜態(tài)地址煮盼,可以在環(huán)境變量中指定。然而带污,獲取一個微服務地址就不是簡單的事了僵控,微服務的地址是動態(tài)分配的,一組服務實例可能因為自動擴展或升級而動態(tài)的變化鱼冀。因此 API 網(wǎng)關需要服務發(fā)現(xiàn)機制报破,可以是服務器端發(fā)現(xiàn),或者是客戶端發(fā)現(xiàn)(后面的文章會詳細介紹服務發(fā)現(xiàn)的問題)千绪。如果使用客戶端發(fā)現(xiàn)的話充易,API 網(wǎng)關應該能查詢服務注冊中心,這是一個包含所有微服務實例及其地址的數(shù)據(jù)庫荸型。

處理局部故障

局部故障在分布式系統(tǒng)中很常見盹靴,當一個服務調用另一個服務,當后者響應慢或不可用時就出現(xiàn)了這個問題瑞妇。API 網(wǎng)關不能因為無限期的等待下游服務而阻塞稿静。不過,如何處理失敗取決于應用場景或具體哪個服務失敗辕狰,例如:產(chǎn)品詳情頁改备,推薦服務掛了,那么 API 網(wǎng)關應該返回其他產(chǎn)品信息蔓倍,保障產(chǎn)品對用戶仍然可用悬钳,推薦內容可為空或使用固定的 Top 10 列表取代。不過偶翅,如果產(chǎn)品服務掛了默勾,那么 API 網(wǎng)關應該返回客戶端錯誤信息。

API 網(wǎng)關也可以緩存返回的數(shù)據(jù)聚谁。例如:產(chǎn)品價格變動不頻繁母剥,當價格服務不可用時,API 網(wǎng)關可以返回緩存的價格數(shù)據(jù)垦巴。數(shù)據(jù)可以是 API 網(wǎng)關自己緩存媳搪,也可以使用 Redis 或 Memcached之類的外部緩存。通過返回默認值或緩存值骤宣,API 網(wǎng)關保證局部故障不會影響用戶體驗秦爆。

Netflix Hystrix 在編寫代碼調用遠程服務時是非常有用的,Hystrix 會標記超過特定閥值的調用為超時憔披,他還實現(xiàn)了『熔斷器』模式來防止對無響應服務的更多請求等限,如果一個服務的出錯率超過了特定閥值爸吮,那么 Hystrix 會觸發(fā)熔斷器,所有請求會快速失敗并持續(xù)一段時間望门。Hystrix 允許用戶定義請求失敗時的 fallback 操作形娇,例如:讀取緩存或返回默認值。如果你在使用 JVM 筹误,那么應該考慮使用 Hystrix桐早,如果使用的是非 JVM 環(huán)境,那么可以使用一個功能相同的庫厨剪。

總結

對于大部分基于微服務的應用哄酝,實現(xiàn) API 網(wǎng)關作為應用的單一入口是明智的。API 網(wǎng)關負責請求路由祷膳、聚合陶衅、協(xié)議轉換。為每個客戶端提供特定的 API直晨,還可以通過返回默認值或緩存值來處理后端服務的調用失敗搀军。下篇文章,我們將討論服務間的通信勇皇。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末罩句,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子儒士,更是在濱河造成了極大的恐慌的止,老刑警劉巖,帶你破解...
    沈念sama閱讀 207,113評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件着撩,死亡現(xiàn)場離奇詭異,居然都是意外死亡匾委,警方通過查閱死者的電腦和手機拖叙,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評論 2 381
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來赂乐,“玉大人薯鳍,你說我怎么就攤上這事“ご耄” “怎么了挖滤?”我有些...
    開封第一講書人閱讀 153,340評論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長浅役。 經(jīng)常有香客問我斩松,道長,這世上最難降的妖魔是什么觉既? 我笑而不...
    開封第一講書人閱讀 55,449評論 1 279
  • 正文 為了忘掉前任惧盹,我火速辦了婚禮乳幸,結果婚禮上,老公的妹妹穿的比我還像新娘钧椰。我一直安慰自己粹断,他們只是感情好,可當我...
    茶點故事閱讀 64,445評論 5 374
  • 文/花漫 我一把揭開白布嫡霞。 她就那樣靜靜地躺著瓶埋,像睡著了一般。 火紅的嫁衣襯著肌膚如雪诊沪。 梳的紋絲不亂的頭發(fā)上悬赏,一...
    開封第一講書人閱讀 49,166評論 1 284
  • 那天,我揣著相機與錄音娄徊,去河邊找鬼闽颇。 笑死,一個胖子當著我的面吹牛寄锐,可吹牛的內容都是我干的兵多。 我是一名探鬼主播,決...
    沈念sama閱讀 38,442評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼橄仆,長吁一口氣:“原來是場噩夢啊……” “哼剩膘!你這毒婦竟也來了?” 一聲冷哼從身側響起盆顾,我...
    開封第一講書人閱讀 37,105評論 0 261
  • 序言:老撾萬榮一對情侶失蹤怠褐,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后您宪,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體奈懒,經(jīng)...
    沈念sama閱讀 43,601評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,066評論 2 325
  • 正文 我和宋清朗相戀三年宪巨,在試婚紗的時候發(fā)現(xiàn)自己被綠了磷杏。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,161評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡捏卓,死狀恐怖极祸,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情怠晴,我是刑警寧澤遥金,帶...
    沈念sama閱讀 33,792評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站蒜田,受9級特大地震影響稿械,放射性物質發(fā)生泄漏。R本人自食惡果不足惜物邑,卻給世界環(huán)境...
    茶點故事閱讀 39,351評論 3 307
  • 文/蒙蒙 一溜哮、第九天 我趴在偏房一處隱蔽的房頂上張望滔金。 院中可真熱鬧,春花似錦茂嗓、人聲如沸餐茵。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽忿族。三九已至,卻和暖如春蝌矛,著一層夾襖步出監(jiān)牢的瞬間道批,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評論 1 261
  • 我被黑心中介騙來泰國打工入撒, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留隆豹,地道東北人。 一個月前我還...
    沈念sama閱讀 45,618評論 2 355
  • 正文 我出身青樓茅逮,卻偏偏與公主長得像璃赡,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子献雅,可洞房花燭夜當晚...
    茶點故事閱讀 42,916評論 2 344

推薦閱讀更多精彩內容