其實吧,寫Spring Cloud系列,我有時候覺得也挺難受的,因為Spring Cloud的微服務啟動都需要一個一個來,并且在IDea中也需要占用比較大的內存,并且我本來可以一篇寫完5大核心組件的,但是我卻分了三篇,起初我交代過,這個系列,我將會慢慢來,因為我希望,將模塊查分,這樣我自己去理的時候也蠻清楚,別人看的時候,也輕松一點,所以我才一步一步完成微服務,這五大組件,其實都是可以聚合使用的,我只是為了把他單獨劃分出來講解罷了。
并且,我寫文章的時候,大多數理論先開始,然后再舉例代碼的,我希望通過此種方式,讓我自己記憶深入一點,并且也讓讀者看到更加清楚,因為Spring Cloud對于微服務的理清楚,會比你學習的時候更加艱難,理清楚微服務之后再去學習,Spring Cloud會更加好一點。
好的,廢話說多了,今天我們的主角是Hystrix,那么我們先了解什么是Hystrix。
Hystrix
介紹
Hystrix是Netflix開源的一款用于處理分布式系統中的延遲和容錯問題的庫。它提供了線程隔離、斷路器、請求緩存、請求合并和服務降級等功能,以增加系統的彈性和可靠性。
Hystrix的底層實現機制主要包括以下幾個關鍵組件:
- 線程隔離:Hystrix使用線程池隔離每個服務調用,使得服務調用之間互不影響,提高了系統的穩定性和可靠性。
- 斷路器:Hystrix通過斷路器機制來監控服務調用的狀態,當服務調用失敗率超過一定閾值時,斷路器會打開,后續的請求將會被快速失敗,避免對故障服務的連續調用。
- 請求緩存:Hystrix可以緩存請求的結果,當相同的請求再次發生時,可以直接返回緩存的結果,減少對后端服務的調用。
- 請求合并:Hystrix可以將多個相同類型的請求合并為一個批量請求,減少網絡開銷和提高性能。
- 服務降級:Hystrix可以定義服務調用失敗時的降級邏輯,返回一個備選的結果或執行備選的邏輯,保證系統的可用性。
Hystrix可以解決分布式系統中的故障和延遲問題,提供了以下幾個主要的功能和優勢:
- 防止級聯故障:通過斷路器機制,Hystrix可以防止故障的服務調用對整個系統的影響,避免級聯故障的發生。
- 快速失敗和快速恢復:Hystrix能夠快速失敗并快速恢復,當服務調用失敗時,可以快速返回失敗結果或備選結果,提高系統的響應速度。
- 提供容錯能力:Hystrix通過服務降級和備選邏輯,可以在服務不可用或出現故障時提供備選的處理方式,保證系統的可用性。
- 監控和度量:Hystrix提供了豐富的監控和度量功能,可以實時監控服務調用的狀態和性能指標,幫助開發者了解系統的運行情況。
在Spring Cloud中,Hystrix被廣泛應用于微服務架構中的服務調用和容錯處理。通過與Ribbon和Feign等組件的集成,Spring Cloud可以自動為服務調用添加Hystrix的功能,提供了更強大的容錯能力和彈性。同時,Spring Cloud還提供了Hystrix Dashboard和Turbine等工具,用于監控和可視化Hystrix的運行狀態和指標。
注意,實際上Spring Cloud的組件是可以集成使用的,我將至分開是更好的了解這五大組件的功能,以及更好的了解Spring Cloud的微服務的搭建。
老樣子,搭建服務目錄如下:
pom.xml
<?xml version="1.0" encoding="UTF-8"?><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.miaow</groupId><version>0.0.1-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><description>Hystrix熔斷降級</description><artifactId>hystrix</artifactId><name>hystrix</name><!-- FIXME change it to the project's website --><url>http://www.example.com</url><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><maven.compiler.source>1.8</maven.compiler.source><maven.compiler.target>1.8</maven.compiler.target></properties><dependencies><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.11</version><scope>test</scope></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-hystrix</artifactId></dependency></dependencies>
</project>
application.yml
server:port: 2383
spring:application:name: hystrix-demo#路由前綴
zuul:prefix: /api# eureka客戶端注冊到Eureka注冊中心,切記需要啟動eureka服務
eureka:client:service-url:defaultZone: http://localhost:1000/eureka
啟動類
@SpringBootApplication
@EnableDiscoveryClient
@EnableCircuitBreaker
@EnableHystrix
@EnableEurekaClient
public class HystrixApplication {public static void main(String[] args) {SpringApplication.run(HystrixApplication.class);}
}
以下介紹這五個注解
@SpringBootApplication
@SpringBootApplication是一個組合注解,包含了@SpringBootConfiguration、@EnableAutoConfiguration和@ComponentScan三個注解。它的作用是標識一個Spring Boot應用程序的主類,用于啟動Spring Boot應用程序。
@EnableDiscoveryClient
@EnableDiscoveryClient注解用于啟用服務注冊與發現功能,它可以讓應用程序作為一個Eureka客戶端來注冊到Eureka Server,并從Eureka Server中獲取其他服務的信息。
@EnableCircuitBreaker
@EnableCircuitBreaker注解用于啟用斷路器功能,它可以讓應用程序使用Hystrix來實現斷路器模式,當服務調用失敗時,自動熔斷服務,避免服務雪崩。
@EnableHystrix
@EnableHystrix注解是@EnableCircuitBreaker的一個別名,用于啟用Hystrix斷路器功能。
@EnableEurekaClient
@EnableEurekaClient注解用于啟用Eureka客戶端功能,它可以讓應用程序作為一個Eureka客戶端來注冊到Eureka Server,并從Eureka Server中獲取其他服務的信息。
至此,我們以及啟動了6個微服務了:
熔斷降級案例
好的,既然我們將Spring Cloud的五大核心組件已經介紹完畢了,那么我們就用熔斷降級來完成一個案例吧,注意這是一個案例:
這是我的目錄結構:
我們創建一個電影推薦服務MovieRecommendationService,該服務提供一個方法getRecommendedMovies()來獲取推薦的電影列表。在這個例子中,我們假設該服務可能會出現故障或延遲。
import org.springframework.stereotype.Service;@Service
public class MovieRecommendationService {public List<String> getRecommendedMovies() {// 模擬電影推薦服務的調用// 這里可以是一個遠程服務調用或者其他耗時操作// 假設這里可能會出現故障或延遲// 返回一個默認的電影列表return Arrays.asList("Movie 1", "Movie 2", "Movie 3");}
}
然后,我們使用Hystrix來包裝MovieRecommendationService,實現服務降級和斷路器的功能。
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;@Service
public class HystrixMovieRecommendationService {private final MovieRecommendationService movieRecommendationService;@Autowiredpublic HystrixMovieRecommendationService(MovieRecommendationService movieRecommendationService) {this.movieRecommendationService = movieRecommendationService;}@HystrixCommand(fallbackMethod = "getDefaultMovies")public List<String> getRecommendedMovies() {return movieRecommendationService.getRecommendedMovies();}public List<String> getDefaultMovies() {// 定義一個備選的電影列表return Arrays.asList("Default Movie 1", "Default Movie 2", "Default Movie 3");}
}
在上面的代碼中,我們使用@HystrixCommand
注解來標記getRecommendedMovies()
方法,當調用該方法時,Hystrix會自動包裝該方法,并在電影推薦服務調用失敗時,調用fallbackMethod
指定的方法getDefaultMovies()
來返回備選的電影列表。
最后,我們可以在Spring Boot應用程序中使用HystrixMovieRecommendationService
來獲取推薦的電影列表。
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
public class MovieController {private final HystrixMovieRecommendationService movieRecommendationService;@Autowiredpublic MovieController(HystrixMovieRecommendationService movieRecommendationService) {this.movieRecommendationService = movieRecommendationService;}@GetMapping("/movies")public List<String> getRecommendedMovies() {return movieRecommendationService.getRecommendedMovies();}
}
在上面的代碼中,我們創建了一個MovieController
,其中注入了HystrixMovieRecommendationService
,并提供了一個GET請求的接口/movies
來獲取推薦的電影列表。
這樣,當調用/movies接口時,Hystrix
會自動對getRecommendedMovies()
方法進行包裝,當電影推薦服務調用失敗時,會返回getDefaultMovies()
方法定義的備選電影列表。
然后我們重新啟動服務,訪問:
http://localhost:2383/movies