配置中心
什麼是配置中心?有哪些常見的配置中心?
配置中心是一個用於配置集中化管理目支持動態更新、分發配置文件的工具(服務)。
它實現了配置的統一管理和動態同新,當配置信息發生變化時,配置中心可以自動通知服務實例進行配置更新,這樣就可以實例無需重啓即可應用最新的配置,從一定程度上減少了系統訪問的空窗期,非常靈活方便
常見的配置中心:
- Spring Cloud Config:Spring 提供的分佈式配置管理工具,支持從 Git、SVN 等版本控制系統加載配置
- Apollo:由攜程開源的配置管理中心,支持配置的實時推送和權限管理。
- Nacos:阿里巴巴的配置管理和服務發現工具,既支持配置中心功能,又能作為註冊中心使用。
- Consul:HashiCorp 提供的分佈式系統管理工具,既可以用作服務發現,也可以用於存儲和分發配置
- Etcd:分佈式鍵值存儲工具,常用於 Kubernetes 集羣中的配置管理。
- Zookeeper:Zookeeper 是一個開源的分佈式協調服務,和 Nacos 一樣,其既可以作為註冊中心,又可以作為配置中心。
為什麼微服務需要配置中心?
微服務架構中的每個服務通常都需要一些配置信息,例如數據庫連接地址、服務端口、日誌級別等。這些配置可能因為不同環境、不同部署實例或者動態運行時需要進行調整和管理。
微服務的實例一般非常多,如果每個實例都需要一個個地去做這些配置,那麼運維成本將會非常大,這時候就需要一個集中化的配置中心,去管理這些配置。
SpringCloud可以選擇哪些配置中心?
和註冊中心一樣,SpringCloud也支持對多種配置中心的集成。常見的配置中心選型包括:
- Spring Cloud Config:官方推薦的配置中心,支持將配置文件存儲在Git、SVN等版本控制系統中,並提供RESTful API進行訪問和管理。
- ZooKeeper:一個開源的分佈式協調服務,可以用作配置中心。它具有高可用性、一致性和通知機制等特性。
- Consul:另一個開源的分佈式服務發現和配置管理工具,也可用作配置中心。支持多種配置文件格式,提供健康檢查、故障轉移和動態變更等功能。
- Etcd:一個分佈式鍵值存儲系統,可用作配置中心。它使用基於Raft算法的一致性機制,提供分佈式數據一致性保證。
- Apollo:攜程開源的配置中心,支持多種語言和框架。提供細粒度的配置權限管理、配置變更通知和灰度發佈等高級特性,還有可視化的配置管理界面。
- Nacos:阿里巴巴開源的服務發現、配置管理和服務管理平台,也可以作為配置中心使用。支持服務註冊與發現、動態配置管理、服務健康監測和動態DNS服務等功能。
Nacos配置中心的原理了解嗎?
配置中心,説白了就是一句話:配置信息的CRUD。
具體的實現大概可以分成這麼幾個部分:
- 配置信息存儲:Nacos默認使用內嵌數據庫Derby來存儲配置信息,還可以採用MySQL等關係型數據庫。
- 註冊配置信息:服務啓動時,Nacos Client會向Nacos Server註冊自己的配置信息,這個註冊過程就是把配置信息寫入存儲,並生成版本號。
- 獲取配置信息:服務運行期間,Nacos Client通過API從Nacos Server獲取配置信息。Server根據鍵查找對應的配置信息,並返回給Client。
- 監聽配置變化:Nacos Client可以通過註冊監聽器的方式,實現對配置信息的監聽。當配置信息發生變化時,Nacos Server會通知已註冊的監聽器,並觸發相應的回調方法。
Nacos配置中心長輪詢機制?
一般來説客户端和服務端的交互分為兩種:推(Push)和拉(Pull),Nacos在Pull的基礎上,採用了長輪詢來進行配置的動態刷新。 詳情可以看這篇文章Nacos交互模型
在長輪詢模式下,客户端定時向服務端發起請求,檢查配置信息是否發生變更。如果沒有變更,服務端會"hold"住這個請求,即暫時不返回結果,直到配置發生變化或達到一定的超時時間。
具體的實現過程如下:
如果客户端發起 Pull 請求,服務端收到請求之後,先檢查配置是否發生了變更:
- 變更:返回變更配置;
- 無變更:設置一個定時任務,延期 29.5s 執行,把當前的客户端長輪詢連接加入 allSubs 隊列;
在這 29.5s 內的配置變化:
- 配置無變化:等待 29.5s 後觸發自動檢查機制,返回配置;
- 配置變化:在 29.5s 內任意一個時刻配置變化,會觸發一個事件機制,監聽到該事件的任務會遍歷 allSubs 隊列,找到發生變更的配置項對應的 ClientLongPolling 任務,將變更的數據通過該任務中的連接進行返回。相當於完成了一次 PUSH 操作;
長輪詢機制結合了 Pull 機制和 Push 機制的優點; 通過長輪詢的方式,Nacos客户端能夠實時感知配置的變化,並及時獲取最新的配置信息。同時,這種方式也降低了服務端的壓力,避免了大量的長連接佔用內存資源。
Nacos的服務註冊表結構是怎樣的?
Nacos採用了數據的分級存儲模型,最外層是Namespace,用來隔離環境。然後是Group,用來對服務分組。接下來就是服務(Service)了,一個服務包含多個實例,但是可能處於不同機房,因此Service下有多個集羣(Cluster),Cluster下是不同的實例(Instance)。
對應到Java代碼中,Nacos採用了一個多層的Map來表示。結構為Map<String, Map<String, Service>>,其中最外層Map的key就是namespaceId,值是一個Map。內層Map的key是group拼接serviceName,值是Service對象。Service對象內部又是一個Map,key是集羣名稱,值是Cluster對象。而Cluster對象內部維護了Instance的集合。
Nacos中的Namespace是什麼?如何使用它來組織和管理微服務
Nacos中的Namespace是用於隔離不同環境或應用之間的配置和服務信息的概念。通過使用Namespace,可以將不同的環境(例如開發、測試和生產)或不同的應用程序(例如Web應用和移動應用)的配置和服務信息分離開來,以避免衝突和錯誤。
在Nacos中,每個Namespace都有自己獨立的配置和服務註冊表。這意味着,如果有多個應用程序需要使用Nacos,可以將它們分別放置在不同的Namespace中。每個Namespace都有自己的命名空間ID,用於標識該Namespace。要使用Namespace,在Nacos客户端初始化時,需要指定要使用的Namespace ID。
通過使用Namespace,可以對不同Namespace下的服務進行分組和管理,例如可以使用Nacos提供的Group功能對同一Namespace下的服務進行分組,方便管理和查找。同時,使用Namespace還可以對不同環境下的配置進行隔離,避免不同環境之間的配置衝突。
SpringCloud Config 是什麼?
SpringCloud Config 為分佈式系統外部化配置提供了服務端以及客户端的支持,簡單來説就是一個配置中心,其主要包括以下兩個部分的內容:Config Sever和 Config Cient 。
- ConfigServer是一個可橫向擴展,並且集中式配置的服務器,主要用於集中管理服務各種環境下的配置,然後默認使用 Git進行存儲配置的內容,因此可以很方便地實現配置的版本控制
- Config Client 是 Config Server 的客户端,主要用於操作存儲在 Config Server 中的配置信息。
遠程調用
説説微服務之間是如何獨立通訊的?
遠程過程調用(Remote Procedure Invocation)
也就是我們常説的服務的註冊與發現,直接通過遠程過程調用來訪問別的service。
優點:簡單,常見,因為沒有中間件代理,系統更簡單
缺點:只支持請求/響應的模式,不支持別的,比如通知、請求/異步響應、發佈/訂閲、發佈/異步響應,降低了可用性,因為客户端和服務端在請求過程中必須都是可用的。
消息
使用異步消息來做服務間通信。服務間通過消息管道來交換消息,從而通信。
優點:把客户端和服務端解耦,更鬆耦合,提高可用性,因為消息中間件緩存了消息,直到消費者可以消費, 支持很多通信機制比如通知、請求/異步響應、發佈/訂閲、發佈/異步響應。
缺點:消息中間件有額外的複雜。
説説 RPC 的實現原理
首先需要有處理網絡連接通訊的模塊,負責連接建立、管理和消息的傳輸。其次需要有編 解碼的模塊,因為網絡通訊都是傳輸的字節碼,需要將我們使用的對象序列化和反序列化。剩下的就是客户端和服務器端的部分,服務器端暴露要開放的服務接口,客户調用服 務接口的一個代理實現,這個代理實現負責收集數據、編碼並傳輸給服務器然後等待結果返回。
能説下HTTP和RPC的區別嗎?
嚴格來講,HTTP和RPC不是一個層面的東西:
- HTTP(Hypertext Transfer Protocol)是一種應用層協議,主要強調的是網絡通信;
- RPC(Remote Procedure Call,遠程過程調用)是一種用於分佈式系統之間通信的協議,強調的是服務之間的遠程調用。
一些RPC框架比如gRPC,底層傳輸協議其實也是用的HTTP2,包括Dubbo3,也兼容了gRPC,使用了HTTP2作為傳輸層的一層協議。
如果硬要説區別的話,如下:
| HTTP | RPC | |
|---|---|---|
| 定義 | HTTP(超文本傳輸協議)是一種用於傳輸超文本的協議。 | RPC(遠程過程調用)是一種用於實現分佈式系統中不同節點之間通信的協議。 |
| 通信方式 | 基於請求-響應模型,客户端發送請求,服務器返回響應。 | 基於方法調用模型,客户端調用遠程方法並等待結果。 |
| 傳輸協議 | 基於TCP協議,可使用其他傳輸層協議如TLS/SSL進行安全加密。 | 可以使用多種傳輸協議,如TCP、UDP等。 |
| 數據格式 | 基於文本,常用的數據格式有JSON、XML等。 | 可以使用各種數據格式,如二進制、JSON、Protocol Buffers等。 |
| 接口定義 | 使用RESTful風格的接口進行定義,常用的方法有GET、POST、PUT、DELETE等。 | 使用IDL(接口定義語言)進行接口定義,如Protocol Buffers、Thrift等。 |
| 跨語言性 | 支持跨語言通信,可以使用HTTP作為通信協議實現不同語言之間的通信。 | 支持跨語言通信,可以使用IDL生成不同語言的客户端和服務端代碼。 |
| 靈活性 | 更加靈活,適用於不同類型的應用場景,如Web開發、API調用等。 | 更加高效,適用於需要高性能和低延遲的分佈式系統。 |
在微服務體系裏,基於HTTP風格的遠程調用通常使用框架如Feign來實現,基於RPC的遠程調用通常使用框架如Dubbo來實現。
那Feign和Dubbo的區別呢?
這兩個才是適合拿來比較的東西:
| Feign | Dubbo | |
|---|---|---|
| 定義 | Feign是一個聲明式的Web服務客户端,用於簡化HTTP API的調用。 | Dubbo是一個分佈式服務框架,用於構建面向服務的微服務架構。 |
| 通信方式 | 基於HTTP協議,使用RESTful風格的接口進行定義和調用。 | 基於RPC協議,支持多種序列化協議如gRPC、Hessian等。 |
| 服務發現 | 通常結合服務註冊中心(如Eureka、Consul)進行服務發現和負載均衡。 | 通過ZooKeeper、Nacos等進行服務註冊和發現,並提供負載均衡功能。 |
| 服務治理 | 不直接提供服務治理功能,需要結合其他組件或框架進行服務治理。 | 提供服務註冊與發現、負載均衡、容錯機制、服務降級等服務治理功能。 |
| 跨語言性 | 支持跨語言通信,可以使用HTTP作為通信協議實現不同語言之間的通信。 | 支持跨語言通信,通過Dubbo的IDL生成不同語言的客户端和服務端代碼。 |
| 生態系統 | 集成了Spring Cloud生態系統,與Spring Boot無縫集成。 | 擁有完整的生態系統,包括註冊中心、配置中心、監控中心等組件。 |
| 適用場景 | 適用於構建RESTful風格的微服務架構,特別適合基於HTTP的微服務調用。 | 適用於構建面向服務的微服務架構,提供更全面的服務治理和容錯機制。 |
需要注意的是,Feign和Dubbo並不是互斥的關係。實際上,Dubbo可以使用HTTP協議作為通信方式,而Feign也可以集成RPC協議進行遠程調用。選擇使用哪種遠程調用方式取決於具體的業務需求和技術棧的選擇。
負載均衡的意義什麼?
在計算中,負載均衡可以改善跨計算機,計算機集羣,網絡鏈接,中央處理單元或磁盤驅動器等多種計算資源的工作負載分佈。
負載均衡旨在優化資源使用,最大化吞吐量,最小化響應時間並避免任何單一資源 的過載。使用多個組件進行負載均衡可而不是單個組件可能會通過冗餘來提高可靠性和可用性。負載均衡可通常涉及專用軟件或硬件,例如多層交換機或域名系統服務器進程。
集中式與進程內負載均衡的區別
目前業界主流的負載均衡方案可分成兩類:
- 集中式負載均衡, 即在 consumer 和 provider 之間使用獨立的負載均衡設施(可以是硬件,如F5, 也可以是軟件,如 Nginx), 由該設施負責把 訪問請求 通過某種策略轉發至 provider;
- 進程內負載均衡,將負載均衡邏輯集成到 consumer,consumer 從服務註冊中心獲知有哪些地址可用,然後自己再從這些地址中選擇出一個合適的 provider。Ribbon 就屬於後者,它只是一個類庫,集成於 consumer 進程,consumer 通過它來獲取到 provider 的地址。
説説有哪些負載均衡算法?
常見的負載均衡算法包含以下幾種:
| 內置負載均衡規則類 | 規則描述 |
|---|---|
| RoundRobinRule | 簡單輪詢服務列表來選擇服務器。它是Ribbon默認的負載均衡規則。 |
| AvailabilityFilteringRule | 對以下兩種服務器進行忽略:
(1)在默認情況下,這台服務器如果3次連接失敗,這台服務器就會被設置為“短路”狀態。短路狀態將持續30秒,如果再次連接失敗,短路的持續時間就會幾何級地增加。 (2)併發數過高的服務器。如果一個服務器的併發連接數過高,配置了AvailabilityFilteringRule規則的客户端也會將其忽略。併發連接數的上限,可以由客户端的 <clientName>.<clientConfigNameSpace>.ActiveConnectionsLimit屬性進行配置。 |
| WeightedResponseTimeRule | 為每一個服務器賦予一個權重值。服務器響應時間越長,這個服務器的權重就越小。這個規則會隨機選擇服務器,這個權重值會影響服務器的選擇。 |
| ZoneAvoidanceRule | 以區域可用的服務器為基礎進行服務器的選擇。使用Zone對服務器進行分類,這個Zone可以理解為一個機房、一個機架等。而後再對Zone內的多個服務做輪詢。 |
| BestAvailableRule | 忽略那些短路的服務器,並選擇併發數較低的服務器。 |
| RandomRule | 隨機選擇一個可用的服務器。 |
| RetryRule | 重試機制的選擇邏輯 |
- 輪詢算法(Round Robin):輪詢算法是最簡單的負載均衡算法之一。它按照順序將請求依次分配給每個後端服務器,循環往復。當請求到達時,負載均衡器按照事先定義的順序選擇下一個服務器。輪詢算法適用於後端服務器具有相同的處理能力和性能的場景。
- 加權輪詢算法(Weighted Round Robin):加權輪詢算法在輪詢算法的基礎上增加了權重的概念。每個後端服務器都被賦予一個權重值,權重值越高,被選中的概率就越大。這樣可以根據服務器的處理能力和性能調整請求的分配比例,使得性能較高的服務器能夠處理更多的請求。
- 隨機算法(Random):隨機算法將請求隨機分配給後端服務器。每個後端服務器有相等的被選中概率,沒有考慮服務器的實際負載情況。這種算法簡單快速,適用於後端服務器性能相近且無需考慮請求處理能力的場景。
- 加權隨機算法(Weighted Random):加權隨機算法在隨機算法的基礎上引入了權重的概念。每個後端服務器被賦予一個權重值,權重值越高,被選中的概率就越大。這樣可以根據服務器的處理能力和性能調整請求的分配比例。
- 最少連接算法(Least Connection):最少連接算法會根據後端服務器當前的連接數來決定請求的分配。負載均衡器會選擇當前連接數最少的服務器進行請求分配,以保證後端服務器的負載均衡。這種算法適用於後端服務器的處理能力不同或者請求的處理時間不同的場景。
- 哈希算法(Hash):哈希算法會根據請求的某個特定屬性(如客户端IP地址、請求URL等)計算哈希值,然後根據哈希值選擇相應的後端服務器。
常見的負載均衡器,比如Ribbion、Gateway等等,基本都支持這些負載均衡算法。
可以用幾行代碼實現一個負載均衡器嗎?
不要題目嚇到,這類題目不會讓你實現一個完整的可以運行的系統,僅用幾行代碼突出其核心思想即可
可以,例如可以用常見的輪詢(Round Robin)的方式來分發請求。核心就是維護一個服務器列表和當前下標,每次請求返回一個不同的服務器
List<String> servers = List.of("A", "B", "C");
AtomicInteger index = new AtomicInteger(0);
public String getServer() {
return servers.get(index.getAndIncrement() % servers.size());
}
Atomiclnteger 用來保證在多線程環境下也能安全地自增,不會出現重複或跳號的情況。
輪詢的優點是實現簡單、平均分配,缺點是不考慮服務器實際負載,所有機器一視同仁。
什麼是Ribbon?
ribbon是一個負載均衡客户端,可以很好地控制htt和tcp的一些行為。feign默認集成了ribbon。
什麼是 Feign?它的優點是什麼?
Feign 是一個聲明式的Web服務客户端。
所謂的聲明式就是指不需要編寫複雜的關於 Http 請求的東西。只需要聲明一個一個接口,然後在這個接口上添加一些註解,這些註解包括了請求的方法(如GET和POST)、請求的URL等信息
Feign 在運行時通過註解和接口上定義的內容來動態構造和發送 Http 請求。所以使用 Feign,開發者只需要定義服務接口並通過註解指明服務名和參數等信息,Feign 就能自動完成 Http 請求的構建、發送和結果處理
Feign 也是 Spring Cloud Netflix 組件之一,結合Spring Cloud 的服務註冊和發現、負載均衡等功能,能夠讓服務間的調用變得更加方便
Feign 的主要特點有:
- 聲明式的服務客户端,通過 Java 接口和註解構建服務客户端,簡化了 Http 調用的使用過程,無需手動構建 HTTP 請求
- 很好地融入了 SpringCloud 生態,可以使用 SpringCloud負載均衡、服務熔斷等能力
使用方式
- 添加pom依賴。
- 啓動類添加
@EnableFeignClients - 定義一個接口
@FeignClient(name=“xxx”)指定調用哪個服務
Ribbon和Feign的區別?
- 啓動類註解不同,Ribbon是@RibbonClient feign的是@EnableFeignClients;
- 服務指定的位置不同,Ribbon是在@RibbonClient註解上聲明,Feign則是在定義抽象方法的接口中使用@FeignClient聲明;
- 調用方式不同,Ribbon需要自己構建http請求,模擬http請求。
Ribbon是一個客户端負載均衡器,作用在於多個微服務實例間分發請求,提升可用性和性能。它可與各種HTTP客户端如RestTemplate配合使用來發送HTTP請求並進行負載均衡。
Feign則是一個聲明式的HTTP客户端,通過編寫接口來定義對遠程微服務的需求。Feign使用註解和模板方法簡化了遠程調用的編寫,使得調用遠程服務的代碼更加清晰和簡潔。它更注重簡潔的聲明式編程模型,你只需編寫接口並使用註解描述HTTP請求,Feign會在運行時生成實現類來執行實際的HTTP請求。
Ribbon更注重負載均衡,需要配合其他庫如RestTemplate來發送http請求,而Feign則採用聲明式編程模型,只需編寫接口和註解即可。此外,Ribbon提供了自定義負載均衡策略的能力,而Feign通常與Ribbon一起使用以實現負載均衡。
為什麼Feign第一次調用耗時很長?
主要原因是由於Ribbon的懶加載機制,當第一次調用發生時,Feign會觸發Ribbon的加載過程,包括從服務註冊中心獲取服務列表、建立連接池等操作,這個加載過程會增加首次調用的耗時。
ribbon:
eager-load:
enabled: true
clients: service-1
那怎麼解決這個問題呢?
可以在應用啓動時預熱Feign客户端,自動觸發一次無關緊要的調用,來提前加載Ribbon和其他相關組件。這樣,就相當於提前進行了第一次調用。
Feign怎麼實現認證傳遞?
比較常見的一個做法是,使用攔截器傳遞認證信息。可以通過實現RequestInterceptor接口來定義攔截器,在攔截器裏,把認證信息添加到請求頭中,然後將其註冊到Feign的配置中。
@Configuration
public class FeignClientConfig {
@Bean
public RequestInterceptor requestInterceptor() {
return new RequestInterceptor() {
@Override
public void apply(RequestTemplate template) {
// 添加認證信息到請求頭中
template.header("Authorization", "Bearer " + getToken());
}
};
}
private String getToken() {
// 獲取認證信息的邏輯,可以從SecurityContext或其他地方獲取
// 返回認證信息的字符串形式
return "your_token";
}
}
Fegin怎麼做負載均衡?Ribbon?
在Feign中,負載均衡是通過集成Ribbon來實現的。
Ribbon是Netflix開源的一個客户端負載均衡器,可以與Feign無縫集成,為Feign提供負載均衡的能力。
Ribbon在發起請求前,會從“服務中心”獲取服務列表(清單),然後按照一定的負載均衡策略去發起請求,從而實現客户端的負載均衡。Ribbon本身也維護着“服務提供者”清單的有效性。如果它發現“服務提供者”不可用,則會重新從“服務中心”獲取有效的“服務提供者”清單來及時更新。
Feign 和 OpenFeign 的區別?
Feign 和 OpenFeign 都是用於簡化服務之間的 HTTP 調用的工具,讓我們可以更加方便地實現服務間的通信
Feign 最初是由 Netfix 開發的一個聲明式, REST 客户端框架,它的目標是讓微服務之間的調用像調用本地方法一樣容易。如果我們想調用其它服務的接口,可以創建一個接口,然後通過註解聲明所需要調用服務的方法和路徑,Feign 可以自動發送 Http 請求和接收響應,轉換為方法返回值
而 OpenFeign 是 Spring Cloud在 Feign 的基礎上進一步封裝的,它整合了 Spring Cloud 的特性,使得我們可以更加簡單地使用 Feign,包括如下幾個方面:
- 自動配置:Openfeign利用Spring Boot的自動配置機制,通過@FeignClien和@EnableFeignClients 註解就可以創建一個 Feign 客户端,極大簡化了Feign客户端的創建和配置過程。
- 負載均衡:與Spring Cloud等服務發現組件集成,可以輕鬆實現客户端負載均衡
- Hystrix集成:只需要簡單的配置就可以快速集成Hystrix,提高系統的容錯性
服務容災
什麼是熔斷器?為什麼需要熔斷器?
在微服務架構中,服務之間的調用關係會形成調用鏈路,鏈路中的任何一個服務都可能出現超時或者宕機的情況,而在微服務系統中,如果調用失敗的話可能會引起大面積的服務癱瘓,即形成“服務雪崩”的情況,這樣的話對於服務的影響是巨大的。
熔斷器就是為了來解決這個問題,避免服務雪崩情況的發生。
熔斷器的基本原理如下:
- 正常情況下,熔斷器處於關閉狀態,服務消費者正常請求微服務中的服務提供者。
- 當發生了服務調用清求失敗的時候,並且達到了一定比例,比如70% 的清求發生了失敗,或者失敗的清求次數達到了10等等,這個時候熔斷器打開,此時將服務調用者不再發起服務調用請求,這種方法是一種快速失敗的方法,也稱為熔斷方法。
- 熔斷器啓用一段時間時候,自動進入“半關閉狀態”,這個時候熔斷器允許服務調用者發起一個請求給服務提供者,如果請求調用成功了,關閉熔斷器,反之繼續打開熔斷器,循環往復。
這種方式在服務發生意外的時候,可以實現服務錯誤的隔離,避免了服務錯誤導致了系統的整體不可用,這樣保證了系統即使出現了局部問題也不會發生服務雪崩的情況。
什麼是服務雪崩?
在微服務中,假如一個或者多個服務出現故障,如果這時候,依賴的服務還在不斷髮起請求,或者重試,那麼這些請求的壓力會不斷在下游堆積,導致下游服務的負載急劇增加。不斷累計之下,可能會導致故障的進一步加劇,可能會導致級聯式的失敗,甚至導致整個系統崩潰,這就叫服務雪崩。
一般,為了防止服務雪崩,可以採用這些措施:
- 服務高可用部署:確保各個服務都具備高可用性,通過冗餘部署、故障轉移等方式來減少單點故障的影響。
- 限流和熔斷:對服務之間的請求進行限流和熔斷,以防止過多的請求涌入導致後端服務不可用。
- 緩存和降級:合理使用緩存來減輕後端服務的負載壓力,並在必要時進行服務降級,保證核心功能的可用性。
什麼是服務熔斷?
熔斷機制是應對雪崩效應的一種微服務鏈路保護機制。當某個微服務不可用或者響應時間太長時,會進行服務降級,進而熔斷該節點微服務的調用,快速返回“錯誤”的響應信息。當檢測到該節點微服務調用響應正常後恢復調用鏈路。在Spring Cloud框架裏熔斷機制通過Hystrix實現,Hystrix會監控微服務間調用的狀況,當失敗的調用到一定閾值,缺省是5秒內調用20次,如果失敗,就會啓動熔斷機制。
什麼是服務降級?
服務降級,一般是從整體負荷考慮。當系統出現異常情況時,服務降級會主動屏蔽一些非核心或可選的功能,而只提供最基本的功能,以確保系統的穩定運行。通過減少對資源的依賴,服務降級可以保證系統的可用性和性能。 它可以根據業務需求和系統狀況來制定策略,例如替換耗時操作、返回默認響應、返回靜態錯誤頁面等。
Hystrix相關注解@EnableHystrix:開啓熔斷 @HystrixCommand(fallbackMethod=”XXX”),聲明一個失敗回滾處理函數XXX,當被註解的方法執行超時(默認是1000毫秒),就會執行fallback函數,返回錯誤提示。
什麼是服務限流?
服務限流是一種流量控制策略,它通過限制每秒請求的數量(QPS)、請求頻率、併發數等,來保護服務的處理能力,防止系統因為流量過大而出現性能問題或資源耗盡服務限流可以認為是服務降級的一種,限流就是通過限制系統清求的輸入和輸出,從而實現對於系統的保護,這個和降級的概念很像,都是為了保證核心功能的正常運行。限流是因為服務的吞吐量以及負載這些都是可以預估的,我們為了保證系統的正常運行,可以設置限制的國值,即涌過限制輸入或者輸出的方式來減少流量的流通,然後實現對於系統的保護限流有很多種實現方案,比如我們説的限流算法、延遲解決、拒絕解決等等,保證請求的範圍在系統可以接受的閾值以內,實現對系統的保護。
有哪些熔斷降級方案實現?
目前常見的服務熔斷降級實現方案有這麼幾種:
| 框架 | 實現方案 | 特點 |
|---|---|---|
| Spring Cloud | Netflix Hystrix | 提供線程隔離、服務降級、請求緩存、請求合併等功能;
可與Spring Cloud其他組件無縫集成 官方已宣佈停止維護,推薦使用Resilience4j代替 |
| Spring Cloud | Resilience4j | 輕量級服務熔斷庫
提供類似於Hystrix的功能 - 具有更好的性能和更簡潔的API 可與Spring Cloud其他組件無縫集成 |
| Spring Cloud Alibaba | Sentinel | 阿里巴巴開源的流量控制和熔斷降級組件
提供實時監控、流量控制、熔斷降級等功能 與Spring Cloud Alibaba生態系統緊密集成 |
| Dubbo | Dubbo自帶熔斷降級機制 | Dubbo框架本身提供的熔斷降級機制
可通過配置實現服務熔斷和降級 與Dubbo的RPC框架緊密集成 |
什麼是Hystrix?
Hystrix是一個延遲和容錯庫,旨在隔離遠程系統,服務和第三方庫的訪問點,當出現故障是不可避免的故障時,停止級聯故障並在複雜的分佈式系統中實現彈性。
通常對於使用微服務架構開發的系統,涉及到許多微服務。這些微服務彼此協作。
思考一下微服務:
假設如果上圖中的微服務9失敗了,那麼使用傳統方法我們將傳播一個異常。但這仍然會導致整個系統崩潰。
隨着微服務數量的增加,這個問題變得更加複雜。微服務的數量可以高達1000.這是hystrix出現的地方 我們將使用Hystrix在這種情況下的Fallback方法功能。我們有兩個服務employee-consumer使用由employee-consumer公開的服務。
簡化圖如下所示
現在假設由於某種原因,employee-producer公開的服務會拋出異常。我們在這種情況下使用Hystrix定義了一個回退方法。這種後備方法應該具有與公開服務相同的返回類型。如果暴露服務中出現異常,則回退方法將返回一些值。
Hystrix如何實現容錯?
儘管已經不再更新,但是Hystrix是非常經典的服務容錯開源庫,它提供了多種機制來保護系統,Hystrix服務容錯六大機制:
- 服務熔斷(Circuit Breaker):Hystrix通過設置閾值來監控服務的錯誤率或響應時間。當錯誤率或響應時間超過預設的閾值時,熔斷器將會打開,後續的請求將不再發送到實際的服務提供方,而是返回預設的默認值或錯誤信息。這樣可以快速隔離故障服務,防止故障擴散,提高系統的穩定性和可用性。
- 服務降級(Fallback):當服務熔斷打開時,Hystrix可以提供一個備用的降級方法或返回默認值,以保證系統繼續正常運行。開發者可以定義降級邏輯,例如返回緩存數據、執行簡化的邏輯或調用其他可靠的服務,以提供有限但可用的功能。
- 請求緩存(Request Caching):Hystrix可以緩存對同一請求的響應結果,當下次請求相同的數據時,直接從緩存中獲取,避免重複的網絡請求,提高系統的性能和響應速度。
- 請求合併(Request Collapsing):Hystrix可 以將多個併發的請求合併為一個批量請求,減少網絡開銷和資源佔用。這對於一些高併發的場景可以有效地減少請求次數,提高系統的性能。
- 實時監控和度量(Real-time Monitoring and Metrics):Hystrix提供了實時監控和度量功能,可以對服務的執行情況進行監控和統計,包括錯誤率、響應時間、併發量等指標。通過監控數據,可以及時發現和解決服務故障或性能問題。
- 線程池隔離(Thread Pool Isolation):Hystrix將每個依賴服務的請求都放在獨立的線程池中執行,避免因某個服務的故障導致整個系統的線程資源耗盡。通過線程池隔離,可以提高系統的穩定性和可用性。
説下Hystrix與Sentinel的區別
Hystrix和Sentinel都是服務熔斷器,用於提高分佈式系統的彈性。它們的主要區別在於實現方式、適用場景和資源模型設計。
Hystrix基於命令模式設計,將外部資源的調用封裝在命令對象中,通過線程池或信號量來實現隔離。它提供了豐富的配置選項,如線程池大小、超時時間等,以實現對系統資源的有力控制。Hystrix更適用於需要高併發、快速響應的場景,因為它可以快速隔離和恢復故障。
Sentinel則基於流量控制和熔斷降級的思想,可以與Spring Cloud、gRPC、Dubbo等框架集成。它通過定義資源規則和應用策略來實現對系統資源的控制。Sentinel更適用於需要流量控制和熔斷降級的場景,它可以根據系統負載和響應時間來實現自動熔斷和降級操作。
總之,Hystrix和Sentinel都是服務熔斷器,用於提高系統的彈性。它們在實現方式、適用場景和資源模型設計等方面存在一些不同。具體選擇哪個工具取決於系統的具體需求和場景。
Sentinel採用的什麼限流算法?
Sentinel使用滑動窗口限流算法來實現限流。
滑動窗口限流算法是一種基於時間窗口的限流算法。它將一段時間劃分為多個時間窗口,並在每個時間窗口內統計請求的數量。通過動態地調整時間窗口的大小和滑動步長,可以更精確地控制請求的通過速率。
Sentinel是怎麼實現限流的?
首先需要定義具體需要限流的資源,然後指定一定的規則(基於QPS(每秒查詢數)、線程數等維度),限制資源的訪問頻次。然後根據一定的限流算法(固定窗口、滑動窗口、令牌桶和漏桶),對指定的資源進行訪問的流量控制。具體流程如下:
- 當一個請求進入系統時,Sentinel 會首先對請求進行統計(如當前的 QPS、併發數)
- 接着 Sentine| 檢查配置的限流規則,如果當前請求的速率超過了設定的限流閾值,Sentinel 將觸發限流措施
- 對於被限流的請求,可以選擇直接拒絕、排隊等待、或返回降級響應等方式來處理,保證系統核心功能的穩定
Sentinel怎麼實現集羣限流?
Sentinel利用了Token Server和Token Client的機制來實現集羣限流。
開啓集羣限流後,Client向Token Server發送請求,Token Server根據配置的規則決定是否限流。