1. 基礎知識[1]
什么是微服務架構心软?
- 微服務是系統(tǒng)架構上的一種設計風格;
- 主旨是將一個原本獨立的系統(tǒng)拆分成多個小型服務依许;
- 這些小型服務都在各自獨立的進程中運行迟杂;
-
服務之間通過基于HTTP的RESTful API進行通信協(xié)作刽沾。
被拆分成的每一個小型服務都圍繞著系統(tǒng)中的某一項或一些耦合度較高的業(yè)務功能進行構建,并且每個服務都維護著自身的數(shù)據(jù)存儲排拷、業(yè)務開發(fā)侧漓、自動化測試案例以及獨立部署機制。
與單體系統(tǒng)的區(qū)別
1监氢、單體系統(tǒng)部署在一個進程內(nèi)布蔗,修改一個很小的功能,為部署上線會影響其他功能的運行浪腐;
2纵揍、單體應用中的各功能模塊的使用場景、并發(fā)量牛欢、消耗的資源類型各不相同骡男,對資源的利用又互相影響,這樣使得我們對各個業(yè)務模塊的系統(tǒng)容量很難給出較為準確的評估傍睹;
3隔盛、單體系統(tǒng)雖然初期方便開發(fā)和使用,但隨著系統(tǒng)的發(fā)展拾稳,維護成本會變得越來越大吮炕,難以控制。
如何實施微服務访得?
1龙亲、服務組件化
組件,是一個可以獨立更換和升級的單元悍抑。就像PC中的CPU鳄炉、內(nèi)存、顯卡搜骡、硬盤一樣拂盯,獨立且可以更換升級而不影響其他單元。
在“微服務”架構中记靡,需要我們對服務進行組件化分解谈竿。服務,是一種進程外的組件摸吠,它通過http等通信協(xié)議進行協(xié)作空凸,而不是傳統(tǒng)組件以嵌入的方式協(xié)同工作。服務都獨立開發(fā)寸痢、部署呀洲,可以有效的避免一個服務的修改引起整個系統(tǒng)的重新部署。
2、按業(yè)務組織團隊
當我們開始決定如何劃分“微服務”時两嘴,通常也意味著我們要開始對團隊進行重新規(guī)劃與組織丛楚。按以往的方式,我們往往會以技術的層面去劃分多個不同的團隊憔辫,比如:DBA團隊趣些、運維團隊、后端團隊贰您、前端團隊坏平、設計師團隊等等。若我們繼續(xù)按這種方式組織團隊來實施“微服務”架構開發(fā)時锦亦,當有一個有問題需要更改舶替,可能是一個非常簡單的變動,比如:對人物描述增加一個字段杠园,這就需要從數(shù)據(jù)存儲開始考慮一直到設計和前端顾瞪,雖然大家的修改都非常小,但這會引起跨團隊的時間和預算審批抛蚁。
在實施“微服務”架構時陈醒,需要采用不同的團隊分割方法。由于每一個微服務都是針對特定業(yè)務的寬椙扑Γ或是全棧實現(xiàn)钉跷,既要負責數(shù)據(jù)的持久化存儲,又要負責用戶的接口定義等各種跨專業(yè)領域的職能肚逸。因此爷辙,面對大型項目時候,對于微服務團隊拆分更加建議按業(yè)務線的方式進行拆分朦促,一方面可以有效減少服務內(nèi)部修改所產(chǎn)生的內(nèi)耗膝晾;另一方面,團隊邊界可以變得更為清晰务冕。
3血当、做“產(chǎn)品”的態(tài)度
實施“微服務”架構的團隊中,每個小團隊都應該以做產(chǎn)品的方式洒疚,對其產(chǎn)品的整個生命周期負責。而不是以項目的模式坯屿,以完成開發(fā)與交付并將成果交接給維護者為最終目標油湖。
開發(fā)團隊通過了解服務在具體生產(chǎn)環(huán)境中的情況,可以增加他們對具體業(yè)務的理解领跛,比如:很多時候一些業(yè)務中發(fā)生的特殊或異常情況乏德,很可能產(chǎn)品經(jīng)理都并不知曉,但細心的開發(fā)者很容易通過生產(chǎn)環(huán)境發(fā)現(xiàn)這些特殊的潛在問題或需求。
所以喊括,我們需要用做“產(chǎn)品”的態(tài)度來對待每一個“微服務”胧瓜,持續(xù)關注服務的運作情況,并不斷地分析幫助用戶來提升業(yè)務功能郑什。
4府喳、輕量化通信機制
在單體應用中,組件間直接通過函數(shù)調(diào)用的方式進行交互協(xié)作蘑拯。而在“微服務”架構中钝满,服務由于不在一個進程中,組件間的通信模式發(fā)生了改變申窘,若僅僅將原本在進程內(nèi)的方法調(diào)用改成RPC方式的調(diào)用弯蚜,會導致微服務之間產(chǎn)生繁瑣的通信,使得系統(tǒng)表現(xiàn)更為糟糕剃法,所以碎捺,我們需要更粗粒度的通信協(xié)議。
在“微服務”架構中贷洲,通常會使用這兩個服務調(diào)用方式:
第一種收厨,使用HTTP協(xié)議的RESTful API或輕量級的消息發(fā)送協(xié)議,來實現(xiàn)信息傳遞與服務調(diào)用的觸發(fā)恩脂。
第二種帽氓,通過在輕量級消息總線上傳遞消息,類似RabbitMQ等一些提供可靠異步交換的結構俩块。
在極度強調(diào)性能的情況下黎休,有些團隊會使用二進制的消息發(fā)送協(xié)議,例如:protobuf玉凯。
5势腮、去中心化治理
當我們采用集中化的架構治理方案時,通常在技術平臺上都會做統(tǒng)一的標準漫仆,但是每一種技術平臺都有其短板捎拯,這會導致在碰到短板時,不得不花費大力氣去解決盲厌,并且可能還是因為其底層原因解決的不是很好署照。
在實施“微服務”架構時,通過采用輕量級的契約定義接口吗浩,使得我們對于服務本身的具體技術平臺不再那么敏感建芙,這樣我們整個“微服務”架構的系統(tǒng)中的組件就能針對其不同的業(yè)務特點選擇不同的技術平臺,終于不會出現(xiàn)殺雞用牛刀或是殺牛用指甲鉗的尷尬處境了懂扼。
6禁荸、去中心化管理數(shù)據(jù)
我們在實施“微服務”架構時右蒲,都希望可以讓每一個服務來管理其自有的數(shù)據(jù)庫,這就是數(shù)據(jù)管理的去中心化赶熟。
在去中心化過程中瑰妄,我們除了將原數(shù)據(jù)庫中的存儲內(nèi)容拆分到新的同平臺的其他數(shù)據(jù)庫實例中之外(如:把原本存儲在MySQL中的表拆分后,存儲多幾個不同的MySQL實例中)映砖,也可以針對一些具有特殊結構或業(yè)務特性的數(shù)據(jù)存儲到一些其他技術的數(shù)據(jù)庫實例中(如:把日志信息存儲到MongoDB中间坐、把用戶登錄信息存儲到Redis中)。
雖然啊央,數(shù)據(jù)管理的去中心化可以讓數(shù)據(jù)管理更加細致化眶诈,通過采用更合適的技術來讓數(shù)據(jù)存儲和性能達到最優(yōu)。但是瓜饥,由于數(shù)據(jù)存儲于不同的數(shù)據(jù)庫實例中后逝撬,數(shù)據(jù)一致性也成為“微服務”架構中急需解決的問題之一。分布式事務的實現(xiàn)乓土,本身難度就非常大宪潮,所以在“微服務”架構中,我們更強調(diào)在各服務之間進行“無事務”的調(diào)用趣苏,而對于數(shù)據(jù)一致性狡相,只要求數(shù)據(jù)在最后的處理狀態(tài)是一致的效果;若在過程中發(fā)現(xiàn)錯誤食磕,通過補償機制來進行處理尽棕,使得錯誤數(shù)據(jù)能夠達到最終的一致性。
7彬伦、基礎設施自動化
近年來云計算服務與容器化技術的不斷成熟滔悉,運維基礎設施的工作變得越來越不那么難了。但是单绑,當我們實施“微服務”架構時回官,數(shù)據(jù)庫、應用程序的個頭雖然都變小了搂橙,但是因為拆分的原因歉提,數(shù)量成倍的增長。這使得運維人員需要關注的內(nèi)容也成倍的增長区转,并且操作性任務也會成倍的增長苔巨,這些問題若沒有得到妥善的解決,必將成為運維人員的噩夢废离。
所以侄泽,在“微服務”架構中,請務必從一開始就構建起“持續(xù)交付”平臺來支撐整個實施過程厅缺,該平臺需要兩大內(nèi)容蔬顾,不可或缺:
自動化測試:每次部署前的強心劑,盡可能的獲得對正在運行軟件的信心湘捎。
自動化部署:解放繁瑣枯燥的重復操作以及對多環(huán)境的配置管理诀豁。
8、容錯設計
在單體應用中窥妇,一般不存在單個組件故障而其他還在運行的情況舷胜,通常是一掛全掛。而在“微服務”架構中活翩,由于服務都運行在獨立的進程中烹骨,所以是存在部分服務出現(xiàn)故障,而其他服務都正常運行的情況材泄,比如:當正常運作的服務B調(diào)用到故障服務A時沮焕,因故障服務A沒有返回,線程掛起開始等待拉宗,直到超時才能釋放峦树,而此時若觸發(fā)服務B調(diào)用服務A的請求來自服務C,而服務C頻繁調(diào)用服務B時旦事,由于其依賴服務A魁巩,大量線程被掛起等待,最后導致服務C也不能正常服務姐浮,這時就會出現(xiàn)故障的蔓延谷遂。
所以,在“微服務”架構中卖鲤,快速的檢測出故障源并盡可能的自動恢復服務是必須要被設計和考慮的肾扰。通常,我們都希望在每個服務中實現(xiàn)監(jiān)控和日志記錄的組件扫尖,比如:服務狀態(tài)白对、斷路器狀態(tài)、吞吐量换怖、網(wǎng)絡延遲等關鍵數(shù)據(jù)的儀表盤等甩恼。
9、演進式設計
通過上面的幾點特征沉颂,我們已經(jīng)能夠體會到条摸,要實施一個完美的“微服務”架構,需要考慮的設計與成本并不小铸屉,對于沒有足夠經(jīng)驗的團隊來說钉蒲,甚至要比單體應用發(fā)付出更多的代價。
所以彻坛,很多情況下顷啼,架構師們都會以演進的方式進行系統(tǒng)的構建踏枣,在初期系統(tǒng)以單體系統(tǒng)的方式來設計和實施,一方面系統(tǒng)體量初期并不會很大钙蒙,構建和維護成本都不高茵瀑。另一方面,初期的核心業(yè)務在后期通常也不會發(fā)生巨大的改變躬厌。隨著系統(tǒng)的發(fā)展或者業(yè)務的需要马昨,架構師們會將一些經(jīng)常變動或是有一定時間效應的內(nèi)容進行“微服務”處理,并逐漸地將原來在單體系統(tǒng)中多變的模塊逐步拆分出來扛施,而穩(wěn)定不太變化的就形成了一個核心“微服務”存在于整個架構之中鸿捧。
微服務優(yōu)缺點
為什么選擇Spring Cloud?
微服務技術選型
功能項 | 阿里&淘寶 | 當當 | 百度 | 360 | 京東 | Netflix | Apache | SpringCloud | ||
---|---|---|---|---|---|---|---|---|---|---|
服務治理 | Dubbo | Dubbox | Eureka | Consoul | ||||||
分布式配置管理 | Diamond | Disconf | Qconf | Archaius | Config | |||||
批量任務 | Elastic-Job | Task | Azkaban | |||||||
服務跟蹤 | Hydra | Sleuth | Zipkin |
選擇如此之多疙渣,必然導致技術選型初期需要花費巨大的調(diào)研匙奴、分析與實驗精力。
為什么選擇Spring Cloud妄荔?
- SpringCloud不只是解決微服務的某一個問題饥脑,而是一個解決微服務架構實施的綜合性解決框架;
- 整合了諸多被廣泛實踐和證明過的框架作為實施的基礎部件懦冰,又在該體系基礎上創(chuàng)建了一些非常優(yōu)秀的邊緣組件灶轰;
- 大量的兼容性測試,保證了更好的穩(wěn)定性刷钢;
- 極高的社區(qū)活躍度笋颤。
Spring Cloud簡介
這是一個Spring Cloud生態(tài)簡圖。
Spring Cloud是一個基于Spring Boot實現(xiàn)的微服務架構開發(fā)工具内地。它為微服務架構中涉及的服務治理伴澄、斷路器、負載均衡阱缓、配置管理非凌、控制總線和集群狀態(tài)管理等操作提供了一種簡單的開發(fā)方式。
1荆针、外部或者內(nèi)部的非Spring Cloud項目都統(tǒng)一通過API網(wǎng)關(Zuul)來訪問內(nèi)部服務敞嗡。
2、網(wǎng)關接收到請求后航背,從注冊中心(Eureka)獲取可用服務喉悴。
3、由Ribbon進行均衡負載后玖媚,分發(fā)到后端的具體實例箕肃。
4、微服務之間通過Feign進行通信處理業(yè)務今魔。
5勺像、Hystrix負責處理服務超時熔斷障贸。
6、Turbine監(jiān)控服務間的調(diào)用和熔斷相關指標吟宦。
圖中沒有畫出配置中心惹想,配置中心管理各微服務不同環(huán)境下的配置文件。
2. 微服務構建Spring Boot
與傳統(tǒng)Spring框架的區(qū)別督函?
傳統(tǒng)Spring框架:
1、配置web.xml激挪,加載spring和spring mvc辰狡;
2柬帕、配置數(shù)據(jù)庫連接舱殿、配置spring事務;
3跌捆、配置加載配置文件的讀取薄湿,開啟注解叫倍;
4、配置日志文件豺瘤;
5吆倦、配置完成之后部署tomcat 調(diào)試;
…
Spring Boot:
1坐求、大量的自動化配置簡化了Spring原有樣板化的配置蚕泽;
2、類似模塊化的Starter POMs的定義桥嗤,不需要在pom.xml中維護錯綜復雜的依賴關系须妻;
3、可以很好的融入Docker泛领,自身支持嵌入的Tomcat荒吏、Jetty等容器。
實例略
3. 服務治理Spring Cloud Eureka
服務提供者
- 服務注冊
在服務注冊時渊鞋,需要確認下eureka.client.register-with-eureka=true參數(shù)是否正確绰更,默認為true,若設置為false將不會啟動注冊操作锡宋。 - 服務同步
由于服務注冊中心之間因互相注冊為服務动知,當服務提供者發(fā)送注冊請求到一個服務注冊中心,它會將該請求轉(zhuǎn)發(fā)給集群中相連的其他注冊中心员辩,從而實現(xiàn)注冊中心之間的服務同步盒粮。 - 服務續(xù)約
eureka.instance.lease-renewal-interval-in-seconds參數(shù)用于定義服務續(xù)約任務的調(diào)用間隔時間默認30秒。
eureka.instance.lease-exptration-duration-in-seconds參數(shù)用于定義服務失效時間奠滑,默認為90秒丹皱。
服務消費者
- 獲取服務
當我們啟動服務消費者時候妒穴,它會發(fā)送一個REST請求給服務注冊中心,來獲取上面注冊的服務清單摊崭。為了性能考慮讼油,Eureka Server會維護一份只讀的服務清單來返回給客戶端,同時該緩存清單會每隔30秒更新一次呢簸。
獲取服務是服務消費者的基礎矮台,必須確保eureka.client.fetch-registry=true參數(shù)沒有被修改成為false,該值默認為true根时。若希望修改緩存清單的更新時間瘦赫,可以通過eureka.client.registry-fetch-interval-seconds=30參數(shù)進行修改,默認30蛤迎,單位為秒确虱。 - 服務調(diào)用
服務消費者在獲取服務清單后,通過服務名可以獲得具體提供服務的實例名和該實例的元數(shù)據(jù)替裆。因為有這些服務實例的詳細信息校辩,所以客戶端可以根據(jù)自己的需要決定具體調(diào)用哪個實例。
對于訪問實例的選擇辆童,Eureka中有Rigion和Zone的概念宜咒,一個Region中可以包含多個Zone,每個服務客戶端需要被注冊到一個Zone中把鉴,所以每個客戶端對應一個Region和一個Zone荧呐。在進行服務調(diào)用時候,優(yōu)先訪問同處一個Zone中的服務提供方纸镊,若訪問不到倍阐,就訪問其他的Zone。
服務注冊中心
- 失效剔除
默認每隔一段時間(默認60秒)將當前清單中超時(默認為90秒)沒有續(xù)約的服務剔除出去逗威。
但是當網(wǎng)絡分區(qū)故障發(fā)生時峰搪,微服務與Eureka Server之間無法正常通信,而微服務本身是正常運行的凯旭,此時不應該移除這個微服務概耻,所以引入了自我保護機制。 - 自我保護
服務注冊到Eureka Server之后罐呼,會維護一個心跳連接鞠柄,告訴Eureka Server自己還活著。Eureka Server在運行期間嫉柴,會統(tǒng)計心跳失敗的比例在15分鐘之內(nèi)是否低于85%厌杜,如果出現(xiàn)低于的情況,Eureka Server會將當前的實例注冊信息保護起來,讓這些實例不會過期夯尽,盡可能保護這些注冊信息瞧壮。
eureka.instance.leaseRenewalIntervalInSeconds = 30 # client發(fā)送心跳的頻率
eureka.server.renewalPercentThreshold = 0.85 #觸發(fā)自我保護的心跳數(shù)比例閾值
eureka.server.renewalThresholdUpdateIntervalMs = 15 * 60 * 1000 # 多久重置一下心跳閾值(15mins)
當Eureka Server自動進入自我保護機制,會出現(xiàn)以下幾種情況:
1匙握、Eureka Server不再從注冊列表中移除因為長時間沒收到心跳而應該過期的服務咆槽。
2、Eureka Server仍然能夠接受新服務的注冊和查詢請求圈纺,但是不會被同步到其它節(jié)點上秦忿,保證當前節(jié)點依然可用。
3蛾娶、當網(wǎng)絡穩(wěn)定時灯谣,當前Eureka Server新的注冊信息會被同步到其它節(jié)點中。
在這段保護期間內(nèi)實例若出現(xiàn)問題茫叭,那么客戶端很容易按到實際不存在的服務實例,會出現(xiàn)調(diào)用失敗的情況半等,所以客戶端必須要有容錯機制揍愁,比如可以使用請求重試、斷路器等機制杀饵。
自我保護模式正是一種針對網(wǎng)絡異常波動的安全保護措施莽囤,使用自我保護模式能使Eureka集群更加的健壯、穩(wěn)定的運行切距。
由于本地調(diào)試很容易觸發(fā)注冊中心的保護機制朽缎,這會使得注冊中心維護的服務實例不那么準確。所以谜悟,本地開發(fā)時话肖,可以使用eureka.server.enable-self-preservation=false參數(shù)來關閉保護機制,以確保注冊中心可以將不可用實例正確剔除葡幸。
實例略
4.客戶端負載均衡Spring Cloud Ribbon
1最筒、通常所說的負載均衡都指的是服務端負載均衡,其中分為硬件負載均衡和軟件負載均衡蔚叨。
硬件負載均衡主要通過在服務器節(jié)點之間安裝專門用于負載均衡的設備床蜘,比如F5等;而軟件負載均衡則是通過在服務器上安裝一些具有負載均衡功能或模塊的軟件來完成請求分發(fā)工作蔑水,比如Nigix等邢锯。
2、硬件負載均衡的設備或是軟件負載均衡的軟件模塊都會維護一個下掛可用的服務端清單搀别,通過心跳檢測來剔除故障的服務端節(jié)點以保證清單中都是可以正常訪問的服務端節(jié)點丹擎。當客戶端發(fā)送請求到負載均衡設備時,該設備按照某種算法(比如線性輪詢歇父、按權重負載鸥鹉、按流量負載等)從維護的可用服務端清單中取出一臺服務端的地址蛮穿,然后進行轉(zhuǎn)發(fā)。
3毁渗、客戶端負載均衡和服務器負載均衡最大的不同點在于上面所提到的服務清單所存儲的位置践磅。在客戶端負載均衡中,所有客戶端節(jié)點都維護著自己要訪問的服務端清單灸异,而這些服務端的清單來自于服務注冊中心府适。
實例略
5.服務容錯保護Spring Cloud Hystrix
服務之間相互依賴
單服務異常導致雪崩
Hystrix 通過如上機制來解決雪崩效應問題,還支持實時監(jiān)控肺樟、報警檐春、控制(修改配置)等。
資源隔離:包括線程池隔離和信號量隔離么伯,限制調(diào)用分布式服務的資源使用疟暖,某一個調(diào)用的服務出現(xiàn)問題不會影響其他服務調(diào)用。
降級機制:超時降級田柔、資源不足時(線程或信號量)降級俐巴,降級后可以配合降級接口返回托底數(shù)據(jù)。
熔斷:當失敗率達到閥值自動觸發(fā)降級(如因網(wǎng)絡故障/超時造成的失敗率高)硬爆,熔斷器觸發(fā)的快速失敗會進行快速恢復欣舵。
緩存:提供了請求緩存、請求合并實現(xiàn)缀磕。
資源隔離
1缘圈、線程池隔離模式:使用一個線程池來存儲當前請求,線程池對請求作處理袜蚕,設置任務返回處理超時時間糟把,堆積的請求先入線程池隊列。這種方式要為每個依賴服務申請線程池牲剃,有一定的資源消耗糊饱,好處是可以應對突發(fā)流量(流量洪峰來臨時,處理不完可將數(shù)據(jù)存儲到線程池隊里慢慢處理)
2颠黎、信號量隔離模式:使用一個原子計數(shù)器(或信號量)記錄當前有多少個線程在運行另锋,請求來先判斷計數(shù)器的數(shù)值,若超過設置的最大線程個數(shù)則丟棄該類型的新請求狭归,若不超過則執(zhí)行計數(shù)操作請求來計數(shù)器+1夭坪,請求返回計數(shù)器-1。這種方式是嚴格的控制線程且立即返回模式过椎,無法應對突發(fā)流量(流量洪峰來臨時室梅,處理的線程超過數(shù)量,其他的請求會直接返回,不繼續(xù)去請求依賴的服務)
降級機制
服務降級的目的保證上游服務的穩(wěn)定性亡鼠,當整體資源快不夠了赏殃,將某些服務先關掉,待渡過難關间涵,再開啟回來仁热。根據(jù)業(yè)務場景的不同,一般采用以下兩種模式:
第一種(最常用)如果服務失敗勾哩,則我們通過fallback進行降級抗蠢,返回靜態(tài)值。
第二種采用服務級聯(lián)的模式思劳,如過第一個服務失敗迅矛,則調(diào)用備用服務,例如失敗重試或者訪問緩存失敗再去數(shù)據(jù)庫潜叛。服務級聯(lián)的目的則是盡最大努力保證返回數(shù)據(jù)的成功性秽褒,但如果考慮不充分,則有可能導致級聯(lián)的服務崩潰(比如緩存失敗了威兜,把全部流量打到數(shù)據(jù)庫销斟,瞬間導致數(shù)據(jù)庫掛掉)。因此級聯(lián)模式牡属,也要慎用票堵,增加了管理的難度扼睬。
熔斷
正常情況下逮栅,斷路器處于關閉狀態(tài)(Closed),如果調(diào)用持續(xù)出錯或者超時(默認10秒內(nèi)超過20個請求次數(shù)或10秒內(nèi)超過50%的請求失敶坝睢)措伐,電路被打開進入熔斷狀態(tài)(Open),后續(xù)一段時間內(nèi)的所有調(diào)用都會被拒絕(Fail Fast)军俊,一段時間(默認是5秒)以后侥加,保護器會嘗試進入半熔斷狀態(tài)(Half-Open),允許少量請求進來嘗試粪躬,如果調(diào)用仍然失敗担败,則回到熔斷狀態(tài),如果調(diào)用成功镰官,則回到電路閉合狀態(tài)提前。
緩存
請求緩存可以讓(CommandKey/CommandGroup)相同的情況下,直接共享結果,降低依賴調(diào)用次數(shù)泳唠,在高并發(fā)和CacheKey碰撞率高場景下可以提升性能狈网。
命令調(diào)用合并允許多個請求合并到一個線程/信號下批量執(zhí)行。使用場景:HystrixCollapser用于對多個相同業(yè)務的請求合并到一個線程甚至可以合并到一個連接中執(zhí)行,降低線程交互次數(shù)和IO數(shù),但必須保證他們屬于同一依賴拓哺。
工作流程
1勇垛、 創(chuàng)建一個 HystrixCommand 或 HystrixObservableCommand 實例
第一步就是構建一個 HystrixCommand 或 HystrixObservableCommand 實例來向其它組件發(fā)出操作請求,通過構造方法來創(chuàng)建實例士鸥。
HystrixCommand:返回一個單響應
HystrixObservableCommand:返回一個觀察者發(fā)出的響應
2闲孤、 執(zhí)行方法
這里有4個方法,前兩個只適用于 HystrixCommand 不適用于 HystrixObservableCommand
execute():阻塞型方法础淤,返回單個結果(或者拋出異常)
queue():異步方法崭放,返回一個 Future 對象,可以從中取出單個結果(或者拋出異常)
observe():返回Observable 對象
toObservable():返回Observable 對象
3鸽凶、 緩存判斷
檢查緩存內(nèi)是否有對應指令的結果币砂,如果有的話,將緩存的結果直接以 Observable 對象的形式返回
4玻侥、 斷路器判斷
檢查Circuit Breaker的狀態(tài)决摧。如果Circuit Breaker的狀態(tài)為開啟狀態(tài),Hystrix將不會執(zhí)行對應指令凑兰,而是直接進入失敗處理狀態(tài)(圖中8)掌桩。如果Circuit Breaker的狀態(tài)為關閉狀態(tài),Hystrix會繼續(xù)執(zhí)行(圖5)
5姑食、 線程池波岛、任務隊列、信號量的檢查
確認是否有足夠的資源執(zhí)行操作指令音半。當線程池和隊列(或者是信號量则拷,當不使用線程池隔離模式的時候)資源滿的時候,Hystrix將不會執(zhí)行對應指令并且會直接進入失敗處理狀態(tài)(圖8)
6曹鸠、 HystrixObservableCommand.construct() 和 HystrixCommand.run()
如果資源充足煌茬,Hystrix將會執(zhí)行操作指令。操作指令的調(diào)用最終都會到這兩個方法:
HystrixCommand.run():返回一個響應或者拋出一個異常
HystrixObservableCommand.construct():返回一個可觀測的發(fā)出響應(s)或發(fā)送一個onError通知
如果執(zhí)行指令的時間超時彻桃,執(zhí)行線程會拋出 TimeoutException 異常坛善。Hystrix會拋棄結果并直接進入失敗處理狀態(tài)。如果執(zhí)行指令成功邻眷,Hystrix會進行一系列的數(shù)據(jù)記錄眠屎,然后返回執(zhí)行的結果。
7肆饶、 統(tǒng)計斷路器的健康情況
Hystrix會根據(jù)記錄的數(shù)據(jù)來計算失敗比率改衩,一旦失敗比率達到某一閾值將自動開啟Circuit Breaker
8、 回退
如果我們在Command中實現(xiàn)了HystrixCommand.getFallback()方法(或HystrixObservableCommand. resumeWithFallback() 方法抖拴,Hystrix會返回對應方法的結果燎字。如果沒有實現(xiàn)這些方法的話腥椒,仍然 Hystrix會返回一個空的 Observable 對象,并且可以通過 onError 來終止并處理錯誤候衍。
調(diào)用不同的方法返回不同的結果:
execute(): 將會拋出異常
queue(): 將會返回一個Future 對象笼蛛,如果調(diào)用它的get()方法將會拋出異常
observe()和 toObservable():都會返回上述的 Observable 對象
9、 返回成功
如果Hystrix執(zhí)行成功蛉鹿,返回的響應取決于在步驟2中調(diào)用命令滨砍。
execute():阻塞型方法,返回單個結果(或者拋出異常)
queue():異步方法妖异,返回一個 Future 對象惋戏,可以從中取出單個結果(或者拋出異常)
observe():返回Observable 對象
toObservable():返回Observable 對象
Dashboard
Turbine集群監(jiān)控
6.聲明式服務調(diào)用Spring Cloud Feign
實例略
-
參考資料:《Spring Cloud微服務實戰(zhàn)》 作者:翟永超 出版社:電子工業(yè)出版社 ?