javascript
Spring Cloud【Finchley】-08使用Hystrix实现容错
文章目錄
- 概述
- 實(shí)現(xiàn)容錯(cuò)主要方式
- Hystrix簡(jiǎn)介
- 通用方式整合Hystrix
- Step1 新建子module
- Step2 pom增加spring-cloud-starter-netflix-hystrix依賴
- Step3 啟動(dòng)類增加@EnableCircuitBreaker或者@EnableHystrix注解
- Step4 控制層增加注解即容錯(cuò)方法
- Step5 測(cè)試
- 代碼
概述
前面的幾篇博文,我們接觸到了Eureka實(shí)現(xiàn)服務(wù)的注冊(cè)于發(fā)現(xiàn)、Ribbon實(shí)現(xiàn)客戶端負(fù)載均衡、Feign實(shí)現(xiàn)聲明式的API調(diào)用,談到微服務(wù),容錯(cuò)也是不得不提的話題之一。
Soring Cloud 集成了Hystrix來(lái)提供容錯(cuò)的能力,從而實(shí)現(xiàn)微服務(wù)的容錯(cuò)。
實(shí)現(xiàn)容錯(cuò)主要方式
假設(shè)服務(wù)提供者的響應(yīng)很慢,那么消費(fèi)者的請(qǐng)求將會(huì)被強(qiáng)制等待,直到響應(yīng)或者超時(shí)。 在高負(fù)載的情況下,很有可能發(fā)生的情況是,當(dāng)依賴的服務(wù)不可用,自身的服務(wù)也被拖垮,這就是雪崩效應(yīng),當(dāng)服務(wù)提供者不可用導(dǎo)致消費(fèi)者不可用,并將不可用逐漸放大的過(guò)程。
容錯(cuò)的主要手段:
為網(wǎng)絡(luò)請(qǐng)求設(shè)置超時(shí): 通常情況下一次遠(yuǎn)程調(diào)用對(duì)應(yīng)一個(gè)線程,如果響應(yīng)太慢,這個(gè)線程就得不到釋放,而線程占用的資源當(dāng)然也不會(huì)被釋放,當(dāng)高并發(fā)或者未處理完的線程越來(lái)越多,資源終將被耗盡。
使用斷路器模式:如果有對(duì)某個(gè)微服務(wù)的請(qǐng)求存在大量超時(shí),禁止訪問(wèn)該微服務(wù),防止雪崩。 當(dāng)該微服務(wù)可用,斷路器可以自動(dòng)診斷是否已經(jīng)恢復(fù),恢復(fù)訪問(wèn)請(qǐng)求,從而實(shí)現(xiàn)微服務(wù)的自我修復(fù)
從而提升應(yīng)用的高可用性。
Hystrix簡(jiǎn)介
https://github.com/netflix/hystrix
Hystrix是一個(gè)實(shí)現(xiàn)了超時(shí)機(jī)制和斷路器模式的工具類庫(kù), 是由Netfix開(kāi)源的一個(gè)延遲和容錯(cuò)庫(kù),用于隔離訪問(wèn)遠(yuǎn)程系統(tǒng)、服務(wù)或者第三方庫(kù),防止級(jí)聯(lián)失敗,從而提升系統(tǒng)可用性與容錯(cuò)性。
機(jī)制:
當(dāng)Hystrix Command請(qǐng)求后端服務(wù)失敗數(shù)量超過(guò)一定比例(默認(rèn)50%), 斷路器會(huì)切換到開(kāi)路狀態(tài)(Open).這時(shí)所有請(qǐng)求會(huì)直接失敗而不會(huì)發(fā)送到后端服務(wù).
斷路器保持在開(kāi)路狀態(tài)一段時(shí)間后(默認(rèn)5秒), 自動(dòng)切換到半開(kāi)路狀態(tài)(HALF-OPEN). 這時(shí)會(huì)判斷下一次請(qǐng)求的返回情況, 如果請(qǐng)求成功, 斷路器切回閉路狀態(tài)(CLOSED), 否則重新切換到開(kāi)路狀態(tài)(OPEN).
Hystrix的斷路器就像我們家庭電路中的保險(xiǎn)絲, 一旦后端服務(wù)不可用, 斷路器會(huì)直接切斷請(qǐng)求鏈, 避免發(fā)送大量無(wú)效請(qǐng)求影響系統(tǒng)吞吐量,并且斷路器有自我檢測(cè)并恢復(fù)的能力.
Hystrix主要通過(guò)以下幾點(diǎn)實(shí)現(xiàn)延遲和容錯(cuò):
通用方式整合Hystrix
Spring Cloud官方指導(dǎo):https://cloud.spring.io/spring-cloud-static/Finchley.SR2/single/spring-cloud.html#_circuit_breaker_hystrix_clients
Step1 新建子module
因?yàn)槿蹟嗍前l(fā)生在調(diào)用方即消費(fèi)者,所以我們copy個(gè)消費(fèi)者的工程
父工程microservice-spring-cloud右鍵新建Maven Module 命名為:micorservice-consumer-movie-ribbon-hystrix ,為了簡(jiǎn)單我們把micorservice-consumer-movie-ribbon的內(nèi)容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 啟動(dòng)類增加@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 控制層增加注解即容錯(cuò)方法
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 當(dāng)請(qǐng)求失敗、超時(shí)、被拒絕,或當(dāng)斷路器打開(kāi)時(shí),執(zhí)行的邏輯*/public User findByIdDefault(Long id) {User user = new User();user.setId(id);user.setUsername("默認(rèn)用戶");return user;}}從上述Controller層的方法中,可以看到我們?cè)趂indById方法上增加了注解 @HystrixCommand(fallbackMethod = “findByIdDefault”),并通過(guò)fallbackMethod 屬性指定了當(dāng)請(qǐng)求失敗、超時(shí)、被拒絕,或當(dāng)斷路器打開(kāi)時(shí),執(zhí)行的方法findByIdDefault.
HystrixCommand注解還可以使用注解HystrixProperty的commandProperties屬性來(lái)配置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);}可配置的屬性見(jiàn)官網(wǎng): https://github.com/Netflix/Hystrix/tree/master/hystrix-contrib/hystrix-javanica#configuration
Step5 測(cè)試
訪問(wèn)http://localhost:8761/ 確認(rèn)下服務(wù)已經(jīng)注冊(cè)成功。
訪問(wèn): http://localhost:7902/movie/2 ,返回
{"id":2,"username":"artisan2","name":"小工匠二","age":20,"balance":200.00}停止 micorservice-provider-user,服務(wù)提供者 ,注冊(cè)中心上已經(jīng)沒(méi)有該服務(wù)了。
訪問(wèn)http://localhost:7902/movie/2 ,可訪問(wèn)多次,均返回
{"id":2,"username":"默認(rèn)用戶","name":null,"age":null,"balance":null}已經(jīng)走到了我們自定義的方法中。
再次啟動(dòng) micorservice-provider-user,服務(wù)提供者
訪問(wèn)http://localhost:7902/movie/2
{"id":2,"username":"artisan2","name":"小工匠二","age":20,"balance":200.00}服務(wù)已經(jīng)恢復(fù)。
當(dāng)請(qǐng)求失敗、被拒絕、超時(shí)或者斷路器打開(kāi)時(shí)都會(huì)進(jìn)入到回退的方法,當(dāng)進(jìn)入回退方法并不意味著斷路器已經(jīng)被打開(kāi)。
代碼
https://github.com/yangshangwei/SpringCloudMaster/tree/master/micorservice-consumer-movie-ribbon-hystrix
總結(jié)
以上是生活随笔為你收集整理的Spring Cloud【Finchley】-08使用Hystrix实现容错的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Spring Cloud【Finchle
- 下一篇: Spring Cloud【Finchle