天天看點

微服務間的調用和應用内調用有啥差別

摘要

目前大部分的系統架構都是微服務架構,就算沒有注冊中心、服務管理,也肯定是多個服務,單體服務比較少了。

大家平時需要在應用内調用rpc接口也比較多,那麼有沒有思考過微服務之間的調用和應用内直接調用有什麼差別呢?面試時是不是經常被被問到微服務呢,本篇文章針對

微服務間的方法調用和應用内方法調用的有啥差別

這個很小的點,談談我的經驗

微服務調用特點

先從單體應用說起

微服務間的調用和應用内調用有啥差別

單體應用

單體引用通過一個服務節點直接組裝好資料,傳回給調用者。所有的方法調用都發生在應用内部。

微服務間的調用和應用内調用有啥差別

微服務應用

商品詳情服務需要調用商品,營銷等多個服務組裝好商品詳情頁的資料

微服務調用和應用内調用不同點在于它是跨程序的,甚至是跨節點的,這意味着什麼呢

使用k8s編排微服務時,我們可以讓不同的服務放在同一個節點的不同docker container上,但是考慮到網絡不可靠,和容災,

服務之間不可避免會放到不同的節點/機架上,是以下文都以跨節點來讨論

意味着兩點

  • 對外部有了依賴
  • 如果是跨節點,就有了網絡調用。我們知道網絡都是不可靠的

關于網絡有幾個著名的錯誤推論

The network is reliable(網絡是可靠的)

Latency is zero.(延遲可以為0)

Bandwidth is infinite(帶寬是無限的)

The network is secure(網絡是安全的)

Topology doesn't change(網絡拓撲結構不會變)

Transport cost is zero(網絡傳輸耗時為0)

The network is homogeneous(網絡是同類的)

我們需要做什麼

存在上述兩個問題後,那麼我們需要在寫微服務間方法調用時注意什麼的

微服務架構設計中有一條重要的原則叫

嚴出寬進

,嚴出意思就是說你提供給其他服務的東西要盡可能的進行嚴格的校驗。寬進就是你調用别人的接口要寬容,相容各種情況。比如說你需要考慮别人的節點down了/api逾時/api不可用等等因素。

為了解決這個問題,我們必須要針對具體業務,分析依賴類型,是強依賴還是弱依賴,強依賴包裝成自己的服務異常傳回碼/或者直接告訴前端調用不可用。弱依賴,catch所有異常,無論依賴方發生什麼,不能影響我的接口傳回。

此外,我依賴的服務某段時間内接口錯誤率很高,調用方還在不停的發送請求,那麼就會一直得到錯誤的結果,這時候這些請求其實是無效的,是以這時候需要用戶端熔斷,不再去調用服務方,給服務方恢複的時間,等過段時間再去重試,發現服務方可用時,再去調用。

網絡調用

網絡調用是耗時的,是以我們需要利用池化技術,複用連接配接,比如在單體應用中我們需要與資料庫連接配接,會利用到資料庫連接配接池來提高資料操作效率。那麼微服務調用也是這麼個道理,我們與其他服務建議http/tcp連接配接,也需要建立連接配接池。另外一個服務可能會依賴多個微服務,不能因為和某個服務之間的連接配接出了問題,影響到與其他服務的連接配接,是以需要做連接配接池隔離。

服務間調用有可能失敗,是以我們需要有重試機制,比如因為網絡抖動引發的逾時問題,我們可以通過重試提高API的可用性。

但是思考一下壞的情況,某段時間網絡或者服務端真的有問題了。用戶端逾時時間設定的很大的話,用戶端等待的時間就會很長,然後再加上重試機制,就會将用戶端的連接配接占滿,造成用戶端相關API不可用。

幾個案例

分享幾個微服務調用的故障案例,幫助大家進行場景化思考

為啥要分享這些案例呢,因為TMD的這些案例都是血的教訓,造成線上故障,不是我的錯,卻要我背鍋

案例1:

新上線了一個産品功能,需要推廣,放在另外一個流量比較大的産品子產品中,展示一些我們産品功能的資料。

微服務間的調用和應用内調用有啥差別

出于某種原因,我們的服務mock了rpc調用資料,傳回null。結果其他服務整個前台頁面挂了,挂了,挂了。

典型的強弱依賴問題,調用方沒有處理好依賴類型,明明是一個弱依賴沒有處理,變成了強依賴,造成功能挂了

案例2:

依賴的某個服務需要根據主鍵

List<id>

來批量查詢,依賴服務内部做分庫分表拆分,更新了sdk

在提供的sdk client中做分表路由,将批量id拆分成N個rpc調用。這麼做的原因是防止批量查詢把資料庫連接配接池打爆。

微服務間的調用和應用内調用有啥差別
忽略了網絡調用

案例3

别人調我們的服務的某個接口,這個接口RT(耗時時間)P95 < 30ms。但是用戶端調用的逾時時間設定成了500ms,在某次不知道是什麼原因的情況下,調用方的連接配接大量block,造成線程阻塞,相關API不可用。看服務方監控,該接口傳回時間正常,服務方沒有任何異常。

沒有正确的設定逾時時間

總結

微服務調用和應用内調用有很大的差別,我們不能在進行服務間調用時無感覺,需要知道它面臨的問題

  • 對外部有了依賴,外部是不可靠的
  • 有了網絡調用

解法可以精煉為4條

  • 根據業務需要,判斷依賴類型,做好對應的降級
  • 設定合理的逾時時間
  • 調用方需要對不同的服務調用設定連接配接池隔離
  • 調用方需要有熔斷機制

這些問題看似都很簡單,但是根據我的觀察,真的有很多人寫了無數的rpc調用,還沒有意識到這些問題。

關注【方丈的寺院】,與方丈一起開始技術修行之路

繼續閱讀