微服務間的調用和應用內調用的有啥區別
摘要
目前大部分的系統架構都是微服務架構,就算沒有註冊中心、服務管理,也肯定是多個服務,單體服務比較少了。
大家平時需要在應用內調用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調用,還沒有意識到這些問題。
關註【方丈的寺院】,與方丈一起開始技術修行之路
微服務間的調用和應用內調用的有啥區別