轉自:https://blog.csdn.net/pengjunlee/article/details/86688858
服務熔斷
服務熔斷的作用類似於我們家用的保險絲,當某服務出現不可用或響應超時的情況時,為了防止整個系統出現雪崩,暫時停止對該服務的調用。
服務降級
服務降級是從整個系統的負荷情況出發和考慮的,對某些負荷會比較高的情況,為了預防某些功能(業務場景)出現負荷過載或者響應慢的情況,在其內部暫時舍棄對一些非核心的接口和數據的請求,而直接返回一個提前准備好的fallback(退路)錯誤處理信息。這樣,雖然提供的是一個有損的服務,但卻保證了整個系統的穩定性和可用性。
熔斷VS降級
相同點:
目標一致 都是從可用性和可靠性出發,為了防止系統崩潰;
用戶體驗類似 最終都讓用戶體驗到的是某些功能暫時不可用;
不同點:
觸發原因不同 服務熔斷一般是某個服務(下游服務)故障引起,而服務降級一般是從整體負荷考慮;
管理目標的層次不太一樣,熔斷其實是一個框架級的處理,每個微服務都需要(無層級之分),而降級一般需要對業務有層級之分(比如降級一般是從最外圍服務開始);
Hystrix簡介
Hystrix:英 [hɪst'rɪks] 美 [hɪst'rɪks] ,翻譯過來是“豪豬”的意思。 在分布式環境中,不可避免地會出現某些依賴的服務發生故障的情況。Hystrix是這樣的一個庫,它通過添加容許時延和容錯邏輯來幫助你控制這些分布式服務之間的交互。Hystrix通過隔離服務之間的訪問點,阻止跨服務的級聯故障,並提供了退路選項,所有這些都可以提高系統的整體彈性。
Hystrix的設計目的:
通過第三方客戶端的庫來為訪問依賴服務時的潛在故障提供保護和控制;
防止在復雜分布式系統中出現級聯故障;
快速失敗和迅速恢復;
在允許的情況下,提供退路對服務進行優雅降級;
提供近實時的監控、報警和操作控制;
接下來我們將通過對《模擬RPC調用(Feign)》一章中的 message-center 項目進行改造,演示如何使用Hystrix,eureka服務注冊中心以及message-service服務提供者無需更改。
使用Hystrix
引入Hystrix依賴
在 pom.xml 文件中引入Hystrix依賴:
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.6.RELEASE</version> </parent> <properties> <spring-cloud.version>Finchley.SR2</spring-cloud.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- Eureka-Client 依賴 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <!-- Feign 依賴 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency> <!-- Hystrix 依賴 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-hystrix</artifactId> </dependency> </dependencies> <dependencyManagement> <dependencies> <!-- SpringCloud 版本控制依賴 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>${spring-cloud.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>
修改啟動類
在MessageCenterApplication啟動類上增加@EnableCircuitBreaker注解:
@SpringBootApplication @EnableFeignClients @EnableCircuitBreaker public class MessageCenterApplication { public static void main(String[] args) { new SpringApplicationBuilder(MessageCenterApplication.class).web(WebApplicationType.SERVLET).run(args); } }
這里我們在啟動類中又增加了@EnableCircuitBreaker注解,用來開啟斷路器功能。如果你覺得啟動類上的注解個數有點多的話,可以使用一個@SpringCloudApplication 注解來代替@SpringBootApplication(或者@EnableEurekaServer)、@EnableDiscoveryClient、@EnableCircuitBreaker這三個注解。
@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited @SpringBootApplication @EnableDiscoveryClient @EnableCircuitBreaker public @interface SpringCloudApplication { }
修改Controller
接下來,我們為MessageCenterController中的getMsg()接口增加斷路器功能,修改部分代碼如下:
@GetMapping("/msg/get") @HystrixCommand(fallbackMethod = "getMsgFallback") public Object getMsg() { String msg = messageService.getMsg(); return msg; } public Object getMsgFallback() { return "祝您 2019 豬年大吉,'豬'事如意!"; }
先啟動Eureka,再啟動一個8771端口的message-service服務,最后啟動message-center。待啟動完成之后,Eureka注冊中心實例注冊信息如下:
此時,訪問 http://localhost:8781/api/v1/center/msg/get ,返回如下結果表明服務調用成功:
然后,停掉message-service服務,再次請求 http://localhost:8781/api/v1/center/msg/get ,返回結果如下:
可以看出fallback中的信息被直接返回了,表明Hystrix斷路器調用成功。
注意:fallback方法的簽名需要和原方法保持一致。
/** * 獲取消息詳情 */ @GetMapping("/api/v1/msg/detail/{id}") @HystrixCommand(fallbackMethod = "getDetailFallback") public MessageEntity getDetail(@PathVariable(name = "id") Long id) { return messageService.getById(id); } /** * 獲取消息詳情退路 */ public MessageEntity getDetailFallback(Long id){ return null; }
Feign結合Hystrix
以MessageService的Feign客戶端為例,為其添加Hystrix斷路器功能。
修改Feign客戶端
通過配置@FeignClient注解的fallback屬性來位MessageServiceClient指定一個自定義的fallback處理類(MessageServiceFallback)。
@FeignClient(name = "message-service", fallback = MessageServiceFallback.class) public interface MessageServiceClient { @GetMapping("/api/v1/msg/get") public String getMsg(); }
創建Fallback處理類
MessageServiceFallback需要實現MessageServiceClient接口,並且在Spring容器中必須存在一個該類型的有效Bean。在這里,我們使用@Component注解將其注入到Spring容器中。
@Component public class MessageServiceFallback implements MessageServiceClient { @Override public String getMsg() { System.out.println("調用消息接口失敗,對其進行降級處理!"); return "消息接口繁忙,請稍后重試!"; } }
修改配置
在新版本的Springcloud中,Feign默認關閉了對Hystrix的支持,需要在application.yml進行配置:
feign: hystrix: enabled: true
當message-service服務不可用時,請求 http://localhost:8781/api/v1/center/msg/get,返回結果如下:
查看后台日志,打印如下內容,表明fallback方法被成功調用了:
監控Hystrix
啟用健康監控
Actuator是Springboot提供的用來對應用系統進行自省和監控的功能模塊,借助於Actuator開發者可以很方便地對應用系統某些監控指標進行查看、統計等。
若要使用Actuator對Hystrix 流進行監控,除了需在工程POM文件中引入spring-boot-starter-actuator依賴:
<!-- Actuator 依賴 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency>
還需要在application.yml 中添加如下配置:
management: endpoints: web: exposure: include: hystrix.stream
啟用Hystrix-Dashboard
使用Hystrix一個最大的好處就是它會為我們自動收集每一個HystrixCommand的信息,並利用Hystrix-Dashboard通過一種高效的方式對每一個斷路器的健康狀態進行展示。
值得注意的是,在使用HystrixCommand對RibbonClient進行包裝的時候,你需要確保你配置的Hystrix超時時間要比Ribbon的超時時間長,包括由它們引起的重試時間,舉個例子:如果你的Ribbon連接超時時間是1秒,並且Ribbon會連續重試請求3次,那么你的Hystrix連接超時時間需要配置成稍大於3秒。
引入Hystrix-Dashboard依賴
在 pom.xml 文件中引入Hystrix-Dashboard依賴:
<!-- Hystrix Dashboard 依賴 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId> </dependency>
修改啟動類
在MessageCenterApplication啟動類上增加@EnableHystrixDashboard注解:
@EnableFeignClients @SpringCloudApplication @EnableHystrixDashboard public class MessageCenterApplication { public static void main(String[] args) { new SpringApplicationBuilder(MessageCenterApplication.class).web(WebApplicationType.SERVLET).run(args); } }
儀表盤界面
啟動應用,訪問 http://localhost:8781/hystrix ,打開Hystrix-Dashboard監控首頁。
在這里配置好需要監控的Hystrix流地址 http://localhost:8781/actuator/hystrix.stream ,開始監控。
參考文章
https://github.com/netflix/hystrix/wiki
https://github.com/netflix/hystrix
https://cloud.spring.io/spring-cloud-netflix/single/spring-cloud-netflix.html