什麼是Hystrix?hystrix能幹什麼呢?附帶案列詳細解釋

什麼是Hystrix
hystrix是一個處理分佈式系統的延遲和容錯的開源庫,在分佈式系統裏,許多依賴不可避免的會調用失敗,比如超時,異常,hystrix能夠保證在一個依賴問題的情況選,不會導致整體服務的失敗,避免級聯故障,一提高分佈式系統的彈性.
  "斷路器"本身是一種開關裝置,當某個服務單元發生故障後,通過斷路器的故障監控(類似熔斷保險絲),向調用方法返回一個服務預期的,可處理的備選響應,而不是長時間的等待或者拋出調用方法無法處理的異常了.這樣就可以保證了服務調用方的線程不會被長時間,不必要的佔用,從而避免故障在分佈式系統中的蔓延,乃至雪崩.
作用:服務降級,服務熔斷,服務限流,接近實時的監控.
在這裏插入圖片描述上圖所示:一個程序進來,需要連續調用A,G,E2,E3這四個服務,如果說這四個服務正常運行,則沒啥問題,但是如果E2出現了問題,沒有任何解決措施的情況下,會導致在運行完G時出現等待,延遲,異常等,進而該程序無法進行下去,這個時候我們就需要給服務備份,可以考慮異步等方法,給予用戶提示,服務崩潰,但後面的服務能繼續運行.解決措施就是我們這裏考慮的Hystrix,這也是一個最經典的應用
服務熔斷:
熔斷機制是對應雪崩效應的一種微服務鏈路保護機制.
在這裏插入圖片描述
現在進行一項實例測試:
按照之前的項目:如果要加上Hystrix我們可以增加一個module:
在這裏插入圖片描述代碼:

package com.qiu.springcloud.controller;

import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.qiu.springcloud.pojo.Dept;
import com.qiu.springcloud.service.DeptService;
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.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

//提供restfull服務
@RestController
public class DeptController {
    @Autowired
    private DeptService deptService;
    @HystrixCommand(fallbackMethod = "hystrixGet")
    @GetMapping("/dept/get/{deptNo}")
    public Dept get(@PathVariable("deptNo") Long deptNo){
        Dept dept = deptService.queryById(deptNo);
        if (dept==null){
            throw new RuntimeException("id=>"+deptNo+".不存在該用戶,或者信息未找到~");
        }
        return dept;
    }
    //備選方案
    public Dept hystrixGet(@PathVariable("deptNo") Long deptNo){
        return new Dept()
                .setDeptno(deptNo)
                .setDname("id=>"+deptNo+".不存在該用戶,或者信息未找到~")
                .setDb_sources("no this database in mysql");
    }




}

其他代碼與前module:8001類似.需要修改的代碼:
yaml文件:
在這裏插入圖片描述第二步:在controller的方法上添加註解
在這裏插入圖片描述表示如果服務出錯調取備用方法
第三步:
在這裏插入圖片描述主啓動類上添加對熔斷器的支持,注意這裏不是開啓
@EnableHystrix的註解

然後依次啓動服務:
在網頁中我們可以看到:
這是正常訪問的結果:因爲數據庫中有1-6號的deptno
在這裏插入圖片描述如果訪問了數據庫中沒有的
在這裏插入圖片描述則會調用備用的方法.這就是服務熔斷的小案列體現.
服務降級
在這裏插入圖片描述看上圖:假設有三個服務器分別爲A,B,C.這些箭頭是客戶端,它們要去請求服務端的數據.這個時候可能由於某個時間段A服務器的訪問量高,出現資源不過的情況,所以我們可以使用服務降級的策略,將C服務器關閉,釋放C服務器上的資源加在A服務器上,進而使得用戶能夠正常訪問.但是這個時候由於C服務器關閉了,這樣會導致訪問C服務器的人就不能正常運行.所以說我們要提示正在訪問C服務器的人,從而達到高可用的目的.
同樣解釋服務降級我麼可以用一個小案例
依然是上述那個案例.
首先我們需要創建一個類:DeptClientServiceFallbackFactory.這裏用於提示訪問C服務器的人.該服務已經降級.

package com.qiu.springcloud.service;

import com.qiu.springcloud.pojo.Dept;
import feign.hystrix.FallbackFactory;
import org.springframework.stereotype.Component;

import java.util.List;

@Component
public class DeptClientServiceFallbackFactory implements FallbackFactory {
    public DeptClientService create(Throwable throwable) {
        return new DeptClientService() {
            public Dept queryById(Long deptNo) {
                return new Dept()
                        .setDeptno(deptNo)
                        .setDname("id"+deptNo+"沒有對用的信息,客戶端提供了降級的信息,這個服務已經被關閉")
                        .setDb_sources("no data");
            }

            public List<Dept> queryAll() {
                return null;
            }

            public boolean addDept(Dept dept) {
                return false;
            }
        };
    }
}

