1. 程式人生 > 實用技巧 >Spring-cloud-netflix-hystrix

Spring-cloud-netflix-hystrix

服務註冊中心eureka-server已經搭好,並且SPRING-CLOUD-NETFLIX-EUREKA-CLIENT-APPLICATION提供一個hello服務

畏怯還編寫一個eureka-client-consumer服務消費者,去消費該服務,如果在真實環境中SPRING-CLOUD-NETFLIX-EUREKA-CLIENT-APPLICATION服務掛了,就需要採用熔斷機制hystrix

Hystrix特性

1.斷路器機制

斷路器很好理解, 當Hystrix Command請求後端服務失敗數量超過一定比例(預設50%), 斷路器會切換到開路狀態(Open). 這時所有請求會直接失敗而不會發送到後端服務. 斷路器保持在開路狀態一段時間後(預設5秒), 自動切換到半開路狀態(HALF-OPEN). 這時會判斷下一次請求的返回情況, 如果請求成功, 斷路器切回閉路狀態(CLOSED), 否則重新切換到開路狀態(OPEN). Hystrix的斷路器就像我們家庭電路中的保險絲, 一旦後端服務不可用, 斷路器會直接切斷請求鏈, 避免傳送大量無效請求影響系統吞吐量, 並且斷路器有自我檢測並恢復的能力.

2.Fallback

Fallback相當於是降級操作. 對於查詢操作, 我們可以實現一個fallback方法, 當請求後端服務出現異常的時候, 可以使用fallback方法返回的值. fallback方法的返回值一般是設定的預設值或者來自快取.

3.資源隔離

在Hystrix中, 主要通過執行緒池來實現資源隔離. 通常在使用的時候我們會根據呼叫的遠端服務劃分出多個執行緒池. 例如呼叫產品服務的Command放入A執行緒池, 呼叫賬戶服務的Command放入B執行緒池. 這樣做的主要優點是執行環境被隔離開了. 這樣就算呼叫服務的程式碼存在bug或者由於其他原因導致自己所線上程池被耗盡時, 不會對系統的其他服務造成影響. 但是帶來的代價就是維護多個執行緒池會對系統帶來額外的效能開銷. 如果是對效能有嚴格要求而且確信自己呼叫服務的客戶端程式碼不會出問題的話, 可以使用Hystrix的訊號模式(Semaphores)來隔離資源.

構建服務熔斷專案

 一、新建module,勾選springcloud對應模組

   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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0
.0</modelVersion> <parent> <groupId>lf.liyouyou</groupId> <artifactId>spring-cloud-netflix-demo</artifactId> <version>1.0-SNAPSHOT</version> </parent> <groupId>lf.youyou</groupId> <artifactId>spring-cloud-eureka-client-consumer</artifactId> <version>0.0.1-SNAPSHOT</version> <name>spring-cloud-eureka-client-consumer</name> <description>Demo project for Spring Boot</description> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> <exclusions> <exclusion> <groupId>org.junit.vintage</groupId> <artifactId>junit-vintage-engine</artifactId> </exclusion> </exclusions> </dependency> </dependencies> </project>

二、啟動類添加註解

@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class SpringCloudEurekaClientConsumerApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringCloudEurekaClientConsumerApplication.class, args);
    }

}

三、編寫程式碼

  Feign介面,指定熔斷類

@FeignClient(name="spring-cloud-netflix-eureka-client-application",fallback = HelloRemoteHystrix.class)
public interface HelloRemote {

    @RequestMapping(value = "/hello")
    public String hello(@RequestParam(value = "name") String name);
}

熔斷類:

@Component
public class HelloRemoteHystrix implements HelloRemote{

    @Override
    public String hello(@RequestParam(value = "name") String name) {
        return "hello " +name+", this messge send failed ";
    }
}

Controller:

@RestController
public class HelloController {

    @Autowired
    HelloRemote helloRemote;

    @RequestMapping("/hello/{name}")
    public String index(@PathVariable("name") String name) {
        return helloRemote.hello(name);
    }

    @RequestMapping("/methodHystrix")
    @HystrixCommand(fallbackMethod = "methodHystrix")//方法熔斷
    public String getString() {
        int i = 1/0;
        return "methodHystrix";
} public String methodHystrix(){ return "methodHystrix";
} }

四、配置application.properties:

spring.application.name=spring-cloud-netflix-consumer-hystrix
server.port=9091
eureka.client.service-url.defaultZone=http://localhost:8000/eureka/
feign.hystrix.enabled=true

啟動專案,訪問註冊中心http://localhost:8000/檢視eureka面板(若之前專案未啟動,則需要全部啟動)

訪問:http://localhost:9091/hello/lf

hello lf,nice to meet you!

關閉spring-cloud-netflix-eureka-client-application服務,再訪問,即可看到

hello lf, this messge send failed

直接訪問:http://localhost:9091/methodHystrix方法熔斷

返回:methodHystrix

spring.application.name=spring-cloud-netflix-consumer-hystrix
server.port=9091
eureka.client.service-url.defaultZone=http://localhost:8000/eureka/
feign.hystrix.enabled=true
#預設只開啟了health和info,設定為*,則包含所有的web入口端點
management.endpoints.web.exposure.include=*
hystrix.dashboard.proxy-stream-allow-list=*

訪問:http://localhost:9091/hello/lf

hello lf,this is first messge

關閉spring-cloud-netflix-service-application服務,再訪問,即可看到

hello lf, this messge send failed

直接訪問:http://localhost:9091/methodHystrix

返回:methodHystrix

輸入:http://localhost:9091/hystrix進入如下頁面:

注意自己的應用是在本地還是外部,本地用http,不同版本路徑不同,2.0版本路徑為../actuator/hystrix.stream

輸入之後點選 monitor,進入頁面

出現 Unable to connect to Command Metric Stream.顯示未連線

(1)訪問自己的應用服務http://localhost:9091/actuator/hystrix.stream,顯示ping,呼叫熔斷介面http://localhost:9091/hello/lf,返回data

排除的程式碼、註解、包的問題

(2)檢視debug日誌,若出現

  Proxy opening connection to: http://localhost:9091/actuator/hystrix.stream

  WARN 6980 --- [nio-9091-exec-8] ashboardConfiguration$ProxyStreamServlet : Failed opening connection to http://localhost:9091/actuator/hystrix.stream : 404 : HTTP/1.1 404

  則需要在application.properties配置中,開啟actuator訪問

management.endpoints.web.exposure.include=*

(3)檢視debug日誌,若出現

WARN 9888 --- [nio-9091-exec-3] ashboardConfiguration$ProxyStreamServlet : Origin parameter: http://localhost:9091/actuator/hystrix.stream is not in the allowed list of proxy host names.

If it should be allowed add it to hystrix.dashboard.proxyStreamAllowList.

則需要在application.properties配置中,開啟代理訪問

hystrix.dashboard.proxy-stream-allow-list=*

重新啟動專案,重新訪問,進入hystrix面板

訪問熔斷介面,面板如下

If it should be allowed add it to hystrix.dashboard.proxyStreamAllowList.

則需要在application.properties配置中,開啟代理訪問

spring-cloud-netflix-consumer-hystrix