? ? ? ?在微服務架構里,注冊中心(像 Nacos、Eureka、Consul 等)是服務發現與治理的核心。可要是注冊中心突然宕機,微服務間的遠程調用還能順利進行嗎?這是面試時很常被問到的問題,下面我們就來深入剖析。
一、遠程調用的 “兩次請求” 與實例緩存的引入
在沒有實例緩存的情況下,微服務每次發起遠程調用,大致要經歷以下兩次請求:
- 請求注冊中心,獲取目標服務的地址列表:服務消費者得先去注冊中心查詢,找到自己要調用的服務提供者都有哪些實例,以及這些實例對應的網絡地址。
- 向目標服務的具體地址發送請求:拿到地址列表后,消費者會挑選其中一個地址,向對應的服務提供者發送實際的業務請求。
不過,這種每次調用都進行兩次請求的方式,會讓性能大打折扣。為了解決這個問題,實例緩存就應運而生了。實例緩存的作用是在服務消費者本地,同步并實時更新注冊中心里的服務實例信息。有了它,服務消費者不用每次調用都去注冊中心查詢,能直接從本地緩存里獲取目標服務的地址,從而提升調用效率。
二、注冊中心宕機時,遠程調用能否成功?
注冊中心宕機后,遠程調用是否能成功,關鍵要看服務消費者本地有沒有目標服務的實例緩存。
場景一:服務消費者已有目標服務的實例緩存
比如 “訂單” 服務之前調用過 “商品” 服務,此時 “訂單” 服務本地已經緩存了 “商品” 服務的實例地址。
由于實例緩存還存在,“訂單” 服務發起遠程調用時,就不再依賴注冊中心了。它會直接從本地緩存里取出 “商品” 服務的地址,然后發送請求,所以遠程調用能成功。
這也體現出實例緩存的重要性,它讓微服務在注冊中心短暫不可用的時候,依然能保證服務間調用的連續性,增強了系統的容錯能力。
場景二:服務消費者無目標服務的實例緩存
要是 “訂單” 服務是第一次發起對 “商品” 服務的遠程調用,也就是之前從來沒有調用過 “商品” 服務,本地沒有 “商品” 服務的實例緩存。
這種情況下,“訂單” 服務要發起遠程調用,就必須依賴注冊中心去獲取 “商品” 服務的地址列表。但現在注冊中心已經宕機,“訂單” 服務沒辦法獲取到目標服務的地址,所以遠程調用不能成功。
三、總結
注冊中心宕機后,遠程調用是否能成功,取決于服務消費者本地是否有目標服務的實例緩存:
- 若有緩存(之前調用過目標服務),遠程調用能成功,因為可以從本地緩存獲取服務地址,不依賴注冊中心。
- 若沒有緩存(首次調用目標服務),遠程調用會失敗,因為獲取服務地址必須依賴注冊中心。
由此可見,實例緩存是微服務架構中提升遠程調用性能、增強系統容錯性的關鍵機制,它在注冊中心和服務消費者之間,搭建了一道 “緩沖屏障”,讓系統在注冊中心出現異常時,仍能維持一定程度的服務調用能力。