javascript
Spring Cloud【Finchley】-08使用Hystrix实现容错
文章目錄
- 概述
- 實現容錯主要方式
- Hystrix簡介
- 通用方式整合Hystrix
- Step1 新建子module
- Step2 pom增加spring-cloud-starter-netflix-hystrix依賴
- Step3 啟動類增加@EnableCircuitBreaker或者@EnableHystrix注解
- Step4 控制層增加注解即容錯方法
- Step5 測試
- 代碼
概述
前面的幾篇博文,我們接觸到了Eureka實現服務的注冊于發現、Ribbon實現客戶端負載均衡、Feign實現聲明式的API調用,談到微服務,容錯也是不得不提的話題之一。
Soring Cloud 集成了Hystrix來提供容錯的能力,從而實現微服務的容錯。
實現容錯主要方式
假設服務提供者的響應很慢,那么消費者的請求將會被強制等待,直到響應或者超時。 在高負載的情況下,很有可能發生的情況是,當依賴的服務不可用,自身的服務也被拖垮,這就是雪崩效應,當服務提供者不可用導致消費者不可用,并將不可用逐漸放大的過程。
容錯的主要手段:
為網絡請求設置超時: 通常情況下一次遠程調用對應一個線程,如果響應太慢,這個線程就得不到釋放,而線程占用的資源當然也不會被釋放,當高并發或者未處理完的線程越來越多,資源終將被耗盡。
使用斷路器模式:如果有對某個微服務的請求存在大量超時,禁止訪問該微服務,防止雪崩。 當該微服務可用,斷路器可以自動診斷是否已經恢復,恢復訪問請求,從而實現微服務的自我修復
從而提升應用的高可用性。
Hystrix簡介
https://github.com/netflix/hystrix
Hystrix是一個實現了超時機制和斷路器模式的工具類庫, 是由Netfix開源的一個延遲和容錯庫,用于隔離訪問遠程系統、服務或者第三方庫,防止級聯失敗,從而提升系統可用性與容錯性。
機制:
當Hystrix Command請求后端服務失敗數量超過一定比例(默認50%), 斷路器會切換到開路狀態(Open).這時所有請求會直接失敗而不會發送到后端服務.
斷路器保持在開路狀態一段時間后(默認5秒), 自動切換到半開路狀態(HALF-OPEN). 這時會判斷下一次請求的返回情況, 如果請求成功, 斷路器切回閉路狀態(CLOSED), 否則重新切換到開路狀態(OPEN).
Hystrix的斷路器就像我們家庭電路中的保險絲, 一旦后端服務不可用, 斷路器會直接切斷請求鏈, 避免發送大量無效請求影響系統吞吐量,并且斷路器有自我檢測并恢復的能力.
Hystrix主要通過以下幾點實現延遲和容錯:
通用方式整合Hystrix
Spring Cloud官方指導:https://cloud.spring.io/spring-cloud-static/Finchley.SR2/single/spring-cloud.html#_circuit_breaker_hystrix_clients
Step1 新建子module
因為熔斷是發生在調用方即消費者,所以我們copy個消費者的工程
父工程microservice-spring-cloud右鍵新建Maven Module 命名為:micorservice-consumer-movie-ribbon-hystrix ,為了簡單我們把micorservice-consumer-movie-ribbon的內容copy到該子模塊,修改下application.yml中的spring.application.name即可。
Step2 pom增加spring-cloud-starter-netflix-hystrix依賴
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-hystrix</artifactId> </dependency>Step3 啟動類增加@EnableCircuitBreaker或者@EnableHystrix注解
package com.artisan.micorservice;import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker; import org.springframework.cloud.client.loadbalancer.LoadBalanced; import org.springframework.context.annotation.Bean; import org.springframework.web.client.RestTemplate;@SpringBootApplication @EnableCircuitBreaker public class MicorserviceMovieRibbonHystrix {@Bean@LoadBalancedpublic RestTemplate restTemplate(){return new RestTemplate();}public static void main(String[] args) {SpringApplication.run(MicorserviceMovieRibbonHystrix.class, args);} }Step4 控制層增加注解即容錯方法
package com.artisan.micorservice.controller;import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cloud.client.ServiceInstance; import org.springframework.cloud.client.loadbalancer.LoadBalancerClient; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.client.RestTemplate;import com.artisan.micorservice.model.User; import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;import lombok.extern.slf4j.Slf4j;@RestController public class MovieController {@Autowiredprivate RestTemplate restTemplate;@AutowiredLoadBalancerClient loadBalancerClient;@HystrixCommand(fallbackMethod = "findByIdDefault")@GetMapping("/movie/{id}")public User findById(@PathVariable Long id) {return this.restTemplate.getForObject("http://microservice-provider-user/user/" + id, User.class);}/*** * @param id* @return* @desc 當請求失敗、超時、被拒絕,或當斷路器打開時,執行的邏輯*/public User findByIdDefault(Long id) {User user = new User();user.setId(id);user.setUsername("默認用戶");return user;}}從上述Controller層的方法中,可以看到我們在findById方法上增加了注解 @HystrixCommand(fallbackMethod = “findByIdDefault”),并通過fallbackMethod 屬性指定了當請求失敗、超時、被拒絕,或當斷路器打開時,執行的方法findByIdDefault.
HystrixCommand注解還可以使用注解HystrixProperty的commandProperties屬性來配置HystrixCommand
比如
@HystrixCommand(fallbackMethod = "findByIdDefault",commandProperties= {@HystrixProperty(name="execution.isolation.thread.timeoutInMilliseconds",value="5000"),@HystrixProperty(name="metrics.rollingStats.timeInMilliseconds",value="10000")},threadPoolProperties= {@HystrixProperty(name="coreSize",value="1"),@HystrixProperty(name="maxQueueSize",value="10")})@GetMapping("/movie/{id}")public User findById(@PathVariable Long id) {return this.restTemplate.getForObject("http://microservice-provider-user/user/" + id, User.class);}可配置的屬性見官網: https://github.com/Netflix/Hystrix/tree/master/hystrix-contrib/hystrix-javanica#configuration
Step5 測試
訪問http://localhost:8761/ 確認下服務已經注冊成功。
訪問: http://localhost:7902/movie/2 ,返回
{"id":2,"username":"artisan2","name":"小工匠二","age":20,"balance":200.00}停止 micorservice-provider-user,服務提供者 ,注冊中心上已經沒有該服務了。
訪問http://localhost:7902/movie/2 ,可訪問多次,均返回
{"id":2,"username":"默認用戶","name":null,"age":null,"balance":null}已經走到了我們自定義的方法中。
再次啟動 micorservice-provider-user,服務提供者
訪問http://localhost:7902/movie/2
{"id":2,"username":"artisan2","name":"小工匠二","age":20,"balance":200.00}服務已經恢復。
當請求失敗、被拒絕、超時或者斷路器打開時都會進入到回退的方法,當進入回退方法并不意味著斷路器已經被打開。
代碼
https://github.com/yangshangwei/SpringCloudMaster/tree/master/micorservice-consumer-movie-ribbon-hystrix
總結
以上是生活随笔為你收集整理的Spring Cloud【Finchley】-08使用Hystrix实现容错的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Spring Cloud【Finchle
- 下一篇: Spring Cloud【Finchle