spring cloud 學習(4) - hystrix 服務熔斷處理


hystrix 是一個專用於服務熔斷處理的開源項目,當依賴的服務方出現故障不可用時,hystrix有一個所謂的斷路器,一但打開,就會直接攔截掉對故障服務的調用,從而防止故障進一步擴大(類似中電路中的跳閘,保護家用電器)。

使用步驟:(仍然在之前的示例代碼上加以改造)

一、添加hystrix依賴

compile 'org.springframework.cloud:spring-cloud-starter-hystrix'

 

二、在需要熔斷的方法上添加注解

package com.cnblogs.yjmyzz.spring.cloud.study.service.controller;

import com.cnblogs.yjmyzz.spring.cloud.study.dto.UserDTO;
import com.cnblogs.yjmyzz.spring.cloud.study.service.client.UserFeignClient;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

import java.util.Random;

@RestController
public class OrderController {

    @Autowired
    private UserFeignClient userFeignClient;

    private final Random rnd = new Random(System.currentTimeMillis());

    @GetMapping("/order/{userId}/{orderNo}")
    @HystrixCommand(fallbackMethod = "findOrderFallback", commandProperties = {
            @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "1000")
    })
    public String findOrder(@PathVariable Integer userId, @PathVariable String orderNo) throws InterruptedException {
        Thread.sleep(rnd.nextInt(2000));
        UserDTO user = userFeignClient.findUser(userId);
        if (user != null) {
            return user.getUserName() + " 的訂單" + orderNo + " 找到啦!";
        }
        return "用戶不存在!";
    }

    public String findOrderFallback(Integer userId, String orderNo) {
        return "訂單查找失敗!";
    }
}  

注意findOrder上添加的HystrixCommand注解,大概意思是,如果這個方法調用失敗,會切換到備用方法findOrderFallback上,而且還設置了一個超時時間1000ms,即1秒。換句話說,如果findOrder方法沒有在1s內返回結果,也算調用失敗,同樣會切換到備用方法findOrderFallback上。

注:為了方便演示,故意在findOrder上隨機停了2秒內的一段時間,所以預期這個方法,應該會偶爾超時,偶爾正常。

關於HystrixProperty的更多屬性,可參考github上的官方文檔:https://github.com/Netflix/Hystrix/wiki/Configuration 

 

三、main入口上啟用hytrix熔斷

@EnableDiscoveryClient
@SpringBootApplication
@EnableFeignClients
@EnableCircuitBreaker
public class ServiceConsumer {

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

啟用后,訪問http://localhost:8002/order/1/100 ,可以看到類似以下輸出:

正常時,返回類似上圖的輸出,如果超時,將返回下圖:

此外,spring-boot的acturator也提供了health端點來查看hystrix狀態,查看http://localhost:8002/health

這個表示hystrix的斷路器未打開,如果 http://localhost:8002/order/1/100 這個頁面狂刷(默認要5秒內失敗20次以上),或者干脆把service-provider停掉,這個狀態會變成:

表明此時斷路器是打開的。

 

四、hystrix監控

health端點只能看到斷路器的整體狀態,但是對於細節展示不夠詳細,默認情況下,只要啟用了hystrix功能,還會暴露一個端點hystrix.stream

訪問 http://localhost:8002/hystrix.stream 可以查看詳細的數據

注:這個頁面會實時不斷輸出新的內容(如果有的話),首次訪問的話,如果看到一直轉圈,但是沒有任何內容,說明這時服務對應的方法沒人調用,可以訪問findOrder方法后,再來看這個頁面。

顯然,一堆密密麻麻的文字,沒有人會喜歡看,spring-cloud早就想到這一點了,提供了一個hystrix-dashboard的功能,可以用圖形化的界面來解讀這些數據。

再起一個項目,名為hystrix-dashboard,build.gradle參考下面:

buildscript {
    repositories {
        maven {
            url "http://maven.aliyun.com/nexus/content/groups/public/"
        }
    }
    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:1.5.4.RELEASE")
    }
}

apply plugin: 'org.springframework.boot'

dependencyManagement {
    imports {
        mavenBom "org.springframework.cloud:spring-cloud-dependencies:Dalston.RELEASE"
    }
}

dependencies {
    compile 'org.springframework.cloud:spring-cloud-starter-eureka'
    compile 'org.springframework.cloud:spring-cloud-starter-hystrix-dashboard'
    compile 'org.springframework.boot:spring-boot-starter-actuator'
}

main函數如下:

package com.cnblogs.yjmyzz.spring.cloud.study.hystrix;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.hystrix.dashboard.EnableHystrixDashboard;

/**
 * Created by yangjunming on 2017/6/30.
 */
@SpringBootApplication
@EnableHystrixDashboard
@EnableDiscoveryClient
public class HystrixDashboardApplication {
    public static void main(String[] args) {
        SpringApplication.run(HystrixDashboardApplication.class, args);
    }
}  

當然,這也是一個微服務,也可以注冊到eureka上,參考下面的配置:

spring:
  application:
    name: hystrix-dashboard
server:
  port: 8035


eureka:
  instance:
    prefer-ip-address: true
  client:
    service-url:
      defaultZone: http://yjmyzz:123456@server1:8100/eureka,http://yjmyzz:123456@server2:8200/eureka,http://yjmyzz:123456@server3:8300/eureka

啟用成功后,訪問http://localhost:8035/hystrix,會出現類似下面這個界面:

第1個輸入框里,填寫要監控的hystrix.steam地址,然后title這里起一個名字即可,然后點擊monitor steam,就能看到圖表:

這顯然比純文字友好多了。還有一個問題,如果有多個hystrix.stream地址同時監控,或者把多個地址的數據匯總起來,該怎么弄?github上有一個turbine ,就是專門為解決這個問題的,大家可以自行研究下。

最后,附上文中示例代碼地址:https://github.com/yjmyzz/spring-cloud-demo


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM