天天看點

Hystrix 斷路器

Hystrix 斷路器

1、概述

分布式面臨的問題

複雜分布式體系結構複雜的依賴關系,不可避免的存在服務當機,網絡中斷的問題

  • 服務雪崩

多個微服務之間調用的時候,假設微服務A調用微服務B和微服務C,微服務B和微服務C又調用其他的服務,這就是所謂的扇出。如果扇出的鍊路上某個微服務的調用響應時間過長或者不可用,對微服務A的調用就會占用越來越多的系統資源,進而引起系統崩潰,所謂的雪崩效應。

對于高流量的應用來說,單一的後端依賴可能會導緻所有伺服器上的所有資源都在幾秒鐘内飽和。比失敗更糟糕的是,這些應用程式還可能導緻服務之間的延遲增加,備份隊列,線程和其他系統資源的緊張,導緻整個系統發生更多的級聯故障。這些都表示需要對故障和延遲進行隔離和管理,以便單個依賴關系的失敗,不能取消整個應用程式或系統。

Hystrix介紹

Hystrix是一個用于處理分布式系統的延遲和容錯的開源庫,在分布式系統中,許多依賴不可避免的會調用失敗,比如逾時、異常等,Hystrix能夠保證在一個依賴出問題的情況下,不會導緻整個服務失敗,避免級聯故障,以提高分布式系統的彈性。

“斷路器”本身是一種開關設定,當某個服務單元發生故障之後,通過斷路器的故障監控(類似熔斷保險絲),向調用方傳回一個符合預期的,可處理的備選響應(FallBack),而不是長時間的等待或者抛出服務方無法處理的異常,這樣就保證服務方調用線程不會被長時間、不必要的占用,進而避免故障再分布式系統中的綿延,乃至雪崩。

功能

  • 服務降級
  • 服務熔斷
  • 服務限流
  • 接近實時的監控
  • 。。。。。

官網資料:https://github.com/Netflix/Hystrix/wiki

2、服務熔斷

應對雪崩效應的一種微服務鍊路保護機制,快速傳回錯誤的響應資訊。

熔斷機制的注解:@HystrixCommand

1、參考springcloud-study-provider-dept-8001建立,springcloud-study-provider-dept-hystrix-8001子產品

  • pom檔案新增
<!--Hystrix依賴-->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>
           
  • yml檔案修改執行個體id
eureka:
  client:
    service-url:
      #defaultZone: http://localhost:7001/eureka
      defaultZone: http://localhost:7001/eureka,http://localhost:7004/eureka,http://localhost:7003/eureka

  instance:
    instance-id:  cloud-dept8001-hystrix #自定義服務名稱資訊
    prefer-ip-address: true   #通路路徑可以顯示ip位址
           
  • 修改朱啟動類名稱,并添加注解@EnableCircuitBreaker 開啟熔斷器
package com.blj.springcloud;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;

@EnableEurekaClient//本服務啟動後會自動注冊到Eureka服務中
@SpringBootApplication
@EnableDiscoveryClient //對于注冊進eureka裡面的服務,可以通過服務發現獲得該服務的資訊
@EnableCircuitBreaker//開啟熔斷器
public class DeptProviderHystrix8001_App {
    public static void main(String[] args) {
        SpringApplication.run(DeptProviderHystrix8001_App.class,args);
    }
}
           
  • 修改DeptController用HystrixCommand報異常後如何處理一旦服務調用失敗并抛出錯誤資訊後,會自動調用@HystrixCommand标注好的fallBackMethod調用類中知道的方法
package com.blj.springcloud.controller;

import com.blj.springcloud.entities.Dept;
import com.blj.springcloud.service.DeptService;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
@RequestMapping("dept")
public class DeptController {
    @Autowired
    private DiscoveryClient discoveryClient;


    @Autowired
    private DeptService deptService;

   // @RequestMapping(value = "/add",produces = "application/json",method = RequestMethod.POST)
   @PostMapping("add")
    public Boolean addDept(@RequestBody  Dept dept){
        System.out.println("dept = " + dept);
       return deptService.addDept(dept);
    }

    @GetMapping(value = "/get/{deptno}")
    //-旦調用服務方法失敗并抛出了錯誤資訊後,會自動調用@HystrixCommand标注好的fallbackMethod調用類中的指定方法
    @HystrixCommand(fallbackMethod = "processHystrixGet")
    public Dept get(@PathVariable("deptno") Long deptno){
        Dept dept = deptService.findById(deptno);
        if (dept == null) {
            throw new RuntimeException("該ID"+deptno+"沒有對應資訊!");
        }
        return dept;
    }

    public Dept processHystrixGet(@PathVariable("deptno")Long deptno){
       return new Dept().setDeptno(deptno).setDname("該deptNo沒有對應的資訊").setDbSource("沒有這個資料庫");
    }

    @GetMapping(value = "/list")
    public List<Dept> list(){
        return deptService.findAll();
    }


}
           
  • 測試

3、服務降級

整體資源不夠了,忍痛将某些服務先關掉,待度過難關後再開啟。

資源的搶占和配置設定

