javascript
SpringCloud 超详细个人笔记
文章目錄
- SpringCloud
- 1、常見面試題
- 2、微服務概述
- 2.1、什么是微服務
- 2.2、微服務和微服務架構
- 2.3、微服務優缺點
- 2.4、微服務技術棧有哪些?
- 2.5、為什么選擇SpringCloud 作為微服務架構
- 2.5.1、選型依據
- 2.5.2、當前各大IT公司用的微服務架構有哪些?
- 2.5.3、各微服務框架對比
- 3、SpringCloud 入門概述
- 3.1、SpringCloud是什么
- 3.2、SpringCloud 和 SpringBoot關系
- 3.3、Dubbo 和 SpringCloud技術選型
- 3.3.1、分布式 + 服務治理 Dubbo
- 3.3.2、Dubbo 和 SpringCloud 對比
- 3.4、SpringCloud 能干嘛
- 3.5、SpringCloud在哪下
- 4.1、總體介紹
- 4.2、SpringCloud版本選擇
- 4.3、創建父工程
- 5、Eureka服務注冊與發現
- 5.1、什么是Euraka
- 5.2、原理理解
- 5.3、構建步驟
- 1、eureka-server
- 2.、eureka-client
- 3、actuator 與注冊微服務信息完善
- 4、Eureka 的自我保護機制
- 5、8001服務發現Discovery
- 5.4、Eureka:集群環境配置
- 5.4.1、初始化
- 5.4.2、集群成員相互關聯
- 5.5、對比Zookeeper
- 6、Ribbon
- 6.1、負載均衡以及Ribbon
- 6.2、集成Ribbon
- 6.3、使用Ribbon實現負載均衡
- 7、Feign:負載均衡(基于服務端)
- 7.1 、Feign簡介
- 7.2、Feign的使用步驟
- 7.3、Feign和Ribbon如何選擇?
- 8、Hystrix:服務熔斷
- 8.1、服務雪崩
- 8.2、什么是Hystrix?
- 8.3、Hystrix能干嘛?
- 8.4、服務熔斷
- 8.5、服務降級
- 8.6、服務熔斷和降級的區別
- 8.7、Dashboard 流監控
- 9、Zull路由網關
- 9.1、概述
- 10、Spring Cloud Config 分布式配置
- 10.1、概述
- 10.2、入門案例
- 服務端
- 客戶端
- 10.3、實戰測試
- 用戶級別的配置
SpringCloud
1、常見面試題
1.1、什么是微服務?
1.2、微服務之間是如何獨立通訊的?
1.3、SpringCloud和Dubbo有哪些區別?
1.4、SpringBoot和SpringCloud,請你談談對他們的理解
1.5、什么是服務熔斷?什么是服務降級
1.6、微服務的優缺點是分別是什么?說下你在項目開發中遇到的坑
1.7、你所知道的微服務技術棧有哪些?請列舉一二
1.8、eureka和zookeeper都可以提供服務注冊與發現的功能,請說說兩個的區別?
2、微服務概述
2.1、什么是微服務
什么是微服務?微服務(Microservice Architecture)是近幾年流行的一種架構思想,關于它的概念很難一言以蔽之。
究竟什么是微服務呢?我們在此應用 ThoughtWorks 公司的首席科學家 Martin Fowler 于2014年提出的一段話:
原文:https://martinfowler.com/articles/microservices.html
漢化:https://www.cnblogs.com/liuning8023/p/4493156.html
- 就目前而言,對于微服務,業界應沒有一個統一的,標準的定義
- 但通常而言,微服務架構是一種架構模式,或者說是一種架構風格,它提倡將單一的應用程序劃分成一組小的服務,每個服務器運行在其獨立的自己的進程內,服務之間相互協調,互相配置,為用戶提供最終價值。服務之間采用輕量級的通信機制互相溝通,每個服務都圍繞著具體的業務進行構建,并且能夠被獨立的部署到生產環境中,另外,應盡量避免統一的,集中式的服務管理機制,對具體的一個服務而言,應根據業務上下文,選擇合適的語言,工具對其進行構建,可以一個非常輕量級的集中式管理來協調這些服務,可以使用不同的語言來編寫服務,也可以使用不同的數據存儲;
可能有的人覺得官方的話太過生澀,我們從技術維度來理解下:
- 微服務化的核心就是將傳統的一站式應用,根據業務拆分成一個一個的服務,徹底地去耦合,每一個微服務提供單個業務功能的服務,一個服務做一件事情,從技術角度看就是一種小而獨立的處理過程,類似進程的概念,能夠自行單獨啟動或銷毀,擁有自己獨立的數據庫。
2.2、微服務和微服務架構
微服務
強調的是服務的大小,他關注的某一個點,是具體解決某一個問題/提供落地對應服務的一個服務應用,狹義的看,可以看做是IDEA中的一個個微服務工程,或者Moudel
IDEA 工具里面使用Maven開發的一個個獨立的小Moudle,它具體是使用springboot開發的一個小模塊,專業的事情交給專業的模塊來做,一個模塊就做著一件事情強調的是一個個的個體,每個個體完成一個具體的任務或者功能!微服務架構
一種新的架構形式,Martin Fowler, 2014提出
微服務架構是一種架構模式,它提倡將單一應用程序劃分成一組小的服務,服務之間互相協調,互相配合,為用戶提供最終價值。每個服務運行在其獨立的進程中,服務與服務間采用輕量級的通信機制互相協作,每個服務都圍繞著具體的業務進行構建,并且能夠被獨立的部署到生產環境中,另外,應盡量避免統一的,集中式的服務管理機制,對具體的一個服務而言,應根據業務上下文,選擇合適的語言,工具對其進行構建。
2.3、微服務優缺點
優點
- 單一職責原則
- 每個服務足夠內聚,組夠小,代碼容易理解,這樣能聚集一個指定的業務功能或業務需求;
- 開發簡單,開發效率提供,一個服務可能就是專一的只敢一件事;
- 微服務能夠被小團隊單獨開發,這個小團隊是2~5人的開發人員組成;
- 微服務是松耦合的,是有功能意義的服務,無論是在開發階段或者部署階段都是獨立的。
- 微服務能使用不同的語言開發。
- 易于和第三方繼承,微服務允許容易且靈活的方式集成自動部署,通過持續繼承工具,如 Jenkins,Hudson,Bamboo
- 微服務易于被一個開發人員理解,修改和維護,這樣小團隊能夠功能關注自己的工作成果。無需通過合作才能體現價值。
- 微服務允許你利用融合最新技術
- 微服務知識業務邏輯的代碼,不會和 HTML,CSS 或其他界面混合
- 每個微服務都有自己的存儲能力,可以有自己的數據庫,也可以有同意數據庫
缺點:
- 開發人員要處理分布式系統的復雜性
- 多服務運維難度,隨著服務的增加,運維的壓力也在增大
- 系統部署依賴
- 服務間通信成本
- 數據一致性
- 系統集成測試
- 性能監控。。。。
2.4、微服務技術棧有哪些?
| 服務開發 | SpringBoot,Spring,SpringMVC |
| 服務配置與管理 | Netflix公司的Archaius、阿里的Diamond等 |
| 服務注冊與發現 | Eureka、Consul、Zookeeper等 |
| 服務調用 | Rest、RPC、gRPC |
| 服務熔斷器 | Hystrix、Envoy等 |
| 負載均衡 | Ribbon、Nginx等 |
| 服務接口調用(客戶端調用服務的簡化工具) | Feign等 |
| 消息隊列 | Kafka、RabbitMQ、ActiveMQ等 |
| 服務配置中心管理 | SpringCloudConfig、chef等 |
| 服務路由(API網關) | Zuul等 |
| 服務監控 | Zabbix、Nagios、Metrics、Specatator等 |
| 全鏈路追蹤 | Zipkin、Brave、Dapper等 |
| 服務部署 | Docker、OpenStack、Kubernetes等 |
| 數據流操作開發包 | SpringCloud Stream(封裝與Redis,Rabbit,Kafka等發送接收消息) |
| 事件消息總線 | SpringCloud Bus |
2.5、為什么選擇SpringCloud 作為微服務架構
2.5.1、選型依據
- 整體解決方案和框架成熟度
- 社區熱度
- 可維護性
- 學習曲線
2.5.2、當前各大IT公司用的微服務架構有哪些?
- 阿里:dubbo + HFS
- 京東:JSF
- 新浪:Motan
- 當當網:DubboX
- …
2.5.3、各微服務框架對比
| 功能定位 | 完整的微服務框架 | RPC框架,但整合了ZK或Consul,實現集群環境基本服務注冊/發現 | RPC框架 | RPC框架 | 服務框架 |
| 支持Rest | 是,Ribbon支持多種可插拔的序列化選擇 | 否 | 否 | 否 | 否 |
| 支持RPC | 否 | 是(Hession2) | 是 | 是 | 是 |
| 支持多語言 | 是(Rest形式)? | 否 | 是 | 是 | 否 |
| 負載均衡 | 是(服務端zuul+客戶端Ribbon),zuul-服務,動態路由,云端負載均衡Eureka(針對中間層服務器) | 是(客戶端) | 否 | 否 | 是(客戶端) |
| 配置服務 | Netfix Archaius,Spring Cloud Config Server集中配置 | 是(zookeeper提供) | 否 | 否 | 否 |
| 服務調用鏈監控 | 是(zuul),zuul提供邊緣服務,API網關 | 否 | 否 | 否 | 否 |
| 高可用/容錯 | 是(服務端Hystrix + 客戶端Ribbon) | 是(客戶端) | 否 | 否 | 是(客戶端) |
| 典型應用案例 | Netfix | Sina | |||
| 社區活躍程度 | 高 | 一般 | 高 | 一般 | 2017年后重新開始維護,之前中斷了5年 |
| 學習難度 | 中 | 低 | 高 | 高 | 低 |
| 文檔豐富程度 | 高 | 一般 | 一般 | 一般 | 高 |
| 其他 | Spring Cloud Bus為我們的應用程序帶來了更多管理端點 | 支持降級 | Netflix內部在開發集成gRPC | IDL定義 | 實踐的公司比較多 |
3、SpringCloud 入門概述
3.1、SpringCloud是什么
Spring官網:https://spring.io/
SpringCloud,基于SpringBoot提供了一套微服務解決方案,包括服務注冊于發現,配置中心,全鏈路監控, 服務網關,負載均衡, 熔斷器等組件,除了基于NetFlix的開源組件做高度抽象封裝之外,還有一些選型中立的開源組件。
SpringCloud 利用SpringBoot的開發便利性,巧妙地簡化了分布式系統基礎設施的開發,SpringCloud為開發人員提供了快速構建分布式系統的寫工具,包括配置管理,服務發現,斷路器,路由,微代理,事件總線,全局鎖,決策競選,分布式會話等等,他們都可以用SpringBoot開發風格做的一鍵啟動和部署。
SpringCloud并沒有重復造輪子,他只是將目前各家公司開發的比較成熟,經得起實際考驗的服務框架組合起來,通過SpringBoot風格進行再封裝,屏蔽掉了復雜的配置和實現原理,最終給開發者流出來一套簡單易懂,易部署和易維護的分布式系統開發工具包
SpringCloud 是 分布式微服務架構下的一站式解決方案,是各個微服務架構落地技術的集合體,俗稱微服務全家桶。
3.2、SpringCloud 和 SpringBoot關系
- SpringBoot 專注于快速方便的開發單個個體微服務。
- SpringCloud 是關注全局的微服務協調整理治理框架,他將SpringBoot開發的一個個單體微服務整合并管理起來,為各個微服務之間提供:配置管理,服務發現,斷路器,路由,微代理,事件總線,全局鎖,決策競選,分布式會話等等集成服務。
- SpringBoot可以離開SpringCloud獨立使用,開發項目,但是SpringCloud離不開SpringBoot,屬于依賴關系
- SpringBoot專注于快速開發、方便的開發單個個體微服務,SpringCloud關注全局的服務治理框架
3.3、Dubbo 和 SpringCloud技術選型
3.3.1、分布式 + 服務治理 Dubbo
目前成熟的互聯網架構:應用服務化拆分 + 消息中間件
3.3.2、Dubbo 和 SpringCloud 對比
可以看一下社區活躍度
https://github.com/dubbo
https://github.com/spring-cloud
結果:
| 服務注冊中心 | Zookeeper | Spring Cloud Netfilx Eureka |
| 服務調用方式 | RPC | REST API |
| 服務監控 | Dubbo-monitor | Spring Boot Admin |
| 斷路器 | 不完善 | Spring Cloud Netflix Hystrix |
| 服務網關 | 無 | Spring Cloud Netflix Zuul |
| 分布式配置 | 無 | Spring Cloud Config |
| 服務跟蹤 | 無 | Spring Cloud Sleuth |
| 消息總線 | 無 | Spring Cloud Bus |
| 數據流 | 無 | Spring Cloud Stream |
| 批量任務 | 無 | Spring Cloud Task |
最大區別:SpringCloud 拋棄了 Dubbo 的 RPC 通信,采用的是基于HTTP的REST方式。
嚴格來說,這兩種方式各有優劣。雖然從一定程度上來說,后者犧牲了服務調用的性能,但也避免了上面提到的原來RPC帶來的問題。而且REST相比RPC更為靈活,服務提供方和調用方的依賴只依靠一紙鍥約,不存在代碼級別的強依賴,這在強調快速演化的微服務環境下,顯得更加合適。
品牌機與組裝機的區別
很明顯,Spring Cloud的功能比DUBBO更加強大,涵蓋面更廣,而且作為Spring的拳頭項目,它也能夠與SpringFramework、Spring Boot、Spring Data、Spring Batch等其他Spring項目完美融合,這些對于微服務而言是至關重要的。使用Dubbo構建的微服務架構就像組裝電腦,各環節我們的選擇自由度很高,但是最終結果很有可能因為一條內存質量不行就點不亮了,總是讓人不怎么放心,但是如果你是一名高手,那這些都不是問題;而SpringCloud就像品牌機,在Spring Source的整合下,做了大量的兼容性測試,保證了機器擁有更高的穩定性,但是如果要在使用非原裝組件外的東西,就需要對其基礎有足夠的了解。
社區支持與更新力度
最為重要的是,DUBBO停止了5年左右的更新,雖然2017.7重啟了。對于技術發展的新需求,需要由開發者自行拓展升級(比如當當網弄出了DubboX),這對于很多想要采用微服務架構的中小軟件組織,顯然是不太合適的,中小公司沒有這么強大的技術能力去修改Dubbo源碼+周邊的一整套解決方案,并不是每一個公司都有阿里的大牛+真實的線上生產環境測試過。
總結:
曾風靡國內的開源 RPC 服務框架 Dubbo 在重啟維護后,令許多用戶位置雀躍,但同時,也迎來了一些質疑的聲音?;ヂ摼W技術發展迅速,Dubbo 是否還能跟上時代?Dubbo 與 Spring Cloud 相比又有何優勢和差異?是否會有相關舉措保證 Dubbo 的后續更新頻率?
人物:Dubbo重啟維護開發的劉軍,主要負責人之一
劉軍,阿里巴巴中間件高級研發工程師,主導了 Dubbo 重啟維護以后的幾個發版計劃,專注于高性能 RPC 框架和微服務相關領域。曾負責網易考拉 RPC 框架的研發及指導在內部使用,參與了服務治理平臺、分布式跟蹤系統、分布式一致性框架等從無到有的設計與開發過程。
解決的問題域不一樣:Dubbo 的定位是一款RPC框架,Spring Cloud 的目標是微服務架構下的一站式解決方案
3.4、SpringCloud 能干嘛
- Distributed/versioned configuration(分布式/版本控制配置)
- Service registration and discovery(服務注冊與發現)
- Routing(路由)
- Service-to-service calls(服務到服務的調用)
- Load balancing(負載均衡配置)
- Circuit Breakers(斷路器)
- Distributed messaging(分布式消息管理)
- …
3.5、SpringCloud在哪下
官網:https://spring.io/projects/spring-cloud
這玩意兒版本號有點特別
spring cloud 是一個由眾多獨立子項目組成的大型綜合項目,每個子項目有不同的發行節奏,都維護著自己的發布版本號。 spring cloud 通過一個資源清單 BOM (Bi11 of Materials)來管理每個版本的子項目清單。為避免與子項目的發布號混 淆,所以沒有采用版本號的方式,而是通過命名的方式。這些版本名稱的命名方式采用了倫敦地鐵站的名稱,同時根據字母表的順序來對應版本時間順序,比如: 最早的 Release版 本: Ange1,第二個Release版本: Brixton,然后是camden、Dalston、Edgware,目前最新的是Finchley版本。參考書:
- https://www.springcloud.cc/spring-cloud-netflix.html
- 中文API文檔:https://www.springcloud.cc/spring-cloud-dalston.html
- SpringCloud 中國社區:http://springcloud.cn/
- SpringCloud 中文網:https://www.springcloud.cc/
4.1、總體介紹
-
我們會使用 Dept 部分模塊做一個微服務通用案例 Consumer 消費者 (Client)通過 REST 調用 Provider 提供者 (Server)提供的服務。
-
會議 Spring,SpringMVC,Mybatis 等以往學過的知識。。。
-
Maven 的分包分模塊架構復習
一個簡單的maven模塊結構是這樣的:-- app-parent:一個府項目(app-parent)聚合很多子項目(app-util,app-dao,app-web...)|-- pom.xml||-- app-core||---- pom.xml||-- ap-web||---- pom.xml......一個父工程帶著多個字Module子模塊
MicroServiceCloud父工程(Project)下初次帶著3個子模塊(Module)
- microservicecloud-api 【封裝的整體entity/接口/公共配置等】
- microservicecloud-provider-dept-8001【服務提供者】
- microservicecloud-consumer-dept-80 【服務消費者】
-
動手開干!
4.2、SpringCloud版本選擇
大版本說明
| 1.2.x | Angel版本(天使) | 兼容Spring Boot 1.2.x |
| 1.3.x | Brixton版本(布里克斯頓) | 兼容Spring Boot 1.3.x,也兼容Spring Boot 1.4.x |
| 1.4.x | Camden版本(卡姆登) | 兼容Spring Boot 1.4.x,也兼容Spring Boot 1.5.x |
| 1.5.x | Dalston版本(多爾斯頓) | 兼容Spring Boot 1.5.x,不兼容Spring Boot 2.0.x |
| 1.5.x | Edgware版本(埃奇韋爾) | 兼容Spring Boot 1.5.x,不兼容Spring Boot 2.0.x |
| 2.0.x | Finchley版本(芬奇利) | 兼容Spring Boot 2.0.x,不兼容Spring Boot 1.5.x |
| 2.1.x | Greenwich版本(格林威治) |
實際開發版本關系
| 版本號 | 發布日期 | 版本號 | 發布日期 |
| 1.5.2.RELEASE | 2017年3月 | Dalston.RC1 | 2017年未知月 |
| 1.5.9.RELEASE | Nov,2017 | Edgware.RELEASE | Nov, 2017 |
| 1.5.16.RELEASE | sep, 2018 | Edgware.SR5 | Oct,2018 |
| 1.5.20.RELEASE | Apr, 2019 | Edgware.SR5 | Oct, 2018 |
| 2.0.2.RELEASE | May, 2018 | Finchley.BUILD-SNAPSHOT | 2018年未知月 |
| 2.0.6.RELEASE | Oct, 2018 | Finchley.SR2 | Oct, 2018 |
| 2.1.4.RELEASE | Apr,2019 | Greenwich.SR1 | Mar,2019 |
使用最后的這兩個
4.3、創建父工程
-
新建父工程項目microservicecloud,切記Packageing是pom模式
-
主要是定義POM文件,將后續各個子模塊公用的jar包統一提取出來,類似一個抽象父類
<!-- 打包方式--><packaging>pom</packaging><modules><module>springcloud-api</module><module>springcloud-provider-dept-8001</module><module>springcloud-consumer-dept-80</module></modules><properties><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target></properties><dependencyManagement><dependencies><!-- springcloud的依賴--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-dependencies</artifactId><version>2020.0.2</version><type>pom</type><scope>import</scope></dependency><!-- springboot--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-dependencies</artifactId><version>2.4.0</version><type>pom</type><scope>import</scope></dependency><!--數據庫--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.48</version></dependency><dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.2.3</version></dependency><!-- springboot啟動器--><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>2.1.4</version></dependency><!-- 單元測試--><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.13</version><scope>test</scope></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.16</version></dependency><dependency><groupId>log4j</groupId><artifactId>log4j</artifactId><version>1.2.17</version></dependency><dependency><groupId>ch.qos.logback</groupId><artifactId>logback-core</artifactId><version>1.2.3</version></dependency></dependencies></dependencyManagement>
DeptConsumerController.java
@RestController public class DeptConsumerController {// 消費者,不應該有service層// RestTemplate.... 供我們直接調用就可以了!注冊到spring中//( url, Class<T> responseType, 實體:Map<String, ?> uriVariables)@Autowiredprivate RestTemplate restTemplate; // 提供多種邊界訪問遠程http服務的方法,簡單的restful服務模板private static final String REST_URL_PREFIX = "http://localhost:8001";@RequestMapping("/consumer/dept/get/{id}")public Dept get(@PathVariable("id") Long id){return restTemplate.getForObject(REST_URL_PREFIX + "/dept/get/"+ id, Dept.class);}@RequestMapping("/consumer/dept/add")public boolean add(Dept dept){return restTemplate.postForObject(REST_URL_PREFIX + "/dept/add", dept, Boolean.class);}@RequestMapping("/consumer/dept/list")public List<Dept> queryAll(){return restTemplate.getForObject(REST_URL_PREFIX + "/dept/list", List.class);} }使用RestTemplete先需要放入Spring容器中
ConfigBean.java
@Configuration public class ConfigBean {@Beanpublic RestTemplate getRestTemplate(){return new RestTemplate();} }詳細代碼:
https://gitee.com/su_shuwang/spring-cloud
5、Eureka服務注冊與發現
5.1、什么是Euraka
- Eureka:怎么讀?
- Netflix 在設計Eureka時,遵循的就是AP原則
- Eureka 是 Netflix 的一個子模塊,也是核心模塊之一。Eureka 是一個基于 REST 的服務,用于定位服務,以實現云端中間層服務發現和故障轉移,就可以訪問到服務,而不需要修改調用的配置文件了,功能類似于Dubbo 的注冊中心,比如 Zookeeper;
5.2、原理理解
-
Eureka 的基本架構
- SpringCloud 封裝了 Netflix 公司開發的 Eureka 模塊來實現服務注冊和發現(對比Zookeeper)
- Eureka 采用了 C-S 的架構設計, EurekaServer 作為服務注冊功能的服務器,他是服務注冊中心
- 而系統中的其他微服務。使用Eureka的客戶端連接到 EurekaServer 并維持心跳連接。這樣系統的維護人員就可以通過EurekaServer來監控系統中各個微服務是否正常運行,SpringCloud的一些其他模塊(比如Zuul)就可以通過EurekaServer來發現系統中的其他微服務,并執行相關的邏輯;
- 和 Dubbo 架構對比
- Eureka包含兩個組件: Eureka Server和 Eureka Client 。
- Eureka Server提供服務注冊服務,各個節點啟動后,會在EurekaServer中進行注冊,這樣Eureka Server中的服務注冊表中將會村粗所有可用服務節點的信息,服務節點的信息可以在界面中直觀的看到。
- Eureka Client是一個ava客戶端,用于簡化EurekaServer的交互,客戶端同時也具備一個內置的,使用輪詢負載算法的負載均衡器。在應用啟動后,將會向EurekaServer發送心跳(默認周期為30秒)。如果Eureka Server在多個心跳周期內沒有接收到某個節點的心跳,EurekaServer將會從服務注冊表中把這個服務節點移除掉(默認周期為90秒)
-
三大角色
- Eureka Server:提供服務的注冊與發現。
- Service Provider:將自身服務注冊到Eureka中,從而使消費方能夠找到。
- Service Consumer:服務消費方從Eureka中獲取注冊服務列表,從而找到消費服務。
5.3、構建步驟
1、eureka-server
springcloud-eureka-7001 模塊建立
pom.xml 配置
spring-cloud-starter-eureka-server 已經停止維護,建議使用spring-cloud-starter-netflix-eureka-server
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><parent><artifactId>springcloud</artifactId><groupId>com.su</groupId><version>1.0-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><artifactId>springcloud-eureka-7001</artifactId><properties><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target></properties><dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-server</artifactId><version>2.2.9.RELEASE</version></dependency></dependencies> </project>yml文件
server:port: 7001#Eureka 配置 eureka:instance:hostname: localhost #Eureka 服務端的實例名稱client:register-with-eureka: false # 表示是否向 Eureka注冊中心注冊自己fetch-registry: false # 如果為false,則表示自己為注冊中心,我的職責就是維護服務實例,并不需要去檢索服務service-url: # 監控頁面~defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/# 設置與Eureka Server 交互的地址查詢服務和注冊服務都需要依賴這個defaultZone 地址編寫主啟動類
@SpringBootApplication @EnableEurekaServer // 服務端的啟動類,可以接受別人注冊進來~ public class EurekaServer_7001 {public static void main(String[] args) {SpringApplication.run(EurekaServer_7001.class, args);} }啟動成功后訪問 http://localhost:7001/ 得到以下頁面
2.、eureka-client
調整之前創建的springlouc-provider-dept-8001
修改8001服務的pom文件,增加eureka的支持!
spring-cloud-starter-eureka已經停止維護,建議使用 spring-cloud-starter-netflix-eureka-client
<!--將服務的provider注冊到eureka中--> <!--Eureka--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</artifactId><version>2.2.9.RELEASE</version></dependency>yml修改
# Eureka 的配置, 服務注冊到哪里 eureka:client:service-url:defaultZone: http://localhost:7001/eureka/8001的主啟動類注解支持
@SpringBootApplication @EnableEurekaClient // 自動在服務啟動后,自動注冊到Eureka中! public class DeptProvider_8001 {public static void main(String[] args) {SpringApplication.run(DeptProvider_8001.class, args);} }先啟動7001服務端后啟動8001客戶端進行測試,然后訪問監控頁http://localhost:7001/ 產看結果如圖,成功
3、actuator 與注冊微服務信息完善
主機名稱:服務名稱修改
-
在8001的yml中修改一下配置
# Eureka 的配置, 服務注冊到哪里 eureka:client:service-url:defaultZone: http://localhost:7001/eureka/instance:instance-id: springcloud-provider-dept8001 # 修改Eureka 上的默認描述信息 -
查看結果
訪問信息有IP信息提示
-
在yml中再增加一個配置
# Eureka 的配置, 服務注冊到哪里 eureka:client:service-url:defaultZone: http://localhost:7001/eureka/instance:instance-id: springcloud-provider-dept8001 # 修改Eureka 上的默認描述信息prefer-ip-address: true # 訪問路徑可以顯示ip地址 -
重啟服務測試
info內容構建
現在點擊info,出現ERROR頁面
-
修改8001的pom文件,新增依賴
<!-- actuator完善監控信息--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId></dependency> -
然后回到我們的8001的yaml配置文件中修改增加信息
# info配置 info:app.name: kuangshen-springcloudcompany.name: blog.kuangstudy.com -
重啟項目測試:7001、8001
4、Eureka 的自我保護機制
之前出現的這些紅色情況
我們修改一個服務名,故意制造錯誤!
自我保護機制:好死不如賴活著
一句話總結就是:某時刻某一個微服務不可用,eureka不會立即清理,依舊會對該微服務的信息進行保存!
- 默認情況下,如果EurekaServer在一定時間內沒有接收到某個微服務實例的心跳,EurekaServer將會注銷該實例(默認90秒)。但是當網絡分區故障發生時,微服務與Eureka之間無法正常通行,以上行為可能變得非常危險了——因為微服務本身其實是健康的,此時本不應該注銷這個服務。Eureka通過自我保護機制來解決這個問題——當EurekaServer節點在短時間內丟失過多客戶端時(可能發生了網絡分區故障),那么這個節點就會進入自我保護模式。一旦進入該模式,EurekaServer就會保護服務注冊表中的信息,不再刪除服務注冊表中的數據(也就是不會注銷任何微服務)。當網絡故障恢復后,該EurekaServer節點會自動退出自我保護模式。
- 在自我保護模式中,EurekaServer會保護服務注冊表中的信息,不再注銷任何服務實例。當它收到的心跳數重新恢復到閾值以上時,該EurekaServer節點就會自動退出自我保護模式。它的設計哲學就是寧可保留錯誤的服務注冊信息,也不盲目注銷任何可能健康的服務實例。一句話:好死不如賴活著
- 綜上,自我保護模式是一種應對網絡異常的安全保護措施。它的架構哲學是寧可同時保留所有微服務(健康的微服務和不健康的微服務都會保留),也不盲目注銷任何健康的微服務。使用自我保護模式,可以讓Eureka集群更加的健壯和穩定
- 在SpringCloud中,可以使用eureka.server.enable-self-preservation = false禁用自我保護模式【不推薦關閉自我保護機制】
5、8001服務發現Discovery
DeptController.java新增方法
//獲取一些配置的信息,得到具體的微服務! @Autowired private DiscoveryClient client;//注冊進來的微服務~,獲取一些信息~ @RequestMapping("/dept/discovery") public Object discovery(){//獲取微服務列表的清單List<String> services = client.getServices();System.out.println("discovery=>services:" + services);//得到一個具體的微服務信息,通過具體的微服務id,applicationNameList<ServiceInstance> instances = client.getInstances("SPRINGCLOUD-PROVIDER-DEPT");for (ServiceInstance instance : instances) {System.out.println(instance.getHost() + "\t"+instance.getPort()+"\t"+instance.getUri()+"\t"+instance.getServiceId()+"\t");}return this.client; }主啟動類中加入@EnableDiscoveryClient 注解
@SpringBootApplication @EnableEurekaClient // 自動在服務啟動后,自動注冊到Eureka中! @EnableDiscoveryClient // 服務發現~ 可以用來獲取一些配置的信息,得到具體的微服務 public class DeptProvider_8001 {public static void main(String[] args) {SpringApplication.run(DeptProvider_8001.class, args);} }5.4、Eureka:集群環境配置
5.4.1、初始化
新建springcloud-eureka-7002、springcloud-eureka-7003 模塊
1.為pom.xml添加依賴 (與springcloud-eureka-7001相同)
<!--導包~--> <dependencies><!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-eureka-server --><!--導入Eureka Server依賴--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-eureka-server</artifactId><version>1.4.6.RELEASE</version></dependency><!--熱部署工具--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId></dependency> </dependencies>3.主啟動類(與springcloud-eureka-7001相同)
@SpringBootApplication // @EnableEurekaServer 服務端的啟動類,可以接受別人注冊進來~ public class EurekaServer_7003 {public static void main(String[] args) {SpringApplication.run(EurekaServer_7003.class,args);} }5.4.2、集群成員相互關聯
配置一些自定義本機名字,找到本機hosts文件并打開
在hosts文件最后加上,要訪問的本機名稱,默認是localhost
修改application.yml的配置,如圖為springcloud-eureka-7001配置,springcloud-eureka-7002/springcloud-eureka-7003同樣分別修改為其對應的名稱即可
在集群中使springcloud-eureka-7001關聯springcloud-eureka-7002、springcloud-eureka-7003
完整的springcloud-eureka-7001下的application.yml如下
server:port: 7001#Eureka 配置 eureka:instance:hostname: eureka7001.com #Eureka 服務端的實例名稱client:register-with-eureka: false # 表示是否向 Eureka注冊中心注冊自己fetch-registry: false # 如果為false,則表示自己為注冊中心service-url: # 監控頁面~defaultZone: http://eureka7002.com:7002/eureka/, http://eureka7003.com:7003/eureka/同時在集群中使springcloud-eureka-7002關聯springcloud-eureka-7001、springcloud-eureka-7003
完整的springcloud-eureka-7002下的application.yml如下
server:port: 7002#Eureka 配置 eureka:instance:hostname: eureka7002.com #Eureka 服務端的實例名稱client:register-with-eureka: false # 表示是否向 Eureka注冊中心注冊自己fetch-registry: false # 如果為false,則表示自己為注冊中心service-url: # 監控頁面~defaultZone: http://eureka7001.com:7001/eureka/, http://eureka7003.com:7003/eureka/springcloud-eureka-7003配置方式同理可得.
通過springcloud-provider-dept-8001下的yml配置文件,修改Eureka配置:配置服務注冊中心地址
# Eureka配置:配置服務注冊中心地址 eureka:client:service-url:# 注冊中心地址7001-7003defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/instance:instance-id: springcloud-provider-dept-8001 #修改Eureka上的默認描述信息這樣模擬集群就搭建號了,就可以把一個項目掛載到三個服務器上了
5.5、對比Zookeeper
回顧CAP原則
CAP原則又稱CAP定理,指的是在一個分布式系統中,一致性(Consistency)、可用性(Availability)、分區容錯性(Partition tolerance)。CAP原則指的是,這三個要素最多只能同時實現兩點,不可能三者兼顧。
RDBMS (MySQL\Oracle\sqlServer) ===> ACID
NoSQL (Redis\MongoDB) ===> CAP
ACID是什么?
- A (Atomicity) 原子性
- C (Consistency) 一致性
- I (Isolation) 隔離性
- D (Durability) 持久性
CAP是什么?
- C (Consistency) 強一致性
- A (Availability) 可用性
- P (Partition tolerance) 分區容錯性
CAP的三進二:CA、AP、CP
CAP理論的核心
- 一個分布式系統不可能同時很好的滿足一致性,可用性和分區容錯性這三個需求
- 根據CAP原理,將NoSQL數據庫分成了滿足CA原則,滿足CP原則和滿足AP原則三大類
- CA:單點集群,滿足一致性,可用性的系統,通??蓴U展性較差
- CP:滿足一致性,分區容錯的系統,通常性能不是特別高
- AP:滿足可用性,分區容錯的系統,通常可能對一致性要求低一些
作為分布式服務注冊中心,Eureka比Zookeeper好在哪里?
著名的CAP理論指出,一個分布式系統不可能同時滿足C (一致性) 、A (可用性) 、P (容錯性)
由于分區容錯性P再分布式系統中是必須要保證的,因此我們只能再A和C之間進行權衡。
- Zookeeper 保證的是 CP —> 滿足一致性,分區容錯的系統,通常性能不是特別高
- Eureka 保證的是 AP —> 滿足可用性,分區容錯的系統,通常可能對一致性要求低一些
Zookeeper保證的是CP
當向注冊中心查詢服務列表時,我們可以容忍注冊中心返回的是幾分鐘以前的注冊信息,但不能接收服務直接down掉不可用。也就是說,服務注冊功能對可用性的要求要高于一致性。但zookeeper會出現這樣一種情況,當master節點因為網絡故障與其他節點失去聯系時,剩余節點會重新進行leader選舉。問題在于,選舉leader的時間太長,30-120s,且選舉期間整個zookeeper集群是不可用的,這就導致在選舉期間注冊服務癱瘓。在云部署的環境下,因為網絡問題使得zookeeper集群失去master節點是較大概率發生的事件,雖然服務最終能夠恢復,但是,漫長的選舉時間導致注冊長期不可用,是不可容忍的。
Eureka保證的是AP
Eureka看明白了這一點,因此在設計時就優先保證可用性。Eureka各個節點都是平等的,幾個節點掛掉不會影響正常節點的工作,剩余的節點依然可以提供注冊和查詢服務。而Eureka的客戶端在向某個Eureka注冊時,如果發現連接失敗,則會自動切換至其他節點,只要有一臺Eureka還在,就能保住注冊服務的可用性,只不過查到的信息可能不是最新的,除此之外,Eureka還有之中自我保護機制,如果在15分鐘內超過85%的節點都沒有正常的心跳,那么Eureka就認為客戶端與注冊中心出現了網絡故障,此時會出現以下幾種情況:
- Eureka不再從注冊列表中移除因為長時間沒收到心跳而應該過期的服務
- Eureka仍然能夠接受新服務的注冊和查詢請求,但是不會被同步到其他節點上 (即保證當前節點依然可用)
- 當網絡穩定時,當前實例新的注冊信息會被同步到其他節點中
因此,Eureka可以很好的應對因網絡故障導致部分節點失去聯系的情況,而不會像zookeeper那樣使整個注冊服務癱瘓
6、Ribbon
6.1、負載均衡以及Ribbon
Ribbon是什么?
- SpringCloud Rinbbon是基于Netflix Ribbon實現的一套客戶端負載均衡的工具。
- 簡單的說,Ribbon是Netflix發布的開源項目,主要功能是提供客戶端的軟件負載均衡算法,將NetFlix的中間層服務連接在一起。Ribbon的客戶端組件提供一系列完成的配置項如:連接超時、重試等等。簡單的說,就是配置文件中列出LoadBalancer(簡稱LB:負載均衡)后面所有的機器,Ribbon會自動的幫助你基于某種規則(如簡單輪詢,隨機連接等等)去連接這些機器。我們也很容易使用Ribbon實現自定義的負載均衡算法!
Ribbon能干嘛?
- LB,即負載均衡 (LoadBalancer) ,在微服務或分布式集群中經常用的一種應用。
- 負載均衡簡單的說就是將用戶的請求平攤的分配到多個服務上,從而達到系統的HA (高用)。
- 常見的負載均衡軟件有 Nginx、Lvs 等等。
- Dubbo、SpringCloud 中均給我們提供了負載均衡,SpringCloud 的負載均衡算法可以自定義。
- 負載均衡簡單分類:
- 集中式LB
- 即在服務的提供方和消費方之間使用獨立的LB設施,如Nginx(反向代理服務器),由該設施負責把訪問請求通過某種策略轉發至服務的提供方!
- 進程式 LB
- 將LB邏輯集成到消費方,消費方從服務注冊中心獲知有哪些地址可用,然后自己再從這些地址中選出一個合適的服務器。
Ribbon 就屬于進程內LB,它只是一個類庫,集成于消費方進程,消費方通過它來獲取到服務提供方的地址!
- 將LB邏輯集成到消費方,消費方從服務注冊中心獲知有哪些地址可用,然后自己再從這些地址中選出一個合適的服務器。
- 集中式LB
6.2、集成Ribbon
springcloud-consumer-dept-80向pom.xml中添加Ribbon和Eureka依賴
<!--Ribbon--> <!-- spring-cloud-starter-ribbon 已停止維護,建議使用spring-cloud-starter-netflix-ribbon --><!-- <dependency>--> <!-- <groupId>org.springframework.cloud</groupId>--> <!-- <artifactId>spring-cloud-starter-ribbon</artifactId>--> <!-- <version>1.4.6.RELEASE</version>--> <!-- </dependency>--> <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-ribbon</artifactId><version>2.2.9.RELEASE</version></dependency> <!--Eureka: Ribbon需要從Eureka服務中心獲取要拿什么--> <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</artifactId><version>2.2.9.RELEASE</version> </dependency>依賴導入失敗,解決:
有的時候,依賴雖然下載失敗了,但是相關文件夾中卻多了以 .lastUpdated為后綴的文件,此時,如果開發者在開發工具中反復導 入,會發現始終無法導入成功,這個時候就需要刪除本地倉庫中相關的 .lastUpdated文件,可以通過文件搜索找到本地倉庫中所有的 以 .lastUpdated為后綴的文件,如下:搜索 .lastupdate,找到對應的依賴文件,刪除即可在application.yml文件中配置Eureka
# Eureka配置 eureka:client:register-with-eureka: false # 不向 Eureka注冊自己service-url: # 從三個注冊中心中隨機取一個去訪問defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/主啟動類加上@EnableEurekaClient注解,開啟Eureka
//Ribbon 和 Eureka 整合以后,客戶端可以直接調用,不用關心IP地址和端口號 @SpringBootApplication @EnableEurekaClient //開啟Eureka 客戶端 public class DeptConsumer_80 {public static void main(String[] args) {SpringApplication.run(DeptConsumer_80.class, args);} }自定義Spring配置類:ConfigBean.java 配置負載均衡實現RestTemplate
@Configuration public class ConfigBean {//@Configuration -- spring applicationContext.xml@LoadBalanced //配置負載均衡實現RestTemplate@Beanpublic RestTemplate getRestTemplate() {return new RestTemplate();} }修改conroller:DeptConsumerController.java
//Ribbon:我們這里的地址,應該是一個變量,通過服務名來訪問 //private static final String REST_URL_PREFIX = "http://localhost:8001"; private static final String REST_URL_PREFIX = "http://SPRINGCLOUD-PROVIDER-DEPT";6.3、使用Ribbon實現負載均衡
流程圖:
1.新建兩個服務提供者Moudle:springcloud-provider-dept-8002、springcloud-provider-dept-8003
2.參照springcloud-provider-dept-8001 依次為另外兩個Moudle添加pom.xml依賴 、resourece下的mybatis和application.yml配置,Java代碼
application.yml需要修改 instance-id
# Eureka 的配置, 服務注冊到哪里 eureka:client:service-url:defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/instance:instance-id: springcloud-provider-dept8002 # 修改Eureka 上的默認描述信息prefer-ip-address: true # 訪問路徑可以顯示ip地址3.新建兩個數據庫db02、db03, 并修改數據
CREATE DATABASE /*!32312 IF NOT EXISTS*/`db01` /*!40100 DEFAULT CHARACTER SET utf8 */; USE `db01`; /*Table structure for table `dept` */DROP TABLE IF EXISTS `dept`; CREATE TABLE `dept` (`deptno` bigint(20) NOT NULL AUTO_INCREMENT,`dname` varchar(60) DEFAULT NULL,`db_source` varchar(60) DEFAULT NULL,PRIMARY KEY (`deptno`) ) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8;/*Data for the table `dept` */ insert into dept (`deptno`,`dname`,`db_source`) values (1,'開發部',DATABASE()),(2,'人事部',DATABASE()),(3,'財務部',DATABASE()),(4,'市場部',DATABASE()),(5,'運維部',DATABASE()),(6,NULL,DATABASE());4.啟動所有服務測試(根據自身電腦配置決定啟動服務的個數),訪問http://eureka7001.com:7002/查看結果
測試訪問http://localhost/consumer/dept/list
再次訪問
以上這種每次訪問http://localhost/consumer/dept/list隨機訪問集群中某個服務提供者,這種情況叫做輪詢,輪詢算法在SpringCloud中可以自定義。
如何切換或者自定義規則呢?
在springcloud-provider-dept-80模塊下的ConfigBean中進行配置,切換使用不同的規則
@Configuration public class ConfigBean {//@Configuration -- spring applicationContext.xml/*** IRule:* RoundRobinRule 輪詢策略* RandomRule 隨機策略* AvailabilityFilteringRule : 會先過濾掉,跳閘,訪問故障的服務~,對剩下的進行輪詢~* RetryRule : 會先按照輪詢獲取服務~,如果服務獲取失敗,則會在指定的時間內進行,重試*/@Beanpublic IRule myRule() {return new RandomRule();//使用隨機策略//return new RoundRobinRule();//使用輪詢策略//return new AvailabilityFilteringRule();//使用輪詢策略//return new RetryRule();//使用輪詢策略} }也可以自定義規則,在myRule包下自定義一個配置類MyRule.java,注意:該包不要和主啟動類所在的包同級,要跟啟動類所在包同級:
MyRule.java
@Configuration public class MyRule {@Beanpublic IRule myRule(){return new MyRandomRule(); //默認是輪詢RandomRule,現在自定義為自己的} }主啟動類開啟負載均衡并指定自定義的MyRule配置類
//Ribbon 和 Eureka 整合以后,客戶端可以直接調用,不用關心IP地址和端口號 @SpringBootApplication @EnableEurekaClient //在微服務啟動的時候就能去加載我們自定義的Ribbon類 @RibbonClient(name = "springcloud-provider-dept", configuration = MyRule.class) public class DeptConsumer_80 {public static void main(String[] args) {SpringApplication.run(DeptConsumer_80.class, args);} }自定義的規則(這里我們參考Ribbon中默認的規則代碼自己稍微改動):MyRandomRule.java
public class MyRandomRule extends AbstractLoadBalancerRule {/*** 每個服務訪問5次則換下一個服務(總共3個服務)* <p>* total=0,默認=0,如果=5,指向下一個服務節點* index=0,默認=0,如果total=5,index+1*/private int total = 0;//被調用的次數private int currentIndex = 0;//當前是誰在提供服務//@edu.umd.cs.findbugs.annotations.SuppressWarnings(value = "RCN_REDUNDANT_NULLCHECK_OF_NULL_VALUE")public Server choose(ILoadBalancer lb, Object key) {if (lb == null) {return null;}Server server = null;while (server == null) {if (Thread.interrupted()) {return null;}List<Server> upList = lb.getReachableServers();//獲得當前活著的服務List<Server> allList = lb.getAllServers();//獲取所有的服務int serverCount = allList.size();if (serverCount == 0) {return null;}//int index = chooseRandomInt(serverCount);//生成區間隨機數//server = upList.get(index);//從或活著的服務中,隨機獲取一個//=====================自定義代碼=========================if (total < 5) {server = upList.get(currentIndex);total++;} else {total = 0;currentIndex++;if (currentIndex > upList.size()) {currentIndex = 0;}server = upList.get(currentIndex);//從活著的服務中,獲取指定的服務來進行操作}//======================================================if (server == null) {Thread.yield();continue;}if (server.isAlive()) {return (server);}// Shouldn't actually happen.. but must be transient or a bug.server = null;Thread.yield();}return server;}protected int chooseRandomInt(int serverCount) {return ThreadLocalRandom.current().nextInt(serverCount);}@Overridepublic Server choose(Object key) {return choose(getLoadBalancer(), key);}@Overridepublic void initWithNiwsConfig(IClientConfig clientConfig) {// TODO Auto-generated method stub}}7、Feign:負載均衡(基于服務端)
7.1 、Feign簡介
Feign是聲明式Web Service客戶端,它讓微服務之間的調用變得更簡單,類似controller調用service。SpringCloud集成了Ribbon和Eureka,可以使用Feigin提供負載均衡的http客戶端。
只需要創建一個接口,然后添加注解即可~
Feign,主要是社區版,大家都習慣面向接口編程。這個是很多開發人員的規范。調用微服務訪問兩種方法
Feign能干什么?
- Feign旨在使編寫Java Http客戶端變得更容易
- 前面在使用Ribbon + RestTemplate時,利用RestTemplate對Http請求的封裝處理,形成了一套模板化的調用方法。但是在實際開發中,由于對服務依賴的調用可能不止一處,往往一個接口會被多處調用,所以通常都會針對每個微服務自行封裝一個客戶端類來包裝這些依賴服務的調用。所以,Feign在此基礎上做了進一步的封裝,由他來幫助我們定義和實現依賴服務接口的定義,==在Feign的實現下,我們只需要創建一個接口并使用注解的方式來配置它 (類似以前Dao接口上標注Mapper注解,現在是一個微服務接口上面標注一個Feign注解),==即可完成對服務提供方的接口綁定,簡化了使用Spring Cloud Ribbon 時,自動封裝服務調用客戶端的開發量。
Feign默認集成了Ribbon
利用Ribbon維護了MicroServiceCloud-Dept的服務列表信息,并且通過輪詢實現了客戶端的負載均衡,而與Ribbon不同的是,通過Feign只需要定義服務綁定接口且以聲明式的方法,優雅而簡單的實現了服務調用。
7.2、Feign的使用步驟
拷貝springcloud-consumer-dept-80模塊下的pom.xml,resource,以及java代碼到springcloud-consumer-feign模塊,并添加feign依賴。
<!--feign--> spring-cloud-starter-feign 已經停止維護,推薦使用spring-cloud-starter-openfeign <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId><version>3.0.3</version> </dependency>通過Feign實現:改造DeptConsumerController.java
@RestController public class DeptConsumerController {// private static final String REST_URL_PREFIX = "http://SPRINGCLOUD-PROVIDER-DEPT";@Autowiredprivate DeptClientService service ;@RequestMapping("/consumer/dept/get/{id}")public Dept get(@PathVariable("id") Long id){return this.service.queryById(id);}@RequestMapping("/consumer/dept/add")public boolean add(Dept dept){return this.service.addDept(dept);}@RequestMapping("/consumer/dept/list")public List<Dept> queryAll(){return this.service.queryAll();} }Feign和Ribbon二者對比,前者顯現出面向接口編程特點,代碼看起來更清爽,而且Feign調用方式更符合我們之前在做SSM或者SprngBoot項目時,Controller層調用Service層的編程習慣!
主啟動類:
//Ribbon 和 Eureka 整合以后,客戶端可以直接調用,不用關心IP地址和端口號 @SpringBootApplication @EnableEurekaClient @EnableFeignClients(basePackages = {"com.su.springcloud"}) //@ComponentScan("com.su.springcloud") public class FeignDeptConsumer_80 {public static void main(String[] args) {SpringApplication.run(FeignDeptConsumer_80.class, args);} }pom.xml添加feign依賴
<!--feign--> <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId><version>3.0.3</version> </dependency>新建service包,并新建DeptClientService.java接口,
@Configuration @FeignClient(value = "SPRINGCLOUD-PROVIDER-DEPT") public interface DeptClientService {@GetMapping("/dept/get/{id}")Dept queryById(@PathVariable("id") Long id);@GetMapping("/dept/list")List<Dept> queryAll();@PostMapping("/dept/add")boolean addDept(Dept dept); }7.3、Feign和Ribbon如何選擇?
根據個人習慣而定,如果喜歡REST風格使用Ribbon;如果喜歡社區版的面向接口風格使用Feign.
Feign 本質上也是實現了 Ribbon,只不過后者是在調用方式上,為了滿足一些開發者習慣的接口調用習慣!
下面我們關閉springcloud-consumer-dept-80 這個服務消費方,換用springcloud-consumer-dept-feign(端口還是80) 來代替:(依然可以正常訪問,就是調用方式相比于Ribbon變化了)
8、Hystrix:服務熔斷
分布式系統面臨的問題
復雜分布式體系結構中的應用程序有數十個依賴關系,每個依賴關系在某些時候將不可避免失敗!
8.1、服務雪崩
多個微服務之間調用的時候,假設微服務A調用微服務B和微服務C,微服務B和微服務C又調用其他的微服務,這就是所謂的“扇出”,如果扇出的鏈路上某個微服務的調用響應時間過長,或者不可用,對微服務A的調用就會占用越來越多的系統資源,進而引起系統崩潰,所謂的“雪崩效應”。
對于高流量的應用來說,單一的后端依賴可能會導致所有服務器上的所有資源都在幾十秒內飽和。比失敗更糟糕的是,這些應用程序還可能導致服務之間的延遲增加,備份隊列,線程和其他系統資源緊張,導致整個系統發生更多的級聯故障,這些都表示需要對故障和延遲進行隔離和管理,以達到單個依賴關系的失敗而不影響整個應用程序或系統運行。
我們需要,棄車保帥!
8.2、什么是Hystrix?
Hystrix是一個應用于處理分布式系統的延遲和容錯的開源庫,在分布式系統里,許多依賴不可避免的會調用失敗,比如超時,異常等,Hystrix 能夠保證在一個依賴出問題的情況下,不會導致整個體系服務失敗,避免級聯故障,以提高分布式系統的彈性。
“斷路器”本身是一種開關裝置,當某個服務單元發生故障之后,通過斷路器的故障監控 (類似熔斷保險絲) ,向調用方返回一個服務預期的,可處理的備選響應 (FallBack) ,而不是長時間的等待或者拋出調用方法無法處理的異常,這樣就可以保證了服務調用方的線程不會被長時間,不必要的占用,從而避免了故障在分布式系統中的蔓延,乃至雪崩。
官網資料
https://github.com/Netflix/Hystrix/wiki
8.3、Hystrix能干嘛?
- 服務降級
- 服務熔斷
- 服務限流
- 接近實時的監控
- …
當一切正常時,請求流可以如下所示:
當許多后端系統中有一個潛在阻塞服務時,它可以阻止整個用戶請求:
隨著大容量通信量的增加,單個后端依賴項的潛在性會導致所有服務器上的所有資源在幾秒鐘內飽和。
應用程序中通過網絡或客戶端庫可能導致網絡請求的每個點都是潛在故障的來源。比失敗更糟糕的是,這些應用程序還可能導致服務之間的延遲增加,從而備份隊列、線程和其他系統資源,從而導致更多跨系統的級聯故障。
當使用Hystrix包裝每個基礎依賴項時,上面的圖表中所示的體系結構會發生類似于以下關系圖的變化。每個依賴項是相互隔離的,限制在延遲發生時它可以填充的資源中,并包含在回退邏輯中,該邏輯決定在依賴項中發生任何類型的故障時要做出什么樣的響應:
8.4、服務熔斷
什么是服務熔斷?
熔斷機制是賭贏雪崩效應的一種微服務鏈路保護機制。
當扇出鏈路的某個微服務不可用或者響應時間太長時,會進行服務的降級,進而熔斷該節點微服務的調用,快速返回錯誤的響應信息。當檢測到該節點微服務間調用的狀況,當失敗的調用到一定閾值,缺省是5秒內20次調用失敗就會啟動熔斷機制。熔斷機制的注解是 @HystriCommand。
服務熔斷解決如下問題:
- 當所依賴的對象不穩定時,能夠起到快速失敗的目的;
- 快速失敗后,能夠根據一定的算法動態試探所依賴對象是否恢復。
入門案例
新建springcloud-provider-dept-hystrix-8001模塊并拷貝springcloud-provider-dept–8001內的pom.xml、resource和Java代碼進行初始化并調整。
導入hystrix依賴
<!--導入Hystrix依賴--> <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-hystrix</artifactId><version>1.4.6.RELEASE</version> </dependency>調整yml配置文件
# Eureka 的配置, 服務注冊到哪里 eureka:client:service-url:defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/instance:instance-id: springcloud-provider-dept-hystrix-8001 # 修改Eureka 上的默認描述信息prefer-ip-address: true #改為true后默認顯示的是ip地址而不再是localhostprefer-ip-address: false:
prefer-ip-address: true:
修改controller
@RestController public class DeptController {@Autowiredprivate DeptService deptService;@HystrixCommand(fallbackMethod = "hystrixGet")@GetMapping("/dept/get/{id}")public Dept get(@PathVariable("id") Long id){Dept dept = deptService.queryById(id);if (dept==null){throw new RuntimeException("id=>"+id + "不存在該用戶,或者信息無法找到~");}return dept;}// 備選方法public Dept hystrixGet(@PathVariable("id") Long id){return new Dept().setDeptno(id).setDname("id=>"+id + "沒有對應的信息,null--@Hystrix").setDb_source("no this database in MySQL");} }為主啟動類添加對熔斷的支持注解@EnableCircuitBreaker
@SpringBootApplication @EnableEurekaClient // 自動在服務啟動后,自動注冊到Eureka中! @EnableDiscoveryClient // 服務發現~ 可以用來獲取一些配置的信息,得到具體的微服務 //添加對熔斷的支持 @EnableHystrix public class DeptProviderHystrix_8001 {public static void main(String[] args) {SpringApplication.run(DeptProviderHystrix_8001.class, args);} }測試:
使用熔斷后,當訪問一個不存在的id時,前臺頁展示數據如下:
而不適用熔斷的springcloud-provider-dept–8001模塊訪問相同地址會出現下面狀況:
因此,為了避免因某個微服務后臺出現異常或錯誤而導致整個應用或網頁報錯,使用熔斷是必要的
8.5、服務降級
什么是服務降級?
服務降級是指 當服務器壓力劇增的情況下,根據實際業務情況及流量,對一些服務和頁面有策略的不處理,或換種簡單的方式處理,從而釋放服務器資源以保證核心業務正常運作或高效運作。說白了,就是盡可能的把系統資源讓給優先級高的服務。
資源有限,而請求是無限的。如果在并發高峰期,不做服務降級處理,一方面肯定會影響整體服務的性能,嚴重的話可能會導致宕機某些重要的服務不可用。所以,一般在高峰期,為了保證核心功能服務的可用性,都要對某些服務降級處理。比如當雙11活動時,把交易無關的服務統統降級,如查看螞蟻深林,查看歷史訂單等等。
服務降級主要用于什么場景呢?當整個微服務架構整體的負載超出了預設的上限閾值或即將到來的流量預計將會超過預設的閾值時,為了保證重要或基本的服務能正常運行,可以將一些 不重要 或 不緊急 的服務或任務進行服務的 延遲使用 或 暫停使用。
降級的方式可以根據業務來,可以延遲服務,比如延遲給用戶增加積分,只是放到一個緩存中,等服務平穩之后再執行 ;或者在粒度范圍內關閉服務,比如關閉相關文章的推薦。
由上圖可得,當某一時間內服務A的訪問量暴增,而B和C的訪問量較少,為了緩解A服務的壓力,這時候需要B和C暫時關閉一些服務功能,去承擔A的部分服務,從而為A分擔壓力,叫做服務降級。
服務降級需要考慮的問題
- 1)哪些服務是核心服務,哪些服務是非核心服務?
- 2)哪些服務可以支持降級,哪些服務不能支持降級,降級策略是什么?
- 3)除服務降級之外是否存在更復雜的業務放通場景,策略是什么?
自動降級分類
1)超時降級:主要配置好超時時間和超時重試次數和機制,并使用異步機制探測回復情況
2)失敗次數降級:主要是一些不穩定的api,當失敗調用次數達到一定閥值自動降級,同樣要使用異步機制探測回復情況
3)故障降級:比如要調用的遠程服務掛掉了(網絡故障、DNS故障、http服務返回錯誤的狀態碼、rpc服務拋出異常),則可以直接降級。降級后的處理方案有:默認值(比如庫存服務掛了,返回默認現貨)、兜底數據(比如廣告掛了,返回提前準備好的一些靜態頁面)、緩存(之前暫存的一些緩存數據)
4)限流降級:秒殺或者搶購一些限購商品時,此時可能會因為訪問量太大而導致系統崩潰,此時會使用限流來進行限制訪問量,當達到限流閥值,后續請求會被降級;降級后的處理方案可以是:排隊頁面(將用戶導流到排隊頁面等一會重試)、無貨(直接告知用戶沒貨了)、錯誤頁(如活動太火爆了,稍后重試)。
在springcloud-api模塊下的 service包中 新建降級配置類 DeptClientServiceFallBackFactory.java
// 服務降級~ @Component public class DeptClientServiceFallbackFactory implements FallbackFactory {@Overridepublic DeptClientService create(Throwable throwable) {return new DeptClientService() {@Overridepublic Dept queryById(Long id) {return new Dept().setDeptno(id).setDname("id=>"+id+"沒有對應的信息,客戶端提供了降級的信息,這個服務現在已經被關閉了").setDb_source("沒有數據~");}@Overridepublic List<Dept> queryAll() {return null;}@Overridepublic boolean addDept(Dept dept) {return false;}};} }在DeptClientService中指定降級配置類DeptClientServiceFallBackFactory
@Configuration // 微服務客戶端注解,value:指定微服務的名字,這樣就可以使Feign客戶端直接找到對應的微服務 @FeignClient(value = "SPRINGCLOUD-PROVIDER-DEPT" ,fallbackFactory = DeptClientServiceFallbackFactory.class) public interface DeptClientService {@GetMapping("/dept/get/{id}")Dept queryById(@PathVariable("id") Long id);@GetMapping("/dept/list")List<Dept> queryAll();@PostMapping("/dept/add")boolean addDept(Dept dept); }在springcloud-consumer-dept-feign模塊中開啟降級:
server:port: 80# 開啟降級feign.hystrix feign:hystrix:enabled: true# Eureka 配置 eureka:client:register-with-eureka: falseservice-url:defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/8.6、服務熔斷和降級的區別
服務熔斷—>服務端:某個服務超時或異常,引起熔斷~,類似于保險絲(自我熔斷)
服務降級—>客戶端:從整體網站請求負載考慮,當某個服務熔斷或者關閉之后,服務將不再被調用,此時在客戶端,我們可以準備一個 FallBackFactory ,返回一個默認的值(缺省值)。會導致整體的服務下降,但是好歹能用,比直接掛掉強。
觸發原因不太一樣,服務熔斷一般是某個服務(下游服務)故障引起,而服務降級一般是從整體負荷考慮;管理目標的層次不太一樣,熔斷其實是一個框架級的處理,每個微服務都需要(無層級之分),而降級一般需要對業務有層級之分(比如降級一般是從最外圍服務開始)
實現方式不太一樣,服務降級具有代碼侵入性(由控制器完成/或自動降級),熔斷一般稱為自我熔斷。
熔斷,降級,限流:
限流:限制并發的請求訪問量,超過閾值則拒絕;
降級:服務分優先級,犧牲非核心服務(不可用),保證核心服務穩定;從整體負荷考慮;
熔斷:依賴的下游服務故障觸發熔斷,避免引發本系統崩潰;系統自動執行和恢復
8.7、Dashboard 流監控
新建 springcloud-consumer-hystrix-dashboard 模塊
添加依賴
spring-cloud-starter-hystrix 已停止維護,推薦使用 spring-cloud-starter-netflix-hystrix
<dependencies><!--Hystrix依賴--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-hystrix</artifactId><version>2.2.9.RELEASE</version></dependency><!--dashboard依賴--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId><version>2.2.9.RELEASE</version></dependency><!--Ribbon--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-ribbon</artifactId><version>2.2.9.RELEASE</version></dependency><!--Eureka: Ribbon需要從Eureka服務中心獲取要拿什么--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</artifactId><version>2.2.9.RELEASE</version></dependency><dependency><groupId>com.su</groupId><artifactId>springcloud-api</artifactId><version>1.0-SNAPSHOT</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId><version>2.4.5</version></dependency> </dependencies>配置文件
server:port: 9001主啟動類
@SpringBootApplication @EnableHystrixDashboard // 開啟 public class DeptConsumerDashboard_9001 {public static void main(String[] args) {SpringApplication.run(DeptConsumerDashboard_9001.class, args);} }啟動后訪問 http://localhost:9001/hystrix
給springcloud-provider-dept-hystrix-8001模塊下的主啟動類添加如下代碼,添加監控
@SpringBootApplication @EnableEurekaClient // 自動在服務啟動后,自動注冊到Eureka中! @EnableDiscoveryClient // 服務發現~ 可以用來獲取一些配置的信息,得到具體的微服務 //添加對熔斷的支持 @EnableHystrix public class DeptProviderHystrix_8001 {public static void main(String[] args) {SpringApplication.run(DeptProviderHystrix_8001.class, args);}// 增加一個Servlet@Beanpublic ServletRegistrationBean hystrixMetricsStreamServlet(){ServletRegistrationBean registrationBean = new ServletRegistrationBean(new HystrixMetricsStreamServlet());//訪問該頁面就是監控頁面registrationBean.addUrlMappings("/actuator/hystrix.stream");return registrationBean;} }訪問 http://localhost:8001/actuator/hystrix.stream
這里如果一直ping的話,啟動80端口,訪問http://localhost/consumer/dept/get/1之后
再次訪問http://localhost:8001/actuator/hystrix.stream
進入監控頁面:
Unable to connect to Command Metric Stream 可以在
9001模塊的配置文件下添加:
hystrix:dashboard:proxy-stream-allow-list: "*"重新訪問
現在訪問http://localhost/consumer/dept/get/1
一直刷新,發現刷新的越快,這個圓圈就變的越大,停止一段時間后又變小
如何看
-
七色
-
一圈
實心圓:公有兩種含義,他通過顏色的變化代表了實例的健康程度
它的健康程度從綠色<黃色<橙色<紅色 遞減
該實心圓除了顏色的變化之外,它的大小也會根據實例的請求流量發生變化,流量越大,該實心圓就越大,所以通過該實心圓的展示,就可以在大量的實例中快速發現故障實例和高壓力實例
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-sgHxgw2K-1640001797533)(G:\jieduan2333\JavaEE第四階段\watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3N1MjIzMTU5NTc0Mg==,size_16,color_FFFFFF,t_70)]
-
一線
曲線:用來記錄2分鐘內流量的相對變化,可以通過它來觀察流量的上升和下降趨勢
-
整圖說明
搞懂一個才能看懂復雜的
9、Zull路由網關
9.1、概述
什么是zuul?
Zull包含了對請求的路由和過濾兩個最主要功能:
其中路由功能負責將外部請求轉發到具體的微服務實例上,是實現外部訪問統一入口的基礎,而過濾器功能則負責對請求的處理過程進行干預,是實現請求校驗,服務聚合等功能的基礎。Zuul和Eureka進行整合,將Zuul自身注冊為Eureka服務治理下的應用,同時從Eureka中獲得其他服務的消息,也即以后的訪問微服務都是通過Zuul跳轉后獲得。
注意:Zuul 服務最終還是會注冊進 Eureka
提供:代理 + 路由 + 過濾 三大功能!
Zuul 能干嘛?
- 路由
- 過濾
官方文檔:https://github.com/Netflix/zuul/
新建springcloud-zuul模塊,并導入依賴
spring-cloud-starter-zuul 已經停止維護,建議使用 spring-cloud-starter-netflix-zuul
<!-- zuul依賴--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-zuul</artifactId><version>2.2.9.RELEASE</version></dependency><!-- Hystrix依賴--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-hystrix</artifactId><version>2.2.9.RELEASE</version></dependency><!--dashboard依賴--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId><version>2.2.9.RELEASE</version></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId><version>3.0.3</version></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-ribbon</artifactId><version>2.2.9.RELEASE</version></dependency><!--Eureka: Ribbon需要從Eureka服務中心獲取要拿什么--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</artifactId><version>2.2.9.RELEASE</version></dependency><dependency><groupId>com.su</groupId><artifactId>springcloud-api</artifactId><version>1.0-SNAPSHOT</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId><version>2.4.5</version></dependency> </dependencies>application.yml
server:port: 9527spring:application:name: springcloud-zuuleureka:client:service-url:defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/instance:instance-id: zuul9527.comprefer-ip-address: trueinfo:app.name: kuang-springcloud # 項目名稱company.name: blog.kuangstudy.com # 公司名稱# zull 路由網關配置 zuul:# 路由相關配置# 原來訪問路由 http://www.kuangstudy.com:9527/springcloud-provider-dept/dept/get/1# zull路由配置后訪問路由 http://www.kuangstudy.com:9527/kuang/mydept/dept/get/1routes:mydept.serviceId: springcloud-provider-dept # eureka注冊中心的服務提供方路由名稱mydept.path: /mydept/** # 將eureka注冊中心的服務提供方路由名稱 改為自定義路由名稱# 不能再使用這個路徑訪問了,*: 忽略,隱藏全部的服務名稱~ignored-services: "*"# 設置公共的前綴prefix: /kuang修改 hosts
主啟動類
@SpringBootApplication @EnableZuulProxy // 開啟zuul public class ZuulApplication_9527 {public static void main(String[] args) {SpringApplication.run(ZuulApplication_9527.class, args);} }測試
可以看出Zull路由網關被注冊到Eureka注冊中心中了!
上圖是沒有經過Zull路由網關配置時,服務接口訪問的路由,可以看出直接用微服務(服務提供方)名稱去訪問,這樣不安全,不能將微服務名稱暴露!
所以經過Zull路由網關配置后,訪問的路由為:
我們看到,微服務名稱被替換并隱藏,換成了我們自定義的微服務名稱mydept,同時加上了前綴haust,這樣就做到了對路由訪問的加密處理!
詳情參考springcloud中文社區zuul組件 :https://www.springcloud.cc/spring-cloud-greenwich.html#_router_and_filter_zuul
10、Spring Cloud Config 分布式配置
Dalston.RELEASE
Spring Cloud Config為分布式系統中的外部配置提供服務器和客戶端支持。使用Config Server,您可以在所有環境中管理應用程序的外部屬性??蛻舳撕头掌魃系母拍钣成渑cSpring Environment和PropertySource抽象相同,因此它們與Spring應用程序非常契合,但可以與任何以任何語言運行的應用程序一起使用。隨著應用程序通過從開發人員到測試和生產的部署流程,您可以管理這些環境之間的配置,并確定應用程序具有遷移時需要運行的一切。服務器存儲后端的默認實現使用git,因此它輕松支持標簽版本的配置環境,以及可以訪問用于管理內容的各種工具。很容易添加替代實現,并使用Spring配置將其插入。
10.1、概述
分布式系統面臨的–配置文件問題
微服務意味著要將單體應用中的業務拆分成一個個子服務,每個服務的粒度相對較小,因此系統中會出現大量的服務,由于每個服務都需要必要的配置信息才能運行,所以一套集中式的,動態的配置管理設施是必不可少的。spring cloud提供了configServer來解決這個問題,我們每一個微服務自己帶著一個application.yml,那上百個的配置文件修改起來,令人頭疼!
什么是SpringCloud config分布式配置中心?
spring cloud config 為微服務架構中的微服務提供集中化的外部支持,配置服務器為各個不同微服務應用的所有環節提供了一個中心化的外部配置。
spring cloud config 分為服務端和客戶端兩部分。
服務端也稱為 分布式配置中心,它是一個獨立的微服務應用,用來連接配置服務器并為客戶端提供獲取配置信息,加密,解密信息等訪問接口。
客戶端則是通過指定的配置中心來管理應用資源,以及與業務相關的配置內容,并在啟動的時候從配置中心獲取和加載配置信息。配置服務器默認采用git來存儲配置信息,這樣就有助于對環境配置進行版本管理。并且可用通過git客戶端工具來方便的管理和訪問配置內容。
spring cloud config 分布式配置中心能干嘛?
- 集中式管理配置文件
- 不同環境,不同配置,動態化的配置更新,分環境部署,比如 /dev /test /prod /beta /release
- 運行期間動態調整配置,不再需要在每個服務部署的機器上編寫配置文件,服務會向配置中心統一拉取配置自己的信息
- 當配置發生變動時,服務不需要重啟,即可感知到配置的變化,并應用新的配置
- 將配置信息以REST接口的形式暴露
spring cloud config 分布式配置中心與GitHub整合
由于spring cloud config 默認使用git來存儲配置文件 (也有其他方式,比如自持SVN 和本地文件),但是最推薦的還是git ,而且使用的是 http / https 訪問的形式。
10.2、入門案例
在碼云新建倉庫 springcloud-config
克隆到本地
新建application.yml文件
spring:profiles:active: dev--- spring:profiles: devapplication:name: springcloud-config-dev--- spring:profiles: testapplication:name: springcloud-config-test然后上傳到云倉庫
https://gitee.com/su_shuwang/springcloud-config
服務端
新建springcloud-config-server-3344模塊導入pom.xml依賴
<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!--Eureka--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</artifactId><version>2.2.9.RELEASE</version></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-config-server</artifactId><version>2.2.6.RELEASE</version></dependency><!-- actuator完善監控信息--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId></dependency> </dependencies>resource下創建application.yml配置文件,Spring Cloud Config服務器從git存儲庫(必須提供)為遠程客戶端提供配置:
server:port: 3344spring:application:name: springcloud-config-server# 連接碼云遠程倉庫cloud:config:server:git:# 注意是https的而不是sshuri: https://gitee.com/su_shuwang/springcloud-config.git# 不加這個配置會報Cannot execute request on any known server 這個錯:連接Eureka服務端地址不對 # 或者直接注釋掉eureka依賴 這里暫時用不到eureka eureka:client:register-with-eureka: falsefetch-registry: false主啟動類
@SpringBootApplication @EnableConfigServer public class Config_Server_3344 {public static void main(String[] args) {SpringApplication.run(Config_Server_3344.class, args);} }測試訪問http://localhost:3344/application-dev.yml
測試訪問http://localhost:3344/application-test.yml
測試訪問 http://localhost:3344/application/test/master
定位資源的默認策略是克隆一個git倉庫(在spring.cloud.config.server.git.uri),并使用它來初始化一個迷你SpringApplication。小應用程序的Environment用于枚舉屬性源并通過JSON端點發布。
HTTP服務具有以下格式的資源:
/{application}/{profile}[/{label}] /{application}-{profile}.yml /{label}/{application}-{profile}.yml /{application}-{profile}.properties /{label}/{application}-{profile}.properties其中“應用程序”作為SpringApplication中的spring.config.name注入(即常規的Spring Boot應用程序中通常是“應用程序”),“配置文件”是活動配置文件(或逗號分隔列表的屬性),“label”是可選的git標簽(默認為“master”)。
客戶端
在本地git倉庫springcloud-config文件夾下新建的config-client.yml提交到碼云倉庫:
spring:profiles:active: dev--- server:port: 8201# spring的配置 spring:profiles: devapplication:name: springcloud-provider-dept# Eureka 的配置, 服務注冊到哪里 eureka:client:service-url:defaultZone: http://eureka7001.com:7001/eureka/--- server:port: 8202# spring的配置 spring:profiles: testapplication:name: springcloud-provider-dept# Eureka 的配置, 服務注冊到哪里 eureka:client:service-url:defaultZone: http://eureka7001.com:7001/eureka/新建一個springcloud-config-client-3355模塊,并導入依賴
<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-config</artifactId><version>2.2.8.RELEASE</version></dependency><!-- actuator完善監控信息--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId></dependency> </dependencies>resources下創建application.yml和bootstrap.yml配置文件
bootstrap.yml 是系統級別的配置
# 系統級別的配置 spring:cloud:config:uri: http://localhost:3344name: config-client # 需要從git上讀取的資源名稱,不需要后綴profile: devlabel: masterapplication.yml 是用戶級別的配置
# 用戶級別的配置 spring:application:name: springcloud-config-client-3355創建controller包下的ConfigClientController.java 用于測試
@RestController public class ConfigClientController {@Value("${spring.application.name}")private String applicationName;@Value("${spring.client.service-url.defaultZone}")private String eurekaServer;@Value("${server.port}")private String port;@GetMapping("/config")public String getConfig() {return "applicationName:" + applicationName +"eurekaServer:" + eurekaServer +"port:" + port;} }主啟動類
@SpringBootApplication public class ConfigClient_3355 {public static void main(String[] args) {SpringApplication.run(ConfigClient_3355.class, args);} }測試:
啟動服務端Config_server_3344 再啟動客戶端ConfigClient
訪問:http://localhost:8201/config/
10.3、實戰測試
在springcloud-config下新建config-eureka.yml 文件
spring:profiles:active: dev---server:port: 7001spring:profiles: devapplication:name: springcloud-config-eurekaeureka:instance:hostname: eureka7001.comclient:register-with-eureka: falsefetch-registry: falseservice-url:defaultZone: http://eureka7002.com:7002/eureka/, http://eureka7003.com:7003/eureka/---server:port: 7001spring:profiles: testapplication:name: springcloud-config-eurekaeureka:instance:hostname: eureka7001.comclient:register-with-eureka: falsefetch-registry: falseservice-url:defaultZone: http://eureka7002.com:7002/eureka/, http://eureka7003.com:7003/eureka/新建config-dept.yml文件
spring:profiles:active: dev---server:port: 8001mybatis:type-aliases-package: com.su.springcloud.pojoconfig-location: classpath:mybatis/mybatis-config.xmlmapper-locations: classpath:mybatis/mapper/*.xmlspring:profiles: devapplication:name: springcloud-provider-deptdatasource:type: com.alibaba.druid.pool.DruidDataSourcedriver-class-name: com.mysql.jdbc.Driverurl: jdbc:mysql://localhost:3306/db01?useUnicode=true&characterEncoding=utf-8&useSSL=falseusername: rootpassword: 123456eureka:client:service-url:defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/instance:instance-id: springcloud-provider-dept8001 # 修改Eureka 上的默認描述信息prefer-ip-address: true # 訪問路徑可以顯示ip地址info:app.name: kuangshen-springcloudcompany.name: blog.kuangstudy.com---server:port: 8001mybatis:type-aliases-package: com.su.springcloud.pojoconfig-location: classpath:mybatis/mybatis-config.xmlmapper-locations: classpath:mybatis/mapper/*.xmlspring:profiles: testapplication:name: springcloud-provider-deptdatasource:type: com.alibaba.druid.pool.DruidDataSourcedriver-class-name: com.mysql.jdbc.Driverurl: jdbc:mysql://localhost:3306/db02?useUnicode=true&characterEncoding=utf-8&useSSL=falseusername: rootpassword: 123456eureka:client:service-url:defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/instance:instance-id: springcloud-provider-dept8001 # 修改Eureka 上的默認描述信息prefer-ip-address: true # 訪問路徑可以顯示ip地址info:app.name: kuangshen-springcloudcompany.name: blog.kuangstudy.com上傳云倉庫
新建springcloud-config-eureka-7001模塊,并將原來的springcloud-eureka-7001模塊下的內容拷貝的該模塊。
1.在pom.xml中添加spring cloud config依賴
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-config</artifactId><version>2.2.8.RELEASE</version> </dependency>2.清空該模塊的application.yml配置,并新建bootstrap.yml連接遠程配置
bootstrap.yml
spring:cloud:config:name: config-eurekalabel: masterprofile: devuri: http://localhost:3344application.yml
spring:application:name: spring-cloud-eureka-70013.主啟動類
4.測試
第一步:啟動 Config_Server_3344,并訪問 http://localhost:3344/master/config-eureka-dev.yml 測試
第二部:啟動ConfigEurekaServer_7001,訪問 http://localhost:7001/ 測試
顯示上圖則成功
新建springcloud-config-dept-8001模塊并拷貝springcloud-provider-dept-8001的內容
同理導入spring cloud config依賴、清空application.yml 、新建bootstrap.yml配置文件并配置
spring:cloud:config:name: config-deptlabel: masterprofile: devuri: http://localhost:3344用戶級別的配置
spring:application:name: springcloud-config-client-3355主啟動類
@SpringBootApplication @EnableEurekaClient // 自動在服務啟動后,自動注冊到Eureka中! @EnableDiscoveryClient // 服務發現~ 可以用來獲取一些配置的信息,得到具體的微服務 public class ConfigDeptProvider_8001 {public static void main(String[] args) {SpringApplication.run(ConfigDeptProvider_8001.class, args);} }完結撒花
總結
以上是生活随笔為你收集整理的SpringCloud 超详细个人笔记的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: access开发精要(4)-参考与查阅
- 下一篇: 学习Spring Boot:(十六)使用