springCloud四:熔斷器ribbon--Hystrix

注:前文概念部分摘抄自博客園  純潔的微笑java

熔斷器

雪崩效應

在微服務架構中一般會有多個服務層調用,基礎服務的故障可能會致使級聯故障,進而形成整個系統不可用的狀況,這種現象被稱爲服務雪崩效應。服務雪崩效應是一種因「服務提供者」的不可用致使「服務消費者」的不可用,並將不可用逐漸放大的過程。web

若是下圖所示:A做爲服務提供者,B爲A的服務消費者,C和D是B的服務消費者。A不可用引發了B的不可用,並將不可用像滾雪球同樣放大到C和D時,雪崩效應就造成了。spring

 

 

熔斷器(CircuitBreaker)

熔斷器的原理很簡單,如同電力過載保護器。它能夠實現快速失敗,若是它在一段時間內偵測到許多相似的錯誤,會強迫其之後的多個調用快速失敗,再也不訪問遠程服務器,從而防止應用程序不斷地嘗試執行可能會失敗的操做,使得應用程序繼續執行而不用等待修正錯誤,或者浪費CPU時間去等到長時間的超時產生。熔斷器也可使應用程序可以診斷錯誤是否已經修正,若是已經修正,應用程序會再次嘗試調用操做。apache

熔斷器模式就像是那些容易致使錯誤的操做的一種代理。這種代理可以記錄最近調用發生錯誤的次數,而後決定使用容許操做繼續,或者當即返回錯誤。
熔斷器開關相互轉換的邏輯以下圖:後端

 

熔斷器就是保護服務高可用的最後一道防線。緩存

 

Hystrix特性

1.斷路器機制服務器

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

2.Fallbackapp

Fallback至關因而降級操做. 對於查詢操做, 咱們能夠實現一個fallback方法, 當請求後端服務出現異常的時候, 可使用fallback方法返回的值. fallback方法的返回值通常是設置的默認值或者來自緩存.maven

3.資源隔離

在Hystrix中, 主要經過線程池來實現資源隔離. 一般在使用的時候咱們會根據調用的遠程服務劃分出多個線程池. 例如調用產品服務的Command放入A線程池, 調用帳戶服務的Command放入B線程池. 這樣作的主要優勢是運行環境被隔離開了. 這樣就算調用服務的代碼存在bug或者因爲其餘緣由致使本身所在線程池被耗盡時, 不會對系統的其餘服務形成影響. 可是帶來的代價就是維護多個線程池會對系統帶來額外的性能開銷. 若是是對性能有嚴格要求並且確信本身調用服務的客戶端代碼不會出問題的話, 可使用Hystrix的信號模式(Semaphores)來隔離資源.

 

ribbon-- Hystrix

由於熔斷只是做用在服務調用這一端,所以咱們根據上一篇的示例代碼只須要改動smicroservice-consumer-movie-ribbon-with-hystrix項目相關代碼就能夠。

 

pom.xml文件

<?xml version="1.0"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.itmuch.cloud</groupId>
<artifactId>microservice-spring-cloud</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<groupId>com.itmuch.cloud</groupId>
<artifactId>microservice-consumer-movie-ribbon-with-hystrix</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>
</dependencies>
</project>

配置文件application.yml

spring:
application:
name: microservice-consumer-movie-ribbon-with-hystrix
server:
port: 8010
eureka:
client:
healthcheck:
enabled: true
serviceUrl:
defaultZone: http://user:password123@localhost:8761/eureka
instance:
prefer-ip-address: true
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds: 5000

============================================================================

啓動類

package com.itmuch.cloud;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;
/**
* 斷路器第一天
* @author z
*
*/
@SpringBootApplication
@EnableEurekaClient
@EnableCircuitBreaker //斷路器註解
public class ConsumerMovieRibbonApplication {

@Bean
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
}

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

========================================================================

Controller:在調用的方法上加註解 @HystrixCommand(fallbackMethod = "findByIdFallback")

package com.itmuch.cloud.controller;

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 org.springframework.web.client.RestTemplate;

import com.itmuch.cloud.entity.User;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;

@RestController
public class MovieController {
@Autowired
private RestTemplate restTemplate;

@GetMapping("/movie/{id}")
@HystrixCommand(fallbackMethod = "findByIdFallback")
public User findById(@PathVariable Long id) {
return this.restTemplate.getForObject("http://microservice-provider-user/simple/" + id, User.class);
}
/**
*此方法的方法發回值類型要與findById返回值類型一致,參數要一致
* @param id
* @return
*/
public User findByIdFallback(Long id) {
User user = new User();
user.setId(0L);
return user;
}
}

就這樣一個斷路器就完成了此時咱們啓動註冊中心與smicroservice-consumer-movie-ribbon-with-hystrix 與user微服務

 

此時咱們停掉user微服務,訪問  localhost:8081/movie/1  此時斷路器就會生效並進入對應的Fallback 方法。

 

總結:

ribbon 上添加 Hystrix(熔斷器)

1:須要加入Hystrix依賴包 

<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>

2:啓動類加Hystrix註解

@EnableCircuitBreaker //斷路器註解

3:所調用的方法上加註解

@GetMapping("/movie/{id}")
@HystrixCommand(fallbackMethod = "findByIdFallback")
public User findById(@PathVariable Long id) {
return this.restTemplate.getForObject("http://microservice-provider-user/simple/" + id, User.class);
}

而且findByIdFallback方法中的參數與返回值類型要與調用方法上的一致

4:關於啓動直接進入findByIdFallback方法問題

由於Hystrix默認調用超時時間爲1秒,此時咱們須要在配置文件中設置一下超時時間

hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds: 5000

相關文章
相關標籤/搜索