我們需要實體層添加註解.在前面博客中用到了Feign,同樣這裏也適用
在這裏插入圖片描述.通過查看源碼我們可以得知
在這裏插入圖片描述源碼中Frign註解中提供了fallbackFactory方法,所以
我們可以在註解裏面添加fallbackFactory = DeptClientServiceFallbackFactory.class 這樣可以使service與DeptClientServiceFallbackFactory進行綁定.
同樣不要忘了需要在feign80的配置文件中開啓feign-hystrix
在這裏插入圖片描述上訴操作完成之後我們開始運行.開啓7001,7002,7003註冊中心,然後開啓一個8001用來提供數據,進而開啓feign80端口.然後在網站中查詢.當我們把服務8001斷開時,網站能及時通信客戶端.
在這裏插入圖片描述這樣就簡單的實現了服務降級

服務熔斷:服務端,某個服務超時,引起熔斷~ 類似於保險絲

服務降級:客戶端從整體的網站請求負載考慮,當某個服務熔斷或者關閉之後,服務將不再調用,此時我們可以準備一個FallbackFactory,返回一個默認的值(缺省值),缺點:整體的服務水平下降了.好歹能用,總比掛了強

最後一個我們來看下Hystrix的DashBoard監控
SpringCloud對Hystrix Dashboard進行了整合,可以對通過Hystrix發起的請求進行準實時統計,並以報表和圖形的形式展示給用戶(包括每秒執行多少次請求成功和失敗等.
首先我們先把案例所需的關鍵代碼附上
第一步開啓eureka端口7001.爲了簡要說明,我們這邊就開一個即可,

package com.qiu.springcloud;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;

@SpringBootApplication
@EnableEurekaServer //服務端的啓動類,可以接受別人註冊進來
public class EurekaServer_7001 {
    public static void main(String[] args) {
        SpringApplication.run(EurekaServer_7001.class,args);
    }
}

第二步就是新建一個modules:springcloud-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</artifactId>
        <groupId>com.qiu</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>springcloud-consumer-hystrix-dashboard</artifactId>
    <!--    實體類+web-->
    <dependencies>

        <!--Hystrix依賴~-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-hystrix</artifactId>
            <version>1.4.6.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-hystrix-dashboard</artifactId>
            <version>1.4.6.RELEASE</version>
        </dependency>
        <!--Ribbon-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-ribbon</artifactId>
            <version>1.4.6.RELEASE</version>
        </dependency>
        <!--erueka-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka</artifactId>
            <version>1.4.6.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>com.qiu</groupId>
            <artifactId>springcloud-api</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
        </dependency>
    </dependencies>
</project>

yaml配置:

server:
  port: 9001

主啓動類中需要加上相關的註解

package com.qiu.springcloud;


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

@SpringBootApplication
@EnableHystrixDashboard
public class DeptConsumerDashboard_9001  {
    public static void main(String[] args) {
        SpringApplication.run(DeptConsumerDashboard_9001.class,args);
    }
}

然後就是我們的8001端口.
在這個服務提供者中我們需要注意幾點
第一:
確認pom文件中有有三個依賴:

 <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-hystrix</artifactId>
            <version>1.4.6.RELEASE</version>
        </dependency>
 <!--    添加監控信息,完善監控信息   -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <!--    配置eureka-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka</artifactId>
            <version>1.4.6.RELEASE</version>
        </dependency>

第二:確保主啓動類的註解完整:


import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.metrics.eventstream.HystrixMetricsStreamServlet;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.context.annotation.Bean;

//啓動類
@SpringBootApplication
@EnableEurekaClient //自動的在服務啓動後自動註冊到eureka中
@EnableDiscoveryClient//服務發現
@EnableCircuitBreaker //添加對熔斷的支持
public class DeptProviderHystrix_8001 {
    public static void main(String[] args) {
        SpringApplication.run(DeptProviderHystrix_8001.class,args);
    }

    //增加一個servlet
    @Bean
    public ServletRegistrationBean getServlet() {
        HystrixMetricsStreamServlet streamServlet = new HystrixMetricsStreamServlet();
        ServletRegistrationBean registrationBean = new ServletRegistrationBean(streamServlet);
        registrationBean.setLoadOnStartup(1);
        registrationBean.addUrlMappings("/actuator/hystrix.stream");
        registrationBean.setName("HystrixMetricsStreamServlet");
        return registrationBean;
    }
}

第三:注意路徑:/actuator/hystrix.stream
完整路徑爲http://localhost:8001//actuator/hystrix.stream
在網頁中打開這個網址,將會得到一串字符,這是一些ping記錄.
然後我們打開localhost:9001/hystrix
在這裏插入圖片描述
輸入網址http://localhost:8001//actuator/hystrix.stream進去後得到:
在這裏插入圖片描述關於該頁面詳細介紹:
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章