所謂降級,一般是從整體負荷考慮,當某個服務熔斷後,伺服器将不再被調用,此時用戶端可以自己準備一個本地的fallback回調,傳回一個預設值,這樣做,雖然服務水準下降,好歹能用,比直接改掉要強。

服務降級是在用戶端(消費者)處理完成的,與服務端沒關系

1、修改springcloud-study-api子產品

  • 根據已有的com.blj.springcloud.service.DeptClientService接口,建立一個實作FallBackFactory接口的類。
package com.blj.springcloud.service;

import com.blj.springcloud.entities.Dept;
import feign.hystrix.FallbackFactory;
import org.springframework.stereotype.Component;
import java.util.List;
//@Component 不要忘記添加
//主業務與熔斷方法解耦
@Component
public class DeptClientServiceFallBackFactory implements FallbackFactory<DeptClientService> {
    @Override
    public DeptClientService create(Throwable throwable) {
        return new DeptClientService() {
            @Override
            public boolean add(Dept dept) {
                return false;
            }

            @Override
            public Dept get(Long deptno) {
                 return new Dept().setDeptno(deptno)
                        .setDname("該deptNo沒有對應的資訊,Consumer用戶端提供的降級資訊,此刻服務provider已經關閉")
                        .setDbSource("沒有這個資料庫");
                  }

            @Override
            public List list() {
                return null;
            }
        };
    }
}
           
  • 在DeptClientService中的FeignClient注解中添加FallBackfactory屬性值
package com.blj.springcloud.service;

import com.blj.springcloud.entities.Dept;
import org.springframework.cloud.netflix.feign.FeignClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import java.util.List;

//@FeignClient(value = "STUDY-SPRINGCLOUD-DEPT")
@FeignClient(value = "STUDY-SPRINGCLOUD-DEPT",fallbackFactory = DeptClientServiceFallBackFactory.class)
public interface DeptClientService {

    @RequestMapping(value = "/dept/add",method = RequestMethod.GET)
    public boolean add(Dept dept);

    @RequestMapping(value = "/dept/get/{deptno}",method = RequestMethod.GET)
    public Dept get(@PathVariable("deptno") Long deptno);

    @RequestMapping(value = "/dept/list",method = RequestMethod.GET)
    public List list();


}
           
  • springcloud-study-consumer-dept-feign修改yml
server:
  port: 80

feign:
  hystrix:
    enable: ture


eureka:
  client:
    service-url:
      defaultZone: eureka7001.com:7001/eureka ,http://eureka7004.com:7004/eureka ,http://eureka7003.com:7003/eureka
    register-with-eureka: false
           

4.HystrixDashboard

1、概述

除了隔離依賴服務的調用以外,Hystrix還提供了準實時的調用監控(HystrixDashboard),Hystrix會持續的記錄所有通過Hystrix發起的請求的執行資訊,并統計報表和圖形的形式展示給使用者,包括每秒執行多少次清酒,多少成功,多少失敗等。Netflix通過Hystrix-metrics-event-stream項目實作了對以上名額的監控。spring cloud 也提供了對Hystrix Dashboard的整合,對監控内容轉化成可視化的界面。

2、建構步驟

  • 構模組化塊項目springcloud-study-consumer-hystrix-dashboard
  • pom檔案
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>springcloud-study</artifactId>
        <groupId>com.blj</groupId>
        <version>1.0.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>springcloud-study-consumer-hystrix-dashboard</artifactId>

<dependencies>

    <dependency>
        <groupId>com.blj</groupId>
        <artifactId>springcloud-study-api</artifactId>
        <version>${project.version}</version>
    </dependency>
    <!--hystrix和dashboard依賴-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-hystrix</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-hystrix-dashboard</artifactId>
    </dependency>

    <!--熱部署 修改後立即生效-->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>springloaded</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-devtools</artifactId>
    </dependency>

</dependencies>


</project>
           
  • yml檔案
server:
  port: 9001
           
  • 主啟動類
package com.blj.springcloud;

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

@SpringBootApplication
@EnableHystrixDashboard
public class HystrixDashboardApp {
    public static void main(String[] args) {
        SpringApplication.run(HystrixDashboardApp.class,args);
    }
}
           
  • 所有provider微服務提供類(8001、8002、8002)都需要監控依賴配置
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
           
  • 測試:通路:http://localhost:9001/hystrix,(根據配置端口号),看到豪豬表示已經配置好了
Hystrix 斷路器

如何監控:

在dashboard界面中,填入需要監控的服務位址和端口号加 上/hystrix.stream和監測間隔即可進入監控。(如http://localhost:8001/hystrix.stream)

Hystrix 斷路器

監控分析

  • 七色:進入監控界面後會有其中顔色的數字,其含義可以對應右上角相同顔色的單詞表示的狀态,其值代表該狀态下觸發的次數
  • 一圈:圈的大小代表該服務的流量,圈越大流量越大
  • 一線:代表監控間隔中,服務被通路的頻率的折線圖

    通過觀察這些就可以在大量的執行個體中找出故障執行個體和高壓執行個體進行修複和維護。

    Hystrix 斷路器

繼續閱讀