Hystrix(服務熔斷,服務降級)


一、Hystrix

1、服務雪崩

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

2、Hystrix

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

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

二、服務熔斷

        熔斷機制是應對雪崩效應的一種微服務鏈路保護機制,

        當扇出鏈路的某個微服務不可用或者響應時間太長時,會進行服務的降級,進而熔斷該節點微服務的調用,快速返回”錯誤”的響應信息。當檢測到該節點微服務響應正常后恢復調用鏈路,在SpringCloud框架機制通過Hystrix實現,Hystrix會監控微服務見調用的狀況,當失敗的調用到一個閾值,缺省是5秒內20次調用失敗就會啟動熔斷機制,熔斷機制的注解是@HystrixCommand

創建一個工程,命名為:DeptProvider8001_Hystrix_App

1、增加pom.xml中的依賴包

<?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>microservicecloud</artifactId>
        <groupId>com.yufeng.springcloud</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>microservicecloud-provider-dept-hystrix-8001</artifactId>

    <dependencies>
        <!-- hystrix -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-hystrix</artifactId>
        </dependency>
        <!-- 將微服務provider側注冊進eureka -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka</artifactId>
        </dependency>
        <!-- 引入自己定義的api通用包,可以使用Dept部門Entity -->
        <dependency>
            <groupId>com.yufeng.springcloud</groupId>
            <artifactId>microservicecloud-api</artifactId>
            <version>${project.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-config</artifactId>
        </dependency>

        <!-- actuator監控信息完善 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
        </dependency>
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-core</artifactId>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
        </dependency>
    </dependencies>
</project>

2、yml文件修改,修改服務名稱instance-id:為自己的微服務名稱即可

server:
  port: 8001

mybatis:
  config-location: classpath:mybatis/mybatis.cfg.xml        # mybatis配置文件所在路徑
  type-aliases-package: com.yufeng.springcloud.entities    # 所有Entity別名類所在包
  mapper-locations:
  - classpath:mybatis/mapper/**/*.xml                       # mapper映射文件

spring:
   application:
    name: microservicecloud-dept
   datasource:
    type: com.alibaba.druid.pool.DruidDataSource            # 當前數據源操作類型
    driver-class-name: org.gjt.mm.mysql.Driver              # mysql驅動包
    url: jdbc:mysql://192.168.172.20:3306/cloudDB01              # 數據庫名稱
    username: root
    password: root
    dbcp2:
      min-idle: 5                                           # 數據庫連接池的最小維持連接數
      initial-size: 5                                       # 初始化連接數
      max-total: 5                                          # 最大連接數
      max-wait-millis: 200                                  # 等待連接獲取的最大超時時間


eureka:
  client:  # 客戶端注冊進eureka內
    service-url:
      defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/
  instance:
    instance-id: provider-hystrix-dept-8001
    prefer-ip-address: true  # 訪問路徑可以顯示IP

info:
  app.name: yufeng-microservicecloud
  company.name: www.yufeng.com
  build.artifactId: $project.artifactId$
  build.version: $project.version$

 

3、增加熔斷機制(@HystrixCommand

@RestController public class DeptController { @Autowired private DeptService service; @RequestMapping(value = "/dept/add", method = RequestMethod.POST) public boolean add(@RequestBody Dept dept) { return service.add(dept); } @RequestMapping(value = "/dept/get/{id}", method = RequestMethod.GET)
//一旦調用服務方法失敗拋出“錯誤信息后,胡自動范湖用@HystrixCommand標注好的fallbackMethod調用類中的指定方法” @HystrixCommand(fallbackMethod
= "processHystrixGet") public Dept get(@PathVariable("id") Long id) { Dept dept = service.get(id); //模擬異常 if(null == dept) { throw new RuntimeException("該id的信息不存在! id=" + id); } return service.get(id); } public Dept processHystrixGet(@PathVariable("id") Long id) { return new Dept().setDname("id沒有對應的信息, null -- @HystrixCommand, id=" + id) .setDb_source("no this database in MySQL."); } }

4、主啟動類添加注解 @EnableCircuitBreaker

添加此注解告訴主啟動類對Hystrix的支持

@SpringBootApplication @EnableEurekaClient //本服務啟動后自動注冊到eureka中
@EnableCircuitBreaker  //對hystrixR熔斷機制的支持
public class DeptProvider8001_Hystrix_App { public static void main(String[] args) { SpringApplication.run(DeptProvider8001_Hystrix_App.class, args); } }

5、測試:

(1)啟動 3個eureka服務:EurekaServer7001、EurekaServer7002、EurekaServer7003;

(2)啟動 DeptProvider8001_Hystrix_App 服務

(3)最后啟動DeptConsumer80_App 服務。

(4)測試地址:

http://localhost/consumer/dept/get/2

http://localhost/consumer/dept/get/112

 三、服務降級

服務降級的處理是在客戶端完成的,與服務端沒有關系。

整體資源快不夠用了,忍痛將某些服務先關掉,待度過難關,再回來開啟。

所謂降級,就是一般是從整體符合考慮,就是當某個服務熔斷之后,服務器將不再被調用,此刻客戶端可以自己准備一個本地的fallback回調,返回一個缺省值,這樣做,雖然服務水平下降,但好歹可用,比直接掛掉要強。

1、修改消費者服務接口的提供者項目(microservicecloud-api),讓service接口實現一個FallbackFactory接口類DeptClientServiceFallbackFactory(千萬記得增加 @Component  注解);

注意:直接在接口定義的熔斷機制中進行服務熔斷,之前在controller上的@HystrixCommand(fallbackMethod=”methodName”)將棄用

 

import com.yufeng.springcloud.entities.Dept; import feign.hystrix.FallbackFactory; import org.springframework.stereotype.Component; import java.util.List;  @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 id) { Dept dept = new Dept(); dept.setDeptno(id); dept.setDname("該ID:" + id + "沒有對應的信息,Consumer客戶端提供的信息,此服務Provider已關閉"); dept.setDb_source("no this database in mysql"); return dept; } @Override public List<Dept> list() { return null; } }; } }

2、修改提供服務的service熔斷處理的機制

此處是在公共的service對某個service的方法訪問出現異常后進行統一的fallback處理,即在 DeptClientService接口在注解@FeignClient 中添加 fallbackFactory 屬性值,該屬性賦值為實現FallbcakFactory接口的異常處理類

import com.yufeng.springcloud.entities.Dept; import org.springframework.cloud.netflix.feign.FeignClient; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import java.util.List; @FeignClient(value = "microservicecloud-dept", fallbackFactory = DeptClientServiceFallbackFactory.class) public interface DeptClientService { @RequestMapping(value = "/dept/add", method = RequestMethod.POST) public boolean add(@RequestBody Dept dept); @RequestMapping(value = "/dept/get/{id}", method = RequestMethod.GET) public Dept get(@PathVariable("id") Long id); @RequestMapping(value = "/dept/get/list", method = RequestMethod.GET) public List<Dept> list(); }

3、在消費者工程(microservicecloud-consumer-dept-feign的yml文件增加如下內容,開啟feign中的hystrix

feign: hystrix: enabled: true

 

4、將 microservicecloud-api 工程重新打包,執行: mvn clean install

5、測試

(1)啟動3個 eureka 服務;

(2)啟動 microservicecloud-provider-dept-8001 服務;

(3)啟動 microservicecloud-consumer-dept-feign 服務;

(4)在瀏覽器中訪問:http://localhost/consumer/dept/get/1

(5)將 microservicecloud-provider-dept-8001 服務關閉,瀏覽器訪問:http://localhost/consumer/dept/get/1

 


免責聲明!

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



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