SpringCloud無廢話入門04:Hystrix熔斷器及監控


1.斷路器(Circuit Breaker)模式

        在上文中,我們人為停掉了一個provider,在實際的生產環境中,因為意外某個服務down掉,甚至某一層服務down掉也是會是有發生的。一旦發生這種情況,我們需要將損失減少到最低限度。

        那怎么減少損失。在電力系統中,如果某個電器發生過載等問題,該段電路的繼電器中的保險絲就會熔斷。在分布式系統中,我們也可以設計這樣的模式,並為它賦有專有名詞:斷路器(Circuit Breaker)模式。

        其基本模式在Martin Fowler的一篇文章中進行過專有描述,其大概的架構圖如下:

        它描述了兩個狀態:close、open,以及一個動作:trip,

        close狀態下, client通過熔斷器向supplier發起的服務請求, supplier的返回值經過熔斷器返回client。

        open狀態下,c client通過熔斷器向supplier發起的服務請求,熔斷器直接返回值給client, client和supplier之間被隔斷。

        Trip動作: 如果在close狀態下, supplier持續超時報錯, 熔斷器就進行trip,然后熔斷器將狀態從close進入open。

        除了基本模式,Martin Fowler還描述了一種擴展模式。即熔斷器定期探測supplier的服務的狀態, 一旦服務恢復, 就將狀態設置回close,並且熔斷器進行重試時的狀態為half-open狀態。

        對於熔斷器模式,不再詳細展開。接下來我們看看在SpringCloud的系統中,熔斷器是怎么提供的。

2.Hystrix熔斷與服務降級

        SpringCloud Netflix實現的熔斷器叫Hystrix。我們首先看看微服務架構下, 瀏覽器如何訪問后台服務,

        然后,服務異常情況下,Hystrix通過提供Fallback進行了熔斷的保護,

        Hystrix設定的熔斷閾值是:5秒之內發生20次調用失敗,然后熔斷器就會被處於open狀態, 在熔斷狀態下,服務不再被調用, Hystrix提供一個Fallback回調。當然,這個回調可以由我們實現。

        Fallback是一種降級操作,這種行為我們定義為:服務降級。 

3.實現

        首先,在服務接口的聲明中,加入FeignClient注解的fallback屬性,

package com.zuikc;

import org.springframework.cloud.openfeign.FeignClient;

import org.springframework.web.bind.annotation.RequestMapping;

@FeignClient(value = "hello-service",fallback = FeignFallBack.class)

public interface HelloService {

    //服務中方法的映射路徑

    @RequestMapping("/hello")

    String hello();

}

        注意,假設這里我們沒有使用FeignClient注解,而是原先那種url方式來啟動LB的話,那么,那么就需要在具體的service中直接使用注解:@HystrixCommand(fallbackMethod = "helloFallBack"),來實現熔斷和服務降級。helloFallBack可以是具體服務類中的一個指定的方法。

        接下來,然后接着說FeignClient,實現該FeignFallBack類,

package com.zuikc;

import org.springframework.stereotype.Component;

/**

 * @ClassName FeignFallBack

 * @Description 我們提供咨詢和培訓服務,關於本文有任何困惑,請關注並聯系“碼農星球”

 * @Author 碼農星球

 **/

@Component

public class FeignFallBack implements HelloService {

    //實現的方法是服務調用的降級方法

    @Override

    public String hello() {

        return "error";

    }

}

        這個類實現了HelloService。如果provider調用失敗,就會執行該類的實現。

        最后,還得配置,

server:

  port: 9291

spring:

  application:

    name: Ribbon-Consumer

eureka:

  client:

    service-url:

      defaultZone: http://localhost:9091/eureka/

#providers這個是自己命名的,ribbon,listOfServer這兩個是規定的

providers:

  ribbon:

    listOfServers: http://localhost:9191/eureka,http://localhost:9192/eureka

feign:

  hystrix:

    enabled: true

        粗體部分就是新加的配置。Feign默認禁用熔斷器,所以我們需要配置為enabled。

        經過以上功能的改進后,停止provider吧,看看結果是什么呢?

4.監控

        SpringCloud做的比dubbo好的一點就是其監控非常的明了。我們可以用hystrix的監控方便的看到熔斷器的數據指標。

        要想監控這些數據,我們還得繼續改造我們的項目。

        首先,在provider的pom中加入依賴:

        <dependency>

            <groupId>org.springframework.boot</groupId>

            <artifactId>spring-boot-actuator</artifactId>

        </dependency>

        其次,在我們ribbon項目中,加入依賴:

        <dependency>

            <groupId>com.netflix.hystrix</groupId>

            <artifactId>hystrix-javanica</artifactId>

            <version>RELEASE</version>

        </dependency>

        <dependency>

            <groupId>org.springframework.cloud</groupId>

            <artifactId>spring-cloud-netflix-hystrix-dashboard</artifactId>

        </dependency>

        第一個依賴表示我們得有監控,第二個依賴表示我們得有一個儀表盤。

        接着,讓我們在ribbon的啟動類中加入一個servlet,如下:

package com.zuikc;

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.client.loadbalancer.LoadBalanced;

import org.springframework.cloud.netflix.hystrix.dashboard.EnableHystrixDashboard;

import org.springframework.cloud.openfeign.EnableFeignClients;

import org.springframework.context.annotation.Bean;

import org.springframework.web.client.RestTemplate;

/**

 * @ClassName ServiceRibbonApplication

 * @Description 我們提供咨詢和培訓服務,關於本文有任何困惑,請關注並聯系“碼農星球”

 * @Author 碼農星球

 **/

@SpringBootApplication

@EnableDiscoveryClient

@EnableFeignClients

@EnableCircuitBreaker

@EnableHystrixDashboard

public class ServiceRibbonApplication {

    public static void main(String[] args) {

        SpringApplication.run(ServiceRibbonApplication.class, args);

    }

    @Bean

    @LoadBalanced

    RestTemplate restTemplate() {

        return new RestTemplate();

    }

    @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;

    }

}

        在這個啟動類中,除了這個servlet要注冊之外,就是加入

        @EnableCircuitBreaker

        @EnableHystrixDashboard

        這兩個注解了。注意,由於hystrix默認就是支持熔斷器的,所以@EnableCircuitBreaker注解之前我們並沒有加。但是,這里要使用監控了,就必須要加入這個注解了。

        以上都操作完畢。來打開:http://localhost:9291/hystrix

        然后在出來的如下界面中,首先填入servlet的地址,其次點擊下面的monitor按鈕,

        最終進入到如下這個監控儀表盤界面。每一次對provider的調用,都會清清楚楚被儀表盤呈現出來。

        Ok。本章告一段落。

        感謝關注“碼農星球”。本文版權屬於“碼農星球”。我們提供咨詢和培訓服務,關於本文有任何困惑,請關注並聯系我們。

本文的參考1:

https://martinfowler.com/bliki/CircuitBreaker.html

本文的參考2:

http://cloud.spring.io/spring-cloud-netflix/multi/multi__circuit_breaker_hystrix_clients.html


免責聲明!

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



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