文章目錄
- 微服務
- 微服務的介紹
- 微服務服務架構演變
- 微服務網關
- 微服務的負載均衡
- 微服務的容災機制
- 服務崩潰
- 服務容災機制
- 微服務熔斷機制
- 微服務限流
- Sentinel怎么實現限流
- 微服務限流算法
- 1.令牌桶算法
- 2.漏斗桶算法
- 服務監控
- 日志收集
微服務
微服務的介紹
微服務是一種軟件架構風格,其中軟件系統被構建為一組小型、獨立的服務單元,這些服務單元通過輕量級的通信機制相互協作。每個微服務都專注于單一的業務功能,并且可以獨立部署、升級和擴展。微服務架構的核心理念是將復雜的單塊應用拆分為更小、更易管理的部分,從而提高系統的靈活性、可維護性和可擴展性。
微服務架構通常具有以下特點:
模塊化設計: 系統被分解為多個獨立的服務單元,每個服務單元都擁有自己的數據存儲、業務邏輯和用戶界面。
自治性: 每個微服務都是自治的,即它們可以獨立開發、部署和運行,不依賴于其他服務。
松耦合: 微服務之間通過輕量級的通信機制進行交互,通常使用HTTP/REST、消息隊列或RPC等方式。這種松耦合的設計使得系統更容易擴展、更易于替換和維護。
技術多樣性: 不同的微服務可以使用不同的編程語言、框架和數據存儲技術,從而允許開發團隊選擇最適合其需求的技術棧。
彈性: 微服務架構使得系統更具彈性,可以更容易地處理部分失敗,同時允許水平擴展和負載均衡。
可擴展性: 由于每個微服務都是獨立的,因此可以根據需要對系統的特定部分進行水平或垂直擴展,而不影響其他部分。
盡管微服務架構提供了許多優點,但它也帶來了一些挑戰,如分布式系統的復雜性、服務治理、數據一致性等問題。因此,在采用微服務架構時,團隊需要仔細考慮這些挑戰,并采取適當的措施來解決它們。
微服務服務架構演變
單體服務(Monolithic Service)是一種傳統的軟件架構方式,將整個應用程序作為一個單一的、緊耦合的單元進行開發和部署。單體服務通常由多個模塊組成,這些模塊共享同一個數據庫和代碼庫。然而,隨著應用程序規模的增長,單體服務可能變得龐大且難以維護,且部署和擴展困難。
微服務顧名思義,是將一個單體的服務,劃分成多個服務,每個服務職責更加單一,只負責某一重要的事件處理,且各個模塊之間通過HTTP或者RPC服務進行調用,每個微服務都會統一注冊到注冊中心,來判斷服務是否存活。
微服務網關
微服務網關是在微服務架構中常用的組件,用于提供統一的入口和訪問點,對外暴露服務并處理相關的請求。
1.統一入口
微服務網關為整個微服務架構提供了統一的入口和訪問點,客戶端只需與網關進行通信,無需直接調用后端的多個微服務,簡化了客戶端的調用方式。
2.路由和負載均衡
微服務網關可以根據路由規則將請求分發到相應的微服務實例,通過配置路由規則,可以根據請求的路徑、參數、標頭等信息來決定請求應該轉發到那個微服務。同時網關可以實現負載均衡,將請求均勻地分發到多個后端微服務實例上,提高系統的性能和可伸縮性。
3.安全認證和授權
微服務網關可以集中處理安全認證和授權的邏輯,它可以對請求進行身份驗證、訪問控制和權限校驗,確保只有經過授權的請求能夠訪問后端的微服務,提供統一的安全策略。
4.日志和監控
微服務網關可以記錄請求和響應的日志,并提供監控和分析功能,這樣可以追蹤和監控系統的運行情況,幫助進行故障排查和性能優化。
微服務的負載均衡
微服務負載均衡是在微服務架構中管理和分發請求的關鍵組成部分,確保各個微服務實例能夠有效地分擔負載并提供高可用性和性能。
1.輪詢算法:輪詢算法是最簡單的負載均衡算法之一。它按照順序將請求依次分配給每個后端服務器,循環往復。當請求到達時,負載均衡器按照事先定義的順序選擇下一個服務器。輪詢算法適用于后端服務器具有相同的處理能力和性能的場景。
2.加權輪詢算法:加權輪詢算法在輪詢算法的基礎上增加了權重的概念。每個后端服務器都被賦予一個權重值,權重值越高,被選中的概率就越大。這樣可以根據服務器的處理能力和性能調整請求的分配比例,使得性能較高的服務器能夠處理更多的請求。
3.隨機算法:隨機算法將請求隨機分配給后端服務器。每個后端服務器有相等的被選中概率,沒有考慮服務器的實際負載情況。這種算法簡單快速,適用于后端服務器性能相近且無需考慮請求處理能力的場景。
4.加權隨機算法:加權隨機算法在隨機算法的基礎上引入了權重的概念。每個后端服務器被賦予一個權重值,權重值越高,被選中的概率就越大。這樣可以根據服務器的處理能力和性能調整請求的分配比例。
5.最少連接算法:最少連接算法會根據后端服務器當前的連接數來決定請求的分配。負載均衡器會選擇當前連接數最少的服務器進行請求分配,以保證后端服務器的負載均衡。這種算法適用于后端服務器的處理能力不同或者請求的處理時間不同的場景。
6.哈希算法:哈希算法會根據請求的某個特定屬性(如客戶端IP地址、請求URL等)計算哈希值,然后根據哈希值選擇相應的后端服務器。
常見的負載均衡器,比如Ribbion、Fegin等等,基本都支持這些負載均衡算法。
微服務的容災機制
服務崩潰
在了解服務容災之前,我們先連接服務崩潰,在微服務中,假如一個或者多個服務出現故障,如果這時候,依賴的服務還在不斷發起請求,或者重試,那么這些請求的壓力會不斷在下游堆積,導致下游服務的負載急劇增加。不斷累計之下,可能會導致故障的進一步加劇,可能會導致級聯式的失敗,甚至導致整個系統崩潰,這就叫服務雪崩。
服務容災機制
在微服務架構中,容災是確保系統在面對各種災難性事件時能夠繼續提供服務的重要方面。以下是一些常見的微服務容災策略:
1.服務實例的多副本部署:為每個微服務部署多個實例,并將它們分布在不同的物理服務器、虛擬機或容器中。這樣可以確保即使某個實例發生故障,其他實例仍然可以繼續提供服務。
2.健康檢查和自動恢復:實現對微服務實例的健康檢查機制,定期檢查實例的健康狀態。當某個實例被檢測到不健康時,自動從負載均衡器中移除,并嘗試恢復或替換該實例。
3.服務治理和容錯機制:通過服務治理框架(如Netflix的Hystrix)實現容錯機制,包括超時控制、斷路器模式、降級處理等。這些機制可以在服務出現故障或延遲時提供備用方案或快速失敗,從而保護系統免受級聯故障的影響。
4.多數據中心部署:在不同的地理位置或數據中心部署微服務的副本,以提供地域性容災。當一個數據中心發生故障時,流量可以自動轉移到其他數據中心上,確保系統的可用性。
5.數據備份和復原:對于需要持久化數據的微服務,實施定期的數據備份和恢復策略。確保數據能夠在災難事件中快速恢復,減少數據丟失和業務中斷的風險。
6.災難恢復演練:定期進行災難恢復演練,測試容災方案的有效性,并發現和解決潛在的問題。這有助于提高團隊對災難事件的應對能力,確保系統在面對實際災難時能夠做出及時和有效的響應。
微服務熔斷機制
微服務熔斷機制是一種用于提高微服務系統穩定性和可用性的重要技術,它可以在面對服務故障或延遲時,通過快速失敗和降級處理來保護系統免受級聯故障的影響。以下是微服務熔斷機制的核心概念和原理:
1.斷路器模式:
熔斷機制通常采用斷路器模式實現,類似于電路中的斷路器。斷路器監控對某個服務的調用,當連續失敗的次數達到閾值時,斷路器會打開,阻止對該服務的調用。
打開斷路器后,所有請求將立即失敗,而無需等待超時。這可以避免對不可用的服務發起大量的請求,從而減輕系統負擔,并使服務有更多的時間來恢復正常狀態。
2.熔斷器狀態:
斷路器通常有三個狀態:關閉(Closed)、打開(Open)和半開(Half-Open)。
當服務調用成功時,斷路器保持關閉狀態;當連續失敗的次數達到閾值時,斷路器切換到打開狀態;在打開一段時間后,斷路器進入半開狀態,允許部分請求通過以檢測服務的可用性。
3.熔斷器參數:
熔斷器通常配置有以下參數:
失敗閾值:連續失敗的次數達到該閾值時打開斷路器。
超時時間:等待服務響應的最大時間。
半開狀態持續時間:在打開斷路器后等待多久進入半開狀態。
4.降級處理:
當服務熔斷打開時,Hystrix可以提供一個備用的降級方法或返回默認值,以保證系統繼續正常運行。開發者可以定義降級邏輯,例如返回緩存數據、執行簡化的邏輯或調用其他可靠的服務,以提供有限但可用的功能。
5.健康檢查和自動恢復:
在斷路器打開后,可以定期進行健康檢查,以檢測服務是否已經恢復正常。當服務恢復正常時,斷路器會逐漸關閉,恢復對該服務的調用。
微服務熔斷機制通過斷路器模式和降級處理,有效地保護系統免受不可用服務的影響,并提高了系統的穩定性和可用性。
微服務限流
微服務限流是指在微服務架構中對服務的訪問進行限制,以確保系統在高負載情況下依然能夠正常運行。限流的目的是防止某個服務被過度請求而導致其它服務無法正常工作,或者是防止某些請求對系統造成過大的壓力,導致系統性能下降或崩潰。
有幾種常見的微服務限流策略:
1.基于并發數的限流:限制同時對某個服務的并發請求數量。這可以通過使用信號量、線程池或類似的機制來實現。
2.基于請求速率的限流:限制每個時間窗口內的請求速率。例如,可以限制每秒鐘對某個服務的請求數量。
3.基于資源消耗的限流:限制某個服務在一段時間內所消耗的資源,如CPU、內存或網絡帶寬。
4.基于用戶或客戶端的限流:針對特定用戶、客戶端或IP地址的請求進行限制,以防止惡意行為或異常情況。
5.動態限流:根據系統當前的負載情況自動調整限流策略,以適應不同的工作負載。
實施微服務限流需要根據具體的業務場景和系統特點來選擇合適的策略,并結合監控和告警系統進行動態調整和管理。
Sentinel怎么實現限流
Sentinel通過動態管理限流規則,根據定義的規則對請求進行限流控制。具體實現步驟如下:
1.通過注解
@SentinelResource定義資源:在Sentinel中,資源可以是URL、方法等,用于標識需要進行限流的請求。
// 原本的業務方法.
@SentinelResource(blockHandler = "blockHandlerForGetUser")
public User getUserById(String id) {throw new RuntimeException("getUserById command failed");
}// blockHandler 函數,原方法調用被限流/降級/系統保護的時候調用
public User blockHandlerForGetUser(String id, BlockException ex) {return new User("admin");
}
@SentinelResource 注解屬性說明:
value:資源名稱,必需項(不能為空)。
entryType:資源調用的流量類型:入口流量(EntryType.IN)和出口流量(EntryType.OUT),注意系統規則只對 IN 生效。
blockHandler/blockHandlerClass: 限流和熔斷時執行 BlockException 所對應的方法名。
fallback/fallbackClass:非 BlockException 時,其他非限流、非熔斷時異常對應的方法。
exceptionsToIgnore:用于指定哪些異常被排除掉,不會計入異常統計中,也不會進入 fallback 邏輯中,而是會原樣拋出。
2.通過代碼定義資源實現限流規則:
可以通過代碼的的方式 SphU.entry(“resourceName”) 來定義資源,具體實現代碼如下:
@RequestMapping("/getUser")
public String getUser() {try (Entry entry = SphU.entry("getUser")) {// 被保護邏輯return "VO";} catch (Exception e) {// 限流之后的業務邏輯return "此接口被限流了";}
}
2.配置限流規則:在Sentinel的配置文件中定義資源的限流規則。規則可以包括資源名稱、限流閾值、限流模式(令牌桶或漏桶)等。
private static void initFlowQpsRule() {List<FlowRule> rules = new ArrayList<>();FlowRule rule1 = new FlowRule();rule1.setResource(resource);//資源名稱// Set max qps to 20rule1.setCount(20);//限制的QPS閾值(每秒鐘只允許20個請求)rule1.setGrade(RuleConstant.FLOW_GRADE_QPS);//根據QPS限流rule1.setLimitApp("default");//流控效果rule1.setStrtegy(RuleConstant.STRATEGY_DIRECT);//調用關系限流策略,非必須設置rule1.setControlBehavior(RuleConstant.CONTROL_BEHAVIOR_DEFAULT); // 流控效果【非必須設置】rule1.setClusterMode(false);//是否設置集群限流(非必須設置,默認為非集群)rules.add(rule1);FlowRuleManager.loadRules(rules);
}
setStrategy:設置調用關系限流策略,包含的值有:
直接(RuleConstant.STRATEGY_DIRECT)【默認值】
鏈路(RuleConstant.STRATEGY_RELATE)
關聯(RuleConstant.STRATEGY_CHAIN)
setControlBehavior:設置流控效果,包含的值有:
直接拒絕(RuleConstant.CONTROL_BEHAVIOR_DEFAULT)【默認值】
冷啟動(RuleConstant.CONTROL_BEHAVIOR_WARM_UP)
勻速啟動(RuleConstant.CONTROL_BEHAVIOR_RATE_LIMITER)
冷啟動+勻速啟動(RuleConstant.CONTROL_BEHAVIOR_WARM_UP_RATE_LIMITER)
微服務限流算法
1.令牌桶算法
令牌桶算法是一種流量控制算法,用于限制在任意時間單位內通過的請求速率。它基于令牌桶的概念,具有固定的容量,其中以固定的速率往桶中添加令牌。當一個請求到達時,需要從桶中獲取一個令牌,如果桶中有足夠的令牌,則請求被允許通過;否則,請求被拒絕或者延遲處理。
令牌桶算法的基本原理和步驟:
1.令牌桶:算法維護一個固定容量的令牌桶,其中以固定的速率向桶中添加令牌。
2.令牌生成:桶中以恒定的速率生成令牌,通常每隔固定時間生成一個令牌,或者以固定的速率生成令牌。
3.請求處理:當一個請求到達時,需要從令牌桶中獲取一個令牌。如果桶中有足夠的令牌,則將一個令牌移出桶,并處理該請求;否則,請求被拒絕或者延遲處理。
4.令牌補充:如果請求未被拒絕,則在處理請求后,可以選擇將一個新的令牌放入桶中,以確保下一個請求可以及時被處理。
令牌桶算法的優點包括:
允許短時間內的突發流量,因為如果令牌桶中有足夠的令牌,請求可以立即被處理。
允許動態調整請求處理的速率,只需調整令牌生成的速率即可。
簡單且高效,適用于各種場景下的流量控制。
然而,令牌桶算法也有一些缺點,比如對于突發流量的處理可能不夠靈活,因為令牌桶中的令牌數量是固定的。
2.漏斗桶算法
漏斗算法是一種用于流量控制的算法,類似于令牌桶算法。它基于一個類比:將請求想象成水流,桶就像是一個漏斗,而請求則是水滴。漏斗以固定的速率流水,當水滿了漏斗則會溢出。在漏斗算法中,漏斗以固定的速率處理請求,如果請求到達速率超過漏斗處理的速率,則請求會被拒絕或延遲處理。
漏斗算法的基本原理和步驟:
漏斗:算法維護一個固定容量的漏斗,類似于一個定時漏水的容器。
漏水速率:漏斗以固定的速率處理請求,類比為漏斗定時地漏水。
請求處理:當一個請求到達時,漏斗會處理請求,類比為漏斗裝滿水。如果請求到達速率超過漏斗的處理速率,則漏斗會溢出,表示請求被拒絕或者延遲處理。
漏斗空出:當漏斗溢出時,表示系統無法處理更多的請求,需要等待一段時間,直到漏斗空出了一些空間。
漏斗算法的優點包括:
允許短時間內的突發流量,因為如果漏斗尚未溢出,則請求可以立即被處理。
允許動態調整請求處理的速率,只需調整漏水的速率即可。
簡單且高效,適用于各種場景下的流量控制。
然而,與令牌桶算法相比,漏斗算法在某些情況下可能表現得更為寬松,因為漏斗的處理速率是固定的,無法動態調整,可能會導致系統對于突發流量的處理不夠靈活。
服務監控
我們使用Prometheus和Grafana來實現整個微服務集群的監控和告警:
Prometheus:Prometheus 是一個開源的監控系統,具有靈活的數據模型和強大的查詢語言,能夠收集和存儲時間序列數據。它可以通過HTTP協議定期拉取微服務的指標數據,并提供可擴展的存儲和查詢功能。
Grafana:Grafana 是一個開源的可視化儀表板工具,可以與 Prometheus 結合使用,創建實時和歷史數據的儀表板。Grafana 提供了豐富的圖表和可視化選項,可以幫助用戶更好地理解和分析微服務的性能和狀態。
日志收集
日志收集有很多種方案,我們用的是ELK:
Elasticsearch:Elasticsearch是一個分布式搜索和分析引擎,用于存儲和索引大量的日志數據。它提供了快速的搜索和聚合功能,可以高效地處理大規模的日志數據。
Logstash:Logstash是一個用于收集、過濾和轉發日志數據的工具。它可以從各種來源(如文件、網絡、消息隊列等)收集日志數據,并對數據進行處理和轉換,然后將其發送到Elasticsearch進行存儲和索引。
Kibana:Kibana是一個用于日志數據可視化和分析的工具。它提供了豐富的圖表、儀表盤和搜索功能,可以幫助用戶實時監控和分析日志數據,發現潛在的問題和趨勢。
簡單說,這三者里Elasticsearch提供數據存儲和檢索能力,Logstash負責將日志收集到ES,Kibana負責日志數據的可視化分析。
使用ELK進行微服務日志收集的一般流程如下:
(1)通過FileBeat采集服務器上的日志,然后將采集好的日志推送到Kafka中。此時為什么不直接將采集的日志推送到Logstash呢?因為logstash在并發量很大的時候容易丟失數據,所以為了保證數據不丟失我們采用Kafka將流量消峰然后把數據推送給Logstash消費。
(2)kafka將隊列中的日志數據給Logstash消費,Logstash將數據做定制化處理,處理好數據后再推送到ES指定的索引中。
(3)ES收到Logstash推送的數據之后存儲對于索引的分片中,由于ES自身的特性,針對海量數據處理能力還是很優秀的。
(4)開發人員或運維人員通過Kinaba可視化平臺查詢ES中的數據。