遇到記錄不完全的可以看看這個人的部落格
學相伴SpringCloud
SpringCloud 是一個生態!其實也就是解決上面四個問題的一個解決方案的合集
SpringCloud NetFlix 一站式解決方案
Apache Dubbo Zookeeper 半自動解決方案 ,需要整合
Spring Cloud Alibaba 一站式解決方案! 更簡單
提及一個新概念: 服務網格~ Server Mesh
istio
路由 通訊 高可用 服務降級
主要緣由就是網路不可靠:可能會掉包丟幀
1.Spring Cloud就是微服務系統架構的一站式解決方案,是各個微服務架構落地技術的集合體,俗稱微服務全家桶
2.在平時我們構建微服務的過程中需要做如服務發現註冊、設定中心、負載均衡、斷路器、資料監控等操作,
而Spring Cloud 為我們提供了一套簡易的程式設計模型,使我們能在 Spring Boot 的基礎上輕鬆地實現微服務專案的構建
1.將各個元件分開部署,某個元件佔一個伺服器,互相獨立,互相呼叫,可以將元件的功能發揮強大
2.一個業務分拆多個子業務,部署在不同的伺服器上(不同的伺服器,執行不同的程式碼,為了同一個目的)
優點:
1.模組之間獨立,各做各的事,便於擴充套件,複用性高
2.高吞吐量。某個任務需要一個機器執行20個小時,將該任務用10臺機器的分散式跑
(將這個任務拆分成10個小任務),可能2個小時就跑完了
同一個業務,部署在多個伺服器上(不同的伺服器執行同樣的程式碼,幹同一件事)
優點:
1.通過多臺計算機完成同一個工作,達到更高的效率。
2.兩機或多機內容、工作過程等完全一樣。如果一臺宕機,另一臺可以起作用。
叢集和分散式並不衝突,可以有分散式叢集
//我們可以把java,前端,測試看成是分散式,把都在做java的看成是叢集
1.簡單來說微服務就是很小的服務,小到一個服務只對應一個單一的功能,只做一件事
2.將一個大的專案,按照需求(業務服務)模組拆解成一個個獨立小模組(微小服務),然後獨立部署,它們之間獨立又相互呼叫
缺點:
。開發人員要處理分散式系統的複雜性。多服務運維難度,隨著服務的增加,運維的壓力也在增大
。系統部署依賴
。服務間通訊成本
。資料一致性
。系統整合測試
效能監控.....
SpringBoot專注於快速、方便的開發單個微服務個體,SpringCloud關注全域性的服務治理框架。
//區別:SpringBoot可以離開SpringCloud獨立使用開發專案,但是SpringCloud離不開SpringBoot,屬於依賴的關係.
1.服務註冊與發現:Eureka
2.使用者端負載均衡: Ribbon
3.服務熔斷與降級: Hystrix
4.宣告式服務呼叫:Feign
5.API閘道器服務:Spring Cloud Zuul
6.分散式服務跟蹤:Spring Cloud Sleuth&Zipkin
7.分散式設定中心:Spring Cloud Config
SpringCloud拋棄了Dubbo的RPC通訊,採用的是基於HTTP的REST方式
在社群的活躍度上面,SpringCloud更為活躍
SpringCloud的功能要比Dubbo更加強大,涵蓋面更廣,因為它能與Spring的其他框架完美融合
SpringCloud和Dubbo就類似於 品牌機和組裝機的區別
Dubbo的定位是一款RPC框架,SpringCloud的目標是微服務架構下的一站式解決方案
Nginx指向我們的前端頁面,然後存取後端的閘道器,閘道器在幫我們分發到微服務中去
NetFlix五大神獸:eureka ribbon feign hsytrix zull
一共編寫了5種微服務物件:
springCloud-api(提供一些常用的類和介面,其他每一個微服務都需要匯入這個依賴)
<dependency>
<groupId>com.mao</groupId>
<artifactId>springCloud-api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
springCloud-provider 服務提供者,後續使用的Rest服務以及Eureka中的範例id,都是該服務的spring application name的名字
spring:
application:
name: springCloud-provider-userInfo-8081
springCloud-consumer 服務消費者
提供了一個RestTemplate模板
首先需要將RestTemplate注入進IOC容器中
@Configuration
public class ConfigBean { //@Configuration 相當於 springApplication.xml 設定bean
@Bean
public RestTemplate getRestTemplate(){
return new RestTemplate();
}
}
然後就可以直接呼叫使用了
// 消費者中 不應該有service層
// 提供了一個RestTemplate模板 我們可以直接呼叫
//(url,實體 map, Class<T> responseType) 引數
@Autowired
private RestTemplate restTemplate;
/*
首先要去 設定類 中將RestTemplate註冊進去
RestTemplate 提供了多種便捷存取的遠端http服務的方法,類似於Dubbo中的Reference,他就是個簡單的Restful服務模板
*/
/**
* 伺服器端提供服務的url地址
*/
private static final String REST_URL_PREFIX = "http://localhost:8081";
@GetMapping("/getAllUser")
public List<UserInfo> queryAllUser(){
return restTemplate.getForObject(REST_URL_PREFIX+"/user/list",List.class);
}
Eureka包含兩個元件:Eureka Server和 Eureka Client
Eureka Server提供服務註冊服務,各個節點啟動後,會在EurekaServer中進行註冊,這樣Eureka Server中的服務登入檔中將會村粗所有可用服務節點的資訊,服務節點的資訊可以在介面中直觀的看到。
Eureka Client是一個Java使用者端,用於簡化EurekaServer的互動,使用者端同時也具備一個內建的,使用輪詢負載演演算法的負載均衡器。在應用啟動後,將會向EurekaServer傳送心跳(預設週期為30秒)。如果Eureka Server在多個心跳週期內沒有接收到某個節點的心跳,EurekaServer將會從服務登入檔中把這個服務節點移除掉(預設週期為90秒)
o Eureka Server:提供服務的註冊於發現。zookeeper
o Service Provider:將自身服務註冊到Eureka中,從而使消費方能夠找到。
o Service Consumer:服務消費方從Eureka中獲取註冊服務列表,從而找到消費服務。
匯入依賴:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
<version>2.2.9.RELEASE</version>
</dependency>
如果出現Error creating bean with name 'traceFilterRegistration' 的報錯,說明我們引入的SpringBoot和SpringCloud的依賴不匹配,可以去官網檢視匹配的依賴包
設定註冊中心
server:
port: 7001
#spring的設定
spring:
eureka:
instance:
hostname: localhost #Eureka伺服器端的範例名稱
client:
register-with-eureka: false #表示是否想eureka註冊中心註冊自己
fetch-registry: false #fetch-registry如果為false,則表示自己就是註冊中心
service-url:
#這其實就是一個監控中心的地址,相當於Dubbo中的Dubbo-admin
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
${eureka.instance.hostname} 可以拿到組態檔中的值,活的,動態設定和靜態設定的區別
在Eureka的啟動類上加上@EnableEurekaServer註解,表示他是一個伺服器端的啟動類,可以接受別人註冊進來
http://localhost:7001/ 可以存取這個介面,也就是監控中心
匯入依賴 同上
可以匯入actuator依賴,並且在啟動類上加上@EnableDiscoveryClient註解 檢視對應的已註冊服務的相關資訊(可忽略)@EnableDiscoveryClient和@EnableEurekaClient共同點就是:都是能夠讓註冊中心能夠發現,掃描到改服務。
不同點:@EnableEurekaClient只適用於Eureka作為註冊中心,@EnableDiscoveryClient 可以是其他註冊中心。
<!-- actuator完善監控資訊 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
http://localhost:8081/actuator/info
//匯入springcloud下面的discovery
/**
* 讀取一些設定的資訊,得到具體的微服務
*/
@Autowired
UserInfoService userInfoService;
/**
* 註冊進來的微服務,獲取一些資訊
* @return
*/
@GetMapping("/discovery")
public Object discovery(){
// 獲取所有的微服務清單
List<String> services = client.getServices();
System.out.println(services);
// 得到一個具體的微服務資訊,通過具體的微服務serviceId,applicationName
List<ServiceInstance> instances = client.getInstances("SPRINGCLOUD-PROVIDER-USERINFO-8081");
for (ServiceInstance instance : instances) {
System.out.println(instance);
}
return this.client;
}
設定eureka
#Eureka的設定,服務註冊到哪裡
eureka:
client:
service-url:
defaultZone: http://localhost:7001/eureka/
instance:
instance-id: springcloud-provider-user8001 #修改eureka上的預設描述資訊
#info設定
info:
app.name: mao-springcloud
company.name: maomao.com
在服務提供者的啟動類上加上@EnableEurekaClient註解 // 他會在服務啟動後自動註冊到Eureka註冊中心中
自我保護機制:
EMERGENCY! EUREKA MAY BE INCORRECTLY CLAIMING INSTANCES ARE UP WHEN THEY'RE NOT. RENEWALS ARE LESSER THAN THRESHOLD AND HENCE THE INSTANCES ARE NOT BEING EXPIRED JUST TO BE SAFE.
就是類似於你在 hosts檔案中設定了自己的 host一樣
檔案的位置:C:\Windows\System32\drivers\etc\hosts
127.0.0.1 eureka7001
127.0.0.1 eureka7002
127.0.0.1 eureka7003
你只需要多起幾個註冊中心,每個註冊中心的設定以及導包都是一樣的,只是埠不同
然後這幾個eureka互相掛載就可以了,這樣就可以稱之為叢集(就算你在執行的時候,一個註冊中心掛了還有其他的可以用)
如何掛載?:在註冊中心的組態檔中的defaultZone屬性,輸入其他的eureka服務,多個就用逗號隔開
註冊中心的設定:
eureka:
instance:
hostname: eureka7002 #Eureka伺服器端的範例名稱
# hostname: eureka7002 #Eureka伺服器端的範例名稱
client:
register-with-eureka: false # 表示是否想eureka註冊中心註冊自己
fetch-registry: false # fetch-registry如果為false,則表示自己就是註冊中心
service-url: # 監控介面
# 單機: defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
# 叢集(關聯)互相掛載
defaultZone: http://eureka7001:7001/eureka/
# 如果是有多個的話 可以使用逗號隔開
# defaultZone: http://eureka7002:7002/eureka/,http://eureka7003:7003/eureka/
服務提供者的設定:(我們還需要將服務釋出到所有的註冊中心上)
eureka:
client:
service-url:
# 將服務釋出到所有註冊中心上
defaultZone: http://eureka7001:7001/eureka/,http://eureka7002:7002/eureka/,http://eureka7003:7003/eureka/
a
RDBMS(Mysql、Oracle、SQLServer) ===》ACID
NoSQL(Redis、MongoDB) ===》CAP
CAP的三進二:CA、AP、CP
一個分散式系統只能滿足兩個特性,不可能三者兼得
CAP理論:一個分散式系統不可能同時滿足C(一致性),A(可用性),P(容錯性)
由於P(分割區容錯性)在分散式系統中是必須要保證的,所以我們只能在A和C之間權衡
區別:zookeeper需要呼叫同名介面,而Eureka只需要通過連結即可
Conclusion:因此,Eureka可以很好的應對因網路故障導致部分節點失去聯絡的情況,而不會像zookeeper那樣使整個註冊服務癱瘓
在消費者的微服務中使用 Consumer
匯入依賴,Eureka裡面自帶了Ribbon
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
<version>2.2.9.RELEASE</version>
</dependency>
在消費者的啟動類上加上@EnableEurekaClient註解
編寫Eureka設定
#Eureka設定
eureka:
client:
register-with-eureka: false
service-url:
defaultZone: http://eureka7001:7001/eureka/,http://eureka7002:7002/eureka/
在我們的設定類中的 RestTemplate方法上加上@LoadBalanced //Ribbon 註解,就可以使用了
修改Rest服務的字首地址:在我們使用了Ribbon之後,Rest服務的地址不再是之前的寫死的提供者的地址,而是使用服務提供者在Eureka中的id來作為Rest服務的字首
private static final String REST_URL_PREFIX = "http://SPRINGCLOUD-PROVIDER-USERINFO-8081";
記得這個時候就需要在服務提供者那裡設定
prefer-ip-address: true才能自動獲取本機url
不然會報: No instances available for xxx服務 的報錯
eureka:
instance:
instance-id: springcloud-provider-user8081 #修改eureka上的預設描述資訊
prefer-ip-address: true
可以啟動測試了。。。
在這之後,使用者每次呼叫介面,都只需要在消費端中設定好對應服務在Eureka中註冊使用的ID就可以
P6-P11
我是很後面才來看狂神的視訊的稍微說幾個點,給那些版本和我一樣高的人躲一些坑:
我的springboot版本時2.5.3的,eureka依賴用的是spring-cloud-starter-netflix-eureka-client和spring-cloud-starter-netflix-eureka-server都是3.0.3版本的。
1.首先狂神視訊用的spring-cloud-starter-eureka和spring-cloud-starter-eureka-server已經被丟棄了,官方推薦使用spring-cloud-starter-netflix-eureka-client和spring-cloud-starter-netflix-eureka-server,並且spring-cloud-starter-netflix-eureka-client3.0.x版本(2.2.9版本的不太清楚)是包含對ribbon的依賴的,所以你就不用ribbon原來的依賴了。出ServerPropertiesAutoConfiguration.class] cannot be opened和no instances available…報錯可以嘗試將原來的那些包替換成我的,原來的程式碼不用變
2.在ribbon的視訊裡,@RibbonClient註解在3.0.3版本里已經沒有,可以用@LoadBalancerClient替換
然後我找了一下原始碼,沒有找到IRule類,且官方的負載均衡演演算法好像也只有輪詢和隨機了(我只找到這兩個),兩者實現ReactorServiceInstanceLoadBalancer介面可以用@Bean註解來儲存我們自定義的負載均衡演演算法。
由於本人程式碼能力比較差,很多地方還不太理解,看原始碼也存在很多問題,比如程式碼中的Mono類看不懂,IRule類不見了應該用什麼替換?希望有大佬能指點一下,如果上文有錯誤的地方,也希望大家能指出。
多註冊幾個提供相同服務的服務提供者,但是每個服務提供者的服務Id不同,伺服器埠不同,存取的資料庫也不同(每個資料庫內的資料表都是相同的,都是在組態檔中修改一下即可),然後註冊進去Eureka,就可以了,消費者在請求的時候Ribbon就會自動幫我們輪詢找到合適的服務提供者
IRule(策略),這是一個介面(閘道器),也就是一些實現這個介面的一些類就是Ribbon為我們提供的一些負載均衡演演算法
在設定類中注入一個Bean(寫在啟動類所在包同級的設定類中,就是放到@ComponentScan掃描的包外面)
可以使用
@RibbonClient(name = "xxx",configuration = XxxRibbonConfig.class)
註解在啟動類上,載入指定我Ribbon設定類
@Bean
Public IRule myRule(){
return new RandomRule();
return 返回自己重寫的策略就可以了;
}
Ribbon 和 Feign 目的:都是為了解決微服務的遠端呼叫
feign是宣告式的web service使用者端,它讓微服務之間的呼叫變得更簡單了,類似controller呼叫service。SpringCloud整合了Ribbon和Eureka,可在使用Feign時提供負載均衡的http使用者端。
只需要建立一個介面,然後新增註解即可!
feign,主要是社群,大家都習慣面向介面程式設計。這個是很多開發人員的規範。呼叫微服務存取兩種方法
微服務名字 [ribbon]
介面和註解[feign]
建立一個微服務springCloud-consumer-user-feign,匯入之前消費者一樣的依賴
注意區分Feign提供的sevice介面和Feign的controller控制器
匯入依賴
Feign停更閉源了,openFeign 是官方的而且是增強版的Feign並整合了Ribbon,支援SpringMVC註解。Alibaba 用的是Dubbo RPC
在springCloud-api和springCloud-consumer-user-feign中匯入Feign依賴
<!--Feign-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
<version>2.2.9.RELEASE</version>
</dependency>
編寫消費者介面(類似於Dubbo中的Reference)
使用@FeignClient(value = "Eureka中服務提供者的id")
重點就在使用對映註解寫的url地址:一定要跟服務提供者provider的controller的url對映地址一致,不然會報錯
在springCloud-api中寫一個介面在Service中,UserClientService
介面中的方法跟我們方法提供者中的Service介面內的方法一致
Feign為我們做的就是讓我們編寫的這個介面類似於之前消費者中的controller
@Component
// 有了這個註解,就類似於之前Dubbo的reference一樣,可以直接呼叫
@FeignClient(value = "SPRINGCLOUD-PROVIDER-USERINFO-8081")
public interface UserClientService {
@GetMapping("/user/list")
List<UserInfo> queryAllUser();
}
在Fiegn模組的controller中,注入springCloud-api中提供的UserClientService介面
@RestController
@RequestMapping("/consumer")
public class UserConsumerController {
// 注入我們的springCloud-api中提供的UserClientService介面
@Autowired
private UserClientService service = null;
@GetMapping("/getAllUser")
public List<UserInfo> queryAllUser(){
return this.service.queryAllUser();
}
}
最後在Feign模組的啟動類上使用註解
@EnableFeignClients(basePackages = "com.mao.springcloud")
為了掃描到引入的springcloud-api模組中我們寫的Feign介面UserClientService
注:雪崩的時候沒有一片雪花是無辜的
A、B、C、D四個服務
A->B->C->D 他們在呼叫過程中某一個微服務的呼叫響應時間過長或者不可用
會導致其資源緊張。
Hystrix是一個用於處理分散式系統的延遲和容錯的開源庫,在分散式系統裡,許多依賴不可避免的會呼叫失敗,比如超時,異常等,Hystrix能夠保證在一個依賴出問題的情況下,不會導致整體服務失敗,避免級聯故障,以提高分散式系統的彈性。
「斷路器」本身是一種開關裝置,當某個服務單元發生故障之後,通過斷路器的故障監控(類似熔斷保險絲),向呼叫方返回一個服務預期的,可處理的備選響應(FallBack),而不是長時間的等待或者丟擲呼叫方法無法處理的異常,這樣就可以保證了服務呼叫方的執行緒不會被長時間,不必要的佔用,從而避免了故障在分散式系統中的蔓延,乃至雪崩
舉例:這裡有多個服務
A->B->C1->D,結果此時C1崩了,這時候Hystrix就會調出一個備選方案C2用來頂替C1
熔斷機制:是對應雪崩效應的一種微服務鏈路保護機制。
當扇出鏈路的某個微服務不可用或者響應時間太長時,會進行服務的降級,進而熔斷該節點微服務的呼叫,快速返回錯誤的響應資訊。當檢測到該節點微服務呼叫響應正常後恢復呼叫鏈路。在SpringCloud框架裡熔斷機制通過Hystrix實現。Hystrix會監控微服務間呼叫的狀況,當失敗的呼叫到一定閾值,預設是5秒內20次呼叫失敗就會啟動熔斷機制。熔斷機制的註解是@HystrixCommand。
起一個微服務,內容與服務提供者大致相同,就是在controller層中多加了幾個Hystrix方法
spring-cloud-start-hystrix
在該方法呼叫異常時 呼叫指定方法,類似重定向@HystrixCommand(fallbackMethod = "xxx方法")
新增對熔斷的支援 @EnableCircuitBreaker
匯入依賴,啟動類上加@EnableHystrixDashboard註解
API Gateway
Zuul包含了對請求的路由和過濾兩個最主要的功能:
其中路由功能負責將外部請求轉發到具體的微服務範例上(也就是將原有的真實請求地址localhost:8080隱藏,修改成類似於www.xxx.com的地址),是實現外部存取統一入口的基礎,而過濾器功能則負責對請求的處理過程進行干預,是實現請求校驗,服務聚合等功能的基礎。Zuul和Eureka進行整合,將Zuu自身註冊為Eureka服務治理下的應用,同時從Eureka中獲得其他微服務的訊息,也即以後的存取微服務都是通過Zuul跳轉後獲得。
注意: Zuul服務最終還是會註冊進Eureka,也要註冊進Eureka中
提供:代理 + 路由 + 過濾 三大功能!
匯入依賴
spring-cloud-start-zuul
寫好設定類
設定Spring相關資訊,將zuul註冊進Eureka
啟動類上加@EnableZuulProxy註解支援Zuul
修改zuul的相關設定,即可做到路由和過濾的功能(存取的時候,服務的id大寫不起作用就用小寫)
輸入指定的路由地址,就可以存取到服務
zuul:
routes:
mydept.serviceId: springcloud-provider-dept
mydept.path: /mydept/**
忽略掉指定的地址,在請求的時候就會報錯,就不能在使用該路徑存取了
zuul:
ignored-services: "*"
# 這是設定公共的字首,存取的路徑前必須加上字首
prefix: /mao
因為分散式微服務有很多設定,我們就可以提供一個東西,把所有的設定放到裡面,在需要的時候就去裡面拿就可以
Spring Cloud Config 為微服務架構中的微服務提供集中化的外部設定支援,設定伺服器為各個不同微服務應用的所有環節提供了一個中心化的外部設定。
Spring Cloud Config 分為伺服器端和使用者端兩部分伺服器端也稱為 分散式設定中心,它是一個獨立的微服務應用,用來連線設定伺服器併為使用者端提供獲取設定資訊,加密,解密資訊等存取介面。
使用者端則是通過指定的設定中心來管理應用資源,以及與業務相關的設定內容,並在啟動的時候從設定中心獲取和載入設定資訊。設定伺服器預設採用gt來儲存設定資訊,這樣就有助於對環境設定進行版本管理。並且可以通過git使用者端工具來方便的管理和存取設定內容。
由於Spring Cloud Config 預設使用Git來儲存組態檔(也有其他方式,比如支援SVN和本地檔案),但是最推薦的還是Git ,而且使用的是 http / https 存取的形式
本文來自部落格園,作者:沒有煩惱的貓貓,轉載請註明原文連結:https://www.cnblogs.com/maomao777/p/17072754.html