幫你輕松入門SpringCloud~
1 微服務(wù)概述
1.1什么是微服務(wù)
如idea中使用maven建立的一個個moudle土思,它具體是使用SpringBoot開發(fā)的一個小模塊剩胁,專業(yè)的事交給專業(yè)的模塊來做,每個模塊完成一個具體的任務(wù)或功能。
1.2 什么是微服務(wù)架構(gòu)
它將單一應(yīng)用程序劃分成一組小的服務(wù)雹熬,服務(wù)之間相互協(xié)調(diào)敬惦,相互配合,服務(wù)與服務(wù)之間采用輕量級的通信機(jī)制(如Rest(基于HTTP)、RPC(dubbo))互相協(xié)作智亮,每個服務(wù)都圍繞著具體的業(yè)務(wù)進(jìn)行構(gòu)建退疫,并且能夠獨立部署在生產(chǎn)環(huán)境中(一個個jar包(springboot)),每個服務(wù)可以選擇自己合適的語言、工具對其進(jìn)行構(gòu)建
1.3 微服務(wù)優(yōu)缺點
優(yōu)點:
1.單一職責(zé)原則鸽素;
2.服務(wù)之間低耦合褒繁,服務(wù)內(nèi)部高內(nèi)聚;
3.開發(fā)簡單馍忽,效率高棒坏,一個服務(wù)專一的干一件事;
4.每個服務(wù)在開發(fā)階段或部署階段都是獨立的遭笋,可以有自己的數(shù)據(jù)庫
5.每個服務(wù)可以選擇使用不同的語言開發(fā)坝冕;
6.微服務(wù)只是業(yè)務(wù)邏輯的代碼,不會和HTML瓦呼、CSS或其他的頁面混合喂窟;
缺點:
1.開發(fā)人員要處理分布式系統(tǒng)的復(fù)雜性;
2.多個服務(wù)運(yùn)維央串,運(yùn)維成本壓力增大磨澡;
3.系統(tǒng)部署依賴問題;
4.服務(wù)間通信成本問題质和;
5.數(shù)據(jù)一致性問題稳摄;
6.系統(tǒng)集成測試問題;
7.性能和監(jiān)控問題饲宿;
1.4 微服務(wù)技術(shù)棧
2 SpringCloud(Spring官網(wǎng):https://spring.io/)
2.1 SpringBoot和SpringCloud的關(guān)系
????1.SpringBoot專注于開發(fā)單個個體微服務(wù)
???? 2.SpringCloud是一種生態(tài)厦酬,關(guān)注全局的微服務(wù)協(xié)調(diào)整理治理的框架,它將SpringBoot開發(fā)的一個個單體微服務(wù)瘫想,整合并管理起來仗阅,為各個微服務(wù)提供:配置管理、服務(wù)發(fā)現(xiàn)国夜、斷路器减噪、路由、為代理支竹、事件總棧旋廷、全局鎖、決策競選礼搁、分布式會話等等集成服務(wù)饶碘;
???? 3.SpringBoot可以離開SpringCloud獨立使用改淑,開發(fā)項目表悬,但SpringCloud離不開SpringBoot,屬于依賴關(guān)系士鸥;
2.3 Dubbo和SpringCloud技術(shù)選型
???? 1.Dubbo關(guān)注的領(lǐng)域是SpringCloud的一個子集。專注于服務(wù)的治理豪治,其在服務(wù)治理洞拨、灰度發(fā)布、流量分發(fā)方面比SpringCloud更全面负拟。但SpringCloud是一種生態(tài)烦衣,覆蓋整個微服務(wù)領(lǐng)域。
???? 2.Dubbo使用RPC調(diào)用效率高一些掩浙,SpringCloud使用REST(HTTP)調(diào)用效率低花吟,使用更簡單。
???? 擴(kuò)展RPC和REST
???? 1.RPC原理:socekt+動態(tài)代理,自定義協(xié)議傳輸厨姚,性能高衅澈,就像調(diào)用本地方法一樣簡單
???? 2.REST原理:HTTP,性能不如RPC谬墙,耦合性低今布,不用關(guān)心接口實現(xiàn)細(xì)節(jié),相對更規(guī)范拭抬,更標(biāo)準(zhǔn)部默,跨語言支持
???? 3.選擇:
RPC使用于內(nèi)網(wǎng)服務(wù)調(diào)用,對外提供服務(wù)請走REST玖喘。
????? IO密集的服務(wù)調(diào)用用RPC甩牺,低頻服務(wù)用REST蘑志。
????? 服務(wù)調(diào)用過于密集與復(fù)雜累奈,RPC就比較使用
2.2 SpringCloud能干嘛?
???? 1. 分布式/版本控制配置(父工程中的依賴版本管理)
???? 2.服務(wù)注冊與發(fā)現(xiàn)(eureka)
????3. API網(wǎng)關(guān)急但,路由(zuul)
???? 4. 服務(wù)到服務(wù)的調(diào)用(REST)
???? 5.負(fù)載均衡配置(ribbon澎媒、feign)
???? 6.斷路器(hystrix)
???? 7.分布式消息管理(可以集成MQ服務(wù))
???? 8.監(jiān)控(dashboard 流監(jiān)控)
???? 9.統(tǒng)一配置(springCloud-Config遠(yuǎn)程讀取git倉庫)
???? …
2.3 SpringCloud版本選擇
3 EureKa服務(wù)注冊中心(類似Dubbo的注冊中心zooKeeper)
3.1 基本原理
???? 1.Eureka([ju?ri?k?])采用了C-S(客戶端-服務(wù)端)的架構(gòu)設(shè)計,EurekaServer作為服務(wù)注冊功能的服務(wù)器波桩,他是服務(wù)注冊中心戒努;
???? 2.而系統(tǒng)中的其他微服務(wù),使用Eureka的客戶端連接到EurekaServer并維持心跳連接镐躲。這樣系統(tǒng)的維護(hù)人員就可以通過EurekaServer(有監(jiān)控頁面)來監(jiān)控各個微服務(wù)運(yùn)行是否正常储玫,SpringCloud的一些其他模塊(如zuul)就可以通過EurekaServer來發(fā)現(xiàn)系統(tǒng)中的其他微服務(wù),執(zhí)行相關(guān)的邏輯萤皂。
???? 3.與Dubbo的架構(gòu)對比
??4. EurekaServer提供服務(wù)注冊撒穷,各個節(jié)點啟動后,會在EurekaServer中進(jìn)行注冊裆熙,其服務(wù)注冊表中將會儲存所有的服務(wù)節(jié)點的信息端礼。
??5. EurekaClient是一個java客戶端禽笑,用戶簡化EurekaServer的交互,客戶端同時具備一個默認(rèn)是輪詢負(fù)載算法的負(fù)載均衡器蛤奥。在應(yīng)用啟動后佳镜,將會向EurekaServer發(fā)送心跳(默認(rèn)周期為30s)。如果EurekaServer在多個心跳周期內(nèi)沒有接收到某個節(jié)點的心跳凡桥,EurekaServer將會移除這個服務(wù)節(jié)點(默認(rèn)周期為90s蟀伸,開啟自動保護(hù)機(jī)制會保留節(jié)點的信息)
3.2 自我保護(hù)機(jī)制(好死不如賴活著)
一句話總結(jié):某時刻某一個微服務(wù)不可用,eureka不會立刻清理缅刽,依舊會對該微服務(wù)的信息進(jìn)行保存望蜡!
[if !supportLists]1.????[endif]默認(rèn)情況下,當(dāng)EurekaServer在一定時間內(nèi)沒有收到節(jié)點實例的心跳拷恨,便會把該實例從注冊表中刪除(默認(rèn)是90秒)脖律,但是短時間內(nèi)丟失大量的實例心跳,便會觸發(fā)EurekaServer的自我保護(hù)機(jī)制腕侄,在Eureka管理界面會出現(xiàn)紅色的警告小泉。eureka認(rèn)為雖然收不到實例的心跳,但它認(rèn)為實例還是健康的冕杠,eureka會保護(hù)這些實例微姊,不會把它們從注冊表中刪掉。
[if !supportLists]2.????[endif]該保護(hù)機(jī)制的目的是避免網(wǎng)絡(luò)連接故障分预,在發(fā)生網(wǎng)絡(luò)故障時兢交,微服務(wù)和注冊中心之間無法正常通信,但服務(wù)本身是健康的笼痹,不應(yīng)該注銷該服務(wù)配喳,如果eureka因網(wǎng)絡(luò)故障而把微服務(wù)誤刪了,那即使網(wǎng)絡(luò)恢復(fù)了凳干,該微服務(wù)也不會重新注冊到eureka
server了晴裹,因為只有在微服務(wù)啟動的時候才會發(fā)起注冊請求,后面只會發(fā)送心跳和服務(wù)列表請求救赐,這樣的話涧团,該實例雖然是運(yùn)行著,但永遠(yuǎn)不會被其它服務(wù)所感知经磅。所以泌绣,eureka server在短時間內(nèi)丟失過多的客戶端心跳時,會進(jìn)入自我保護(hù)模式预厌,該模式下阿迈,eureka會保護(hù)注冊表中的信息,不在注銷任何微服務(wù)配乓,當(dāng)網(wǎng)絡(luò)故障恢復(fù)后仿滔,eureka會自動退出保護(hù)模式惠毁。自我保護(hù)模式可以讓集群更加健壯。
[if !supportLists]3.????[endif]但是我們在開發(fā)測試階段崎页,需要頻繁地重啟發(fā)布鞠绰,如果觸發(fā)了保護(hù)機(jī)制,則舊的服務(wù)實例沒有被刪除飒焦,這時請求有可能跑到舊的實例中蜈膨,而該實例已經(jīng)關(guān)閉了,這就導(dǎo)致請求錯誤牺荠,影響開發(fā)測試翁巍。所以,在開發(fā)測試階段休雌,我們可以把自我保護(hù)模式關(guān)閉灶壶,只需在eureka server配置文件中加上如下配置即可:eureka.server.enable-self-preservation=false【不推薦關(guān)閉自我保護(hù)機(jī)制】
3.3 基于注冊進(jìn)來的微服務(wù),獲取一些配置信息杈曲,得到具體的微服務(wù)
服務(wù)發(fā)現(xiàn):
1.主啟動類中加入@EnableDiscoveryClient注解
2.controller中注入DiscoveryClient
3.4 EureKa 配置(yml)
??1.eureka服務(wù)端(先導(dǎo)依賴驰凛,再寫yml,最后加啟動類注解@EnableEurekaServer)
??server:
? ?port: 7001
# Eureka配置
eureka:
?instance:
??? #Eureka服務(wù)端的實例名字
?? hostname: 127.0.0.1
?client:
??? #表示是否向 Eureka 注冊中心注冊自己(這個模塊本身是服務(wù)器,所以不需要)
?? register-with-eureka: false
??? #fetch-registry如果為false,則表示自己為注冊中心,客戶端的化為ture
?? fetch-registry: false
??? #Eureka監(jiān)控頁面~
?? service-url:
???? defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
?2.eureka客戶端(先導(dǎo)依賴,再寫yml, 最后加啟動類注解@EnableEurekaClient)
??eureka:
?client:
??service-url:
?? defaultZone: http://localhost:7001/eureka/
3.實例化Id配置(一個微服務(wù)有自己的實例Id担扑,可以配置相同的服務(wù)端的application實例名字)
eureka:
?instance:
??instance-id: springcloud-provider-dept8001
??prefer-ip-adress:true#微服務(wù)實例顯示真實IP
?4.actuator完善監(jiān)控信息(添加依賴恰响,配置YML)
info:
?app.name: ronin
?company.name: ourway
3.4 EureKa 集群環(huán)境配置
1.初始化:
新建sprincloud-eureka-7002、springcloud-eureka-7003模塊
1.分別添加依賴
2.yml配置(與上述7001相同)
3.啟動類注解都加上@EnableEurekaServer
2.集群成員相互關(guān)聯(lián)
?在三個server模板中的yml配置defaultZone中互相關(guān)聯(lián)其他兩個模板
?如7001:
defaultZone:http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/
3.在服務(wù)提供者修改服務(wù)注冊中心地址(把另外兩個注冊中心加上)
defaultZone:http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/
這樣集群就搭建好了涌献,就可以把一個微服務(wù)掛在到三個服務(wù)器上了
3.5 EureKa與ZooKeeper區(qū)別
??1.了解CAP
[if !supportLists]·????????[endif]C (Consistency) 強(qiáng)一致性
[if !supportLists]·????????[endif]A (Availability) 可用性
[if !supportLists]·????????[endif]P (Partition tolerance) 分區(qū)容錯性
?? CAP只能三取二:CA胚宦、AP(EureKa)、CP(Zookeeper)
1.一個分布式系統(tǒng)不可能同時很好的滿足一致性燕垃,可用性和分區(qū)容錯性這三個需求
2.根據(jù)CAP原理枢劝,將NoSQL數(shù)據(jù)庫分成了滿足CA原則,滿足CP原則和滿足AP原則三大類
3.CA:單點集群利术,滿足一致性呈野,可用性的系統(tǒng),通秤∪可擴(kuò)展性較差
4.CP:滿足一致性,分區(qū)容錯的系統(tǒng)军掂,通常性能不是特別高
5.AP:滿足可用性轮蜕,分區(qū)容錯的系統(tǒng),通郴茸叮可能對一致性要求低一些
2. EureKa保證的是AP
?Eureka各個節(jié)點都是平等的跃洛,幾個節(jié)點掛掉不會影響正常節(jié)點的工作,剩余的節(jié)點依然可以提供注冊和查詢服務(wù)终议。而Eureka的客戶端在向某個Eureka注冊時汇竭,如果發(fā)現(xiàn)連接失敗葱蝗,則會自動切換至其他節(jié)點,只要有一臺Eureka還在细燎,就能保住注冊服務(wù)的可用性两曼,只不過查到的信息可能不是最新的,除此之外玻驻,Eureka還有之中自我保護(hù)機(jī)制悼凑,如果在15分鐘內(nèi)超過85%的節(jié)點都沒有正常的心跳,那么Eureka就認(rèn)為客戶端與注冊中心出現(xiàn)了網(wǎng)絡(luò)故障璧瞬,此時會出現(xiàn)以下幾種情況:
1.Eureka不在從注冊列表中移除因為長時間沒收到心跳而應(yīng)該過期的服務(wù)
2.Eureka仍然能夠接受新服務(wù)的注冊和查詢請求户辫,但是不會被同步到其他節(jié)點上 (即保證當(dāng)前節(jié)點依然可用)
3.當(dāng)網(wǎng)絡(luò)穩(wěn)定時,當(dāng)前實例新的注冊信息會被同步到其他節(jié)點中
3. Zookeeper保證的是CP
當(dāng)向注冊中心查詢服務(wù)列表時嗤锉,我們可以容忍注冊中心返回的是幾分鐘以前的注冊信息渔欢,但不能接收服務(wù)直接down掉不可用。也就是說瘟忱,服務(wù)注冊功能對一致性的要求要高于可用性膘茎。但zookeeper會出現(xiàn)這樣一種情況,當(dāng)master節(jié)點因為網(wǎng)絡(luò)故障與其他節(jié)點失去聯(lián)系時酷誓,剩余節(jié)點會重新進(jìn)行l(wèi)eader選舉披坏。問題在于,選舉leader的時間太長盐数,30-120s棒拂,且選舉期間整個zookeeper集群是不可用的,這就導(dǎo)致在選舉期間注冊服務(wù)癱瘓玫氢。在云部署的環(huán)境下帚屉,因為網(wǎng)絡(luò)問題使得zookeeper集群失去master節(jié)點是較大概率發(fā)生的事件,雖然服務(wù)最終能夠恢復(fù)漾峡,但是攻旦,漫長的選舉時間導(dǎo)致注冊長期不可用,是不可容忍的生逸。
因此牢屋,Eureka可以很好的應(yīng)對因網(wǎng)絡(luò)故障導(dǎo)致部分節(jié)點失去聯(lián)系的情況,而不會像zookeeper那樣使整個注冊服務(wù)癱瘓
?
?
4 Ribbon負(fù)載均衡(基于客戶端)
4.1 Ribbon
??前話:我們一個注冊中心的某個實例中槽袄,會有不同的機(jī)器來提供這個服務(wù)(不同的數(shù)據(jù)庫烙无,不同的微服務(wù)注冊成同一個eureka實例)
?Ribbon會自動的幫助我們基于某種規(guī)則(負(fù)載均衡算法,如輪詢遍尺,隨機(jī)(hash)負(fù)載均衡算法可以自定義(IRule接口))去連接那些注冊中心的微服務(wù)機(jī)器截酷。
負(fù)載均衡簡單分類:
1.集中式LB(即負(fù)載均衡(LoadBalancer)?)
即在服務(wù)的提供方和消費方之間使用獨立的LB設(shè)施,如Nginx(反向代理服務(wù)器)乾戏,由該設(shè)施負(fù)責(zé)把訪問請求通過某種策略轉(zhuǎn)發(fā)至服務(wù)的提供方迂苛!
進(jìn)程式LB
2.將LB邏輯集成到消費方三热,消費方從服務(wù)注冊中心獲知有哪些地址可用,然后自己再從這些地址中選出一個合適的服務(wù)器三幻。
Ribbon 就屬于進(jìn)程內(nèi)LB就漾,它只是一個類庫,集成于消費方進(jìn)程赌髓,消費方通過它來獲取到服務(wù)提供方的地址从藤!
?
4.2 集成Ribbon
?1.消費者客戶端添加依賴Ribbon和Eureka(ribbon要從注冊中心獲取實例)依賴
?2.主啟動類加上@EnableEurekaClient
?3.自定義Spring配置類@Configuration,注入RestTemplate類,并在其方法上加上@loadBalanced (因為springcould服務(wù)之間是通過rest來通信的)
?4.修改controller,直接通過服務(wù)名(注冊中心實例名application)來訪問
4.3 自定義負(fù)載均衡算法
?1.在上述4.2.3的自定義配置類中锁蠕,注入IRule 類:
?? IRule:
????* RoundRobinRule輪詢策略
????* RandomRule隨機(jī)策略
????* AvailabilityFilteringRule:會先過濾掉夷野,跳閘,訪問故障的服務(wù)~荣倾,對剩下的進(jìn)行輪詢
???? * RetryRule:會先按照輪詢獲取服務(wù)悯搔,如果服務(wù)獲取失敗,則會在指定的時間內(nèi)進(jìn)行舌仍,重試
?? @Bean
?? Public IRule myRule(){
????? return new MyRule(); //使用我們自定義的算法類
}
注意:該包不要和主啟動類的包同級妒貌,要跟啟動類所在包同級
2. 主啟動類開啟負(fù)載均衡并指定自定義的MyRule配置類
??@RibbonClient(name="SPRINGCLOUD-PROVIDER-DEPT",configuration=MyRule.class)
3.自定的規(guī)則(參考ribbon默認(rèn)的代碼規(guī)則自己稍有改動)
public class MyRandomRule extends AbstractLoadBalancerRule {}
5 Feign負(fù)載均衡(類似controller調(diào)用service)
調(diào)用微服務(wù)訪問兩種方法
1.微服務(wù)名字 【ribbon】
2.接口和注解 【feign】(默認(rèn)集成了ribbon,并且通過輪詢實現(xiàn)了客戶端的負(fù)載均衡)
5.1 使用Feign
還是老套路
[if !supportLists]1.????[endif]引入pom依賴(openfeign)
[if !supportLists]2.????[endif]配置文件修改(這里不需要修改)
[if !supportLists]3.???? [endif]創(chuàng)建一個service接口铸豁,通過@FeignClient("服務(wù)名")灌曙,以及@RequestMapping(value="服務(wù)提供url",method=url類型(RequestMethod.GET等))节芥。
[if !supportLists]4.????[endif]主啟動類添加注解(@EnableXXXX)
// feign客戶端注解,并指定要掃描的包以及配置接口DeptClientService
@EnableFeignClients(basePackages = {"com.haust.springcloud"})
// 切記不要加這個注解在刺,不然會出現(xiàn)404訪問不到
//@ComponentScan("com.haust.springcloud")
[if !supportLists]5.????[endif]當(dāng)前controller直接調(diào)用上述3接口直接獲取微服務(wù)接口即可實現(xiàn)業(yè)務(wù)
[if !supportLists]5.2?????[endif]Feign和Ribbon該如何選擇?根據(jù)個人習(xí)慣而定头镊,如果喜歡REST風(fēng)格使用Ribbon蚣驼;如果喜歡社區(qū)版的面向接口風(fēng)格使用Feign.
6 HyStrix 服務(wù)熔斷
復(fù)雜分布式體系結(jié)構(gòu)中的應(yīng)用程序有數(shù)十個依賴關(guān)系,每個依賴關(guān)系在某些時候?qū)⒉豢杀苊馐相艇。?/p>
6.1 服務(wù)雪崩
??多個微服務(wù)之間調(diào)用的時候颖杏,假設(shè)微服務(wù)A調(diào)用微服務(wù)B和C,微服務(wù)B和C又調(diào)用其他的微服務(wù)坛芽,這就是所謂的“扇出”留储。如果扇出的鏈路上某個微服務(wù)的調(diào)用響應(yīng)時間過長,或者不可用靡馁,對微服務(wù)A的調(diào)用就會占用越來越多的系統(tǒng)資源欲鹏,進(jìn)而造成后面微服務(wù)B和C的崩潰,最終系統(tǒng)崩潰臭墨,這就是所謂的“雪崩效應(yīng)”
?? 解決方案:需要對故障和延遲進(jìn)行隔離和管理,以達(dá)到單個依賴關(guān)系的失敗而不影響整個應(yīng)用程序或系統(tǒng)運(yùn)行膘盖,需要顧全大局胧弛,棄車保帥尤误!
6.2 什么是HyStrix?(斷路器)
?? HyStrix是一個應(yīng)用于處理分布式系統(tǒng)的延遲和容錯的開源庫,在某個服務(wù)單元出現(xiàn)問題的情況下结缚,向調(diào)用方返回一個服務(wù)預(yù)期的损晤,可處理的備選響應(yīng)(FallBack),而不是長時間的等待或者拋出調(diào)用方法無法處理的異常红竭。
6.3 HyStrix之服務(wù)熔斷
當(dāng)扇出鏈路的某個微服務(wù)不可用或響應(yīng)時間太長時尤勋,會進(jìn)行服務(wù)的降級,進(jìn)而熔斷該節(jié)點微服務(wù)的調(diào)用茵宪,快速返回錯誤的響應(yīng)信息(FallBack)最冰。檢測到該節(jié)點微服務(wù)調(diào)用響應(yīng)正常后恢復(fù)調(diào)用鏈路。Hystrix會監(jiān)控微服務(wù)間調(diào)用的狀況稀火,當(dāng)失敗的調(diào)用到一定閥值5秒內(nèi)20次調(diào)用失敗暖哨,就會啟動熔斷機(jī)制。(@HyStrixCommand)
服務(wù)熔斷很好的解決了服務(wù)雪崩的問題凰狞,起到快速失敗的結(jié)果篇裁;快速失敗后,能夠根據(jù)一定的算法動態(tài)試探所依賴對象是否恢復(fù)赡若。
入門實例(老套路)
[if !supportLists]1.????[endif]導(dǎo)入hystrix依賴
[if !supportLists]2.????[endif]配置文件修改(這里不需要修改)
[if !supportLists]3.????[endif]controller方法上加上@HyStrixCommand(fallbackMethod=”備選方法名”)
[if !supportLists]4.????[endif]編寫備選方法
[if !supportLists]5.???? [endif]主啟動類添加熔斷注解@EnableCircuitBreaker
因此达布,為了避免因某個微服務(wù)后臺出現(xiàn)異常或錯誤而導(dǎo)致整個應(yīng)用或網(wǎng)頁報錯逾冬,使用熔斷是必要的黍聂!
?
6.4 HyStrix之服務(wù)降級
服務(wù)降級是指 當(dāng)前服務(wù)器壓力劇增的情況下,根據(jù)實際業(yè)務(wù)情況及流量粉渠,對一些服務(wù)和頁面有策略的不處理分冈,從而釋放服務(wù)器資源以保證核心業(yè)務(wù)正常運(yùn)作或高效運(yùn)作。
?盡可能把系統(tǒng)資源讓給優(yōu)先級高的服務(wù)
???? 使用場景:當(dāng)整個微服務(wù)架構(gòu)整體的負(fù)載超出了預(yù)設(shè)的上線閥值或者即將到來的流量預(yù)計講過超過預(yù)設(shè)的閥值時霸株,為了保證重要的或基本的服務(wù)能正常運(yùn)行雕沉,將一些不重要或不緊急的任務(wù)進(jìn)行服務(wù)的延遲使用或暫停使用,如一件商品訪問量劇增去件,可關(guān)閉相關(guān)商品的推薦坡椒。
???? 服務(wù)降級需要考慮的問題:
[if !supportLists]1. [endif]哪些服務(wù)是核心服務(wù),非核心業(yè)務(wù)
[if !supportLists]2. [endif]哪些服務(wù)可以支持降級尤溜,降級策略是什么
[if !supportLists]3. [endif]除服務(wù)降級之外是否存在更復(fù)雜的業(yè)務(wù)方通背景倔叼,策略是什么
???? 自動降級分類:
???? 1.超時降級:主要配置超時時間和超時重試次數(shù)和機(jī)制,使用異步機(jī)制探測恢復(fù)情況
???? 2.失敗次數(shù)降級:主要是一些不穩(wěn)定的api宫莱,當(dāng)失敗調(diào)用次數(shù)達(dá)到一定閥值自動降級
???? 3.故障降級:比如要調(diào)用的遠(yuǎn)程服務(wù)掛掉了(網(wǎng)絡(luò)故障丈攒,DNS故障,rpc服務(wù)拋出異常),則可以直接降級巡验。降級后的處理方案有:默認(rèn)值(比如庫存服務(wù)掛了际插,返回默認(rèn)現(xiàn)貨)、兜底數(shù)據(jù)(比如廣告服務(wù)掛了显设,返回提前準(zhǔn)備好的一些靜態(tài)頁面)框弛、緩存(之間暫存的一些緩存數(shù)據(jù))
???? 4.限流降級:秒殺或搶購一些商品時,此時可能會因為訪問量太大而導(dǎo)致系統(tǒng)崩潰捕捂,此時會使用限流來進(jìn)行限制訪問量瑟枫,當(dāng)達(dá)到限流閥值,后續(xù)請求會被降級指攒。降級后的處理方案有:排隊頁面(將用戶導(dǎo)流到排隊頁面等一會重試)慷妙、無貨(直接告訴用戶沒貨了)、錯誤頁(如活動太火爆了幽七,稍后重試)
???? 入門案例
[if !supportLists]1.????[endif]在客戶端新建降級配置類(implements FallbackFactory接口)
[if !supportLists]2.????[endif]在feign的接口類中指定降級配置類
@FeignClient(value="SPRINGCLOUD-PROVIDER-DEPT",fallbackFactory=DeptClientServiceFallBackFactory.class)//fallbackFactory指定降級配置類
[if !supportLists]3.????[endif]在yml中配置降級
fegin:
?hystrix:
??enabled: true
6.5 服務(wù)熔斷和降級的區(qū)別
1.服務(wù)熔斷-》服務(wù)端:某個服務(wù)超時或異常景殷,引起熔斷,類似保險絲(自我熔斷)
2.服務(wù)降級-》客戶端:從整體網(wǎng)站請求負(fù)載考慮澡屡,當(dāng)某個服務(wù)熔斷或關(guān)閉之后猿挚,服務(wù)將不再被調(diào)用,此時在客戶端我們可以準(zhǔn)備一個FallbackFactory驶鹉,返回一個默認(rèn)的值(缺省值)
3.實現(xiàn)方式不太一樣绩蜻,服務(wù)降級具有代碼侵入性(由控制器完成/或自動降級),熔斷一版稱為自我熔斷
限流:限制并發(fā)的請求訪問量室埋,超過閥值則拒絕办绝;
降級:服務(wù)分優(yōu)先級,犧牲非核心業(yè)務(wù)(不可用)姚淆,保證核心服務(wù)穩(wěn)定孕蝉;從整體負(fù)荷考慮
熔斷:依賴的下游故障觸發(fā)熔斷,避免系統(tǒng)發(fā)生崩潰腌逢;使用備份策略降淮,系統(tǒng)自動執(zhí)行和恢復(fù)
6.6 HyStrix Dashboard流監(jiān)控(獨立服務(wù):監(jiān)控其他服務(wù)的狀態(tài))
?? 1.編寫Dashboard服務(wù)
???? 1)導(dǎo)入依賴(hystrix-dashboard)
???? 2)主啟動類中添加@EnableHystrixDashboard
?3)訪問自己Dashboard的頁面
2.在其他服務(wù)中
?1)主啟動類中添加監(jiān)控(增加一個servlet,死代碼)
?? @Bean
??? public ServletRegistrationBeanhystrixMetricsStreamServlet(){
??????? ServletRegistrationBeanregistrationBean = new ServletRegistrationBean(new HystrixMetricsStreamServlet());
??????? //訪問該頁面就是監(jiān)控頁面
???????registrationBean.addUrlMappings("/actuator/hystrix.stream");
??????? return registrationBean;
??? }
[if !supportLists]4.????[endif]在Dashboard頁面輸入“配置監(jiān)控服務(wù)的ip+端口”+/actuator/hystrix.stream進(jìn)行監(jiān)控
[if !supportLists]5.????[endif]效果如下圖
7 Zuul 路由網(wǎng)關(guān)
7.1 Zuul
Zull包含了對請求的路由(用來跳轉(zhuǎn)的)和過濾兩個最主要功能:
[if !supportLists]1.???[endif]路由:將外部的請求轉(zhuǎn)發(fā)到具體的微服務(wù)實例上搏讶,是實現(xiàn)外部訪問統(tǒng)一入口的基礎(chǔ)佳鳖。
[if !supportLists]2.????[endif]過濾:對請求的處理過程進(jìn)行干預(yù),是實現(xiàn)請求校驗媒惕,服務(wù)聚合等功能的基礎(chǔ)
??Zuul和Eureka進(jìn)行整合系吩,將Zuul自身注冊為Eureka服務(wù)治理下的應(yīng)用,同時從Eureka中獲得其他服務(wù)的信息妒蔚,也即以后訪問的微服務(wù)都是通過Zuul跳轉(zhuǎn)后獲得
7.2 Zuul 示例
1.導(dǎo)入依賴(也要導(dǎo)入eureka依賴)
2.配置YML文件
?zuul:
????? routes:
?????? mydept(自定義名稱).serviceId:
springcloud-provider-dept #eureka注冊中心服務(wù)實例名application
??????? mydept.path: /mydept/**
????? ignored-services: “*”? #忽略穿挨,隱藏全部的服務(wù)名稱月弛,只能從上述路由進(jìn)去
????? #設(shè)置公共的前綴
????? Prefix: /zhang
# 原來訪問路由eg:http://www.cspStudy.com:9527/springcloud-provider-dept/dept/get/1
? # zull路由配置后訪問路由eg:http://www.cspstudy.com:9527/zhang /mydept/dept/get/1
???? 3.主啟動類中添加開啟zuul注解@EnableZuulProxy
8 Config 分布式遠(yuǎn)程配置(git)
?? 這么多的微服務(wù),每個服務(wù)都有必要的配置信息絮蒿,使用Config 服務(wù)尊搬,集中式叁鉴,動態(tài)管理配置土涝,服務(wù)器存儲后端默認(rèn)實現(xiàn)使用git,因此它輕松支持標(biāo)簽版本的配置環(huán)境(dev,test,…),運(yùn)維人員可以通過鏈條git來更改版本幌墓,不必去依次動每個服務(wù)
同樣但壮,springcloud config也分為服務(wù)端和客戶端兩部分:
? 1.服務(wù)端也稱為分布式配置中心,它是一個獨立的微服務(wù)應(yīng)用常侣,用來連接配置服務(wù)器并為客戶端提供獲取配置信息蜡饵,加密,解密信息等訪問接口胳施。
? 2.客戶端則是通過指定的配置中心來管理應(yīng)用資源溯祸,以及與業(yè)務(wù)相關(guān)的配置內(nèi)容,并在啟動的時候從配置中心獲取和加載配置信息舞肆。配置服務(wù)器默認(rèn)采用git來存儲配置信息焦辅,這樣就有助于對環(huán)境配置進(jìn)行版本管理。并且可用通過git客戶端工具來方便的管理和訪問配置內(nèi)容椿胯。
能干嘛筷登?
1.集中式管理配置文件
2.不同環(huán)境,不同配置哩盲,動態(tài)化的配置更新前方,分環(huán)境部署,比如/dev /test/prod /beta /release
3.運(yùn)行期間動態(tài)調(diào)整配置廉油,不再需要在每個服務(wù)部署的機(jī)器上編寫配置文件惠险,服務(wù)會向配置中心統(tǒng)一拉取配置自己的信息
4.當(dāng)配置發(fā)生變動時,服務(wù)不需要重啟抒线,即可感知到配置的變化班巩,并應(yīng)用新的配置(熱部署只要rebuild)
5.將配置信息以REST接口的形式暴露
8.1 Config示例
?? 1.新建config server (導(dǎo)入依賴,更改配置十兢,主啟動加上@EnableConfigServer)
?server:
? port: 3344
spring:
? application:
??? name:springcloud-config-server
? #連接碼云遠(yuǎn)程倉庫
? cloud:
??? config:
????? server:
??????? git:
????????? #注意是https的而不是ssh
????????? uri:https://gitee.com/cao_shi_peng/springcloud-config.git
??????????? #通過 config-server可以連接到git趣竣,訪問其中的資源以及配置~
# 不加這個配置會報Cannot execute request on any
known server 這個錯:連接Eureka服務(wù)端地址不對
# 或者直接注釋掉eureka依賴 這里暫時用不到eureka
eureka:
? client:
??? register-with-eureka:false
??? fetch-registry: false
2. HTTP服務(wù)具有以下格式的資源:(label為分支名)
?? /{application}/{profile}[/{label}]
/{application}-{profile}.yml
/{label}/{application}-{profile}.yml
/{application}-{profile}.properties
/{label}/{application}-{profile}.properties
[if !supportLists]3.????[endif]各個服務(wù)作為客戶端去獲取config server的配置信息
[if !supportLists]1.????[endif]導(dǎo)入依賴
[if !supportLists]2.????[endif]注意!這里導(dǎo)入兩個yml文件(有點像類加載器)
bootstrap.yml?是系統(tǒng)級別的配置
# 系統(tǒng)級別的配置
spring:
? cloud:
??? config:
????? name: config-client #需要從git上讀取的資源名稱旱物,不要后綴
????? profile: dev
????? label: master
????? uri:http://localhost:3344
application.yml?是用戶級別的配置
# 用戶級別的配置
spring:
? ???????????????application:
??? ??name: springcloud-config-client
????? 4.controller下通過@value讀取配置進(jìn)行測試
9 怎么保證服務(wù)之間的數(shù)據(jù)一致性
以我做過的門戶發(fā)布平臺舉例:
?租戶注銷需要執(zhí)行一下幾個步驟
?1.更改租戶微服務(wù)中的狀態(tài)
?2.注銷網(wǎng)站微服務(wù)中該租戶使用的網(wǎng)站
方案一:
??租戶服務(wù)中要調(diào)網(wǎng)站服務(wù)的功能遥缕,用的restTemplate,加上普通的事務(wù)就可
方案二:
??引入消息中間件宵呛,服務(wù)之間加一層消息中間件单匣,rabbitMQ中有手動確認(rèn)接收機(jī)制
方案三:如果有多個數(shù)據(jù)源,這方面spring也可以集成atomiko實現(xiàn)分布式事務(wù)。