SpringCloud hystrix断路器与局部降级全面介绍

目录
  • 服务降级
  • 一、Hystrix的服务使用前的问题
    • 1、ProductController 中方法异常和超时
    • 2、访问查看效果
    • 3、问题分析
  • 二、 商品服务 Hystrix的 局部降级
    • 1、降级配置
    • 2、回调(兜底降级)方法
    • 3、具体代码
    • 4、主启动类激活Hstrix
    • 5、进行测试
  • 三、 订单服务 Hystrix的 局部降级
    • 1、降级配置
    • 2、回调(兜底降级)方法
    • 3、具体代码
    • 4、将商品服务中的超时时间为正常
    • 5、主启动类激活Hstrix
    • 6、进行测试

服务降级

服务压力剧增的时候,根据当前的业务情况及流量对一些服务和页面有策略的降级,以此缓解服务器的压力,以保证核心任务的进行。同时保证部分甚至大分客户能得到正确的响应。也就是当前的请求处理不了或者出错了,给一个默认的返回。例如:双11降级产品评价等非核心功能,保证支持和订单的核心任务进行。

服务熔断

就是防止服务雪崩现象出现,是服务降级的一种特殊情况。

一、Hystrix的服务使用前的问题

1、ProductController 中方法异常和超时

在商品服务 ProductController 中的方法中增加异常和超时,ProductController 中方法修改如下:

package com.hwadee.springcloud.controller;
import com.hwadee.springcloud.entity.Product;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.math.BigDecimal;
@RestController
@RequestMapping("/product")
public class ProductController {
    //方便后面讲负载均衡,查看ip,此处获取配置中的端口号和ip
    @Value("${server.port}")
    private String port;
    @Value("${spring.cloud.client.ip-address}")
    private String ip;
    @RequestMapping("/buy/{id}")
    public Product findById(@PathVariable Long id) {
        Product product = new Product();
        product.setId(id);
        // 后面需要测试负载均衡,所以返回 ip 地址及端口号
        product.setName("当前访问商品服务地址:" + ip + ":" + port+"  "+"查询商品订单,订单号:"+id);
        product.setPrice(new BigDecimal(10000.0));
        System.out.println(product);
        //测试超时熔断
        try {
            Thread.sleep(5000);
            //测试并发熔断
            //Thread.sleep(500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return product;
    }
    @RequestMapping(value = "/delete/{id}")
    public Product deleteOrderById(@PathVariable Long id){
        Product product = new Product();
        product.setId(id);
        // 后面需要测试负载均衡,所以返回 ip 地址及端口号
        product.setName("当前访问商品服务地址:" + ip + ":" + port+"  "+"从购物车删除订单,订单号:"+id);
        product.setPrice(new BigDecimal(10000.0));
        System.out.println(product);
        //测试异常熔断
        System.out.println(10/0);
        return product;
    }
}

2、访问查看效果

访问http://localhost:9000/order/buy/1

访问http://localhost:9000/order/delete/1

订单服务中OrderController 中 调用商品服务 ProductController 中方法时,ProductController 中方法出现异常和超时,访问浏览器的异常结果和订单服务中的内部异常如下:

3、问题分析

在微服务架构中,我们将系统拆分成了一个个的服务单元,各单元应用间通过服务注册与订阅的方式互相依赖。由于每个单元都在不同的进程中运行,依赖通过远程调用的方式执行,这样就有可能因为网络原因或是依赖服务自身问题出现调用故障或延迟,而这些问题会直接导致调用方的对外服务也出现延迟,若此时调用方的请求不断增加,最后就会出现因等待出现故障的依赖方响应而形成任务积压,线程资源无法释放,最终导致自身服务的瘫痪,进一步甚至出现故障的蔓延最终导致整个系统的瘫痪。如果这样的架构存在如此严重的隐患,那么相较传统架构就更加的不稳定,如下图。

二、 商品服务 Hystrix的 局部降级

1、降级配置

注解 @HistrixCommand

在商品服务 ProductController 中的 findById( )和deleteOrderById( ) 方法上增加降级配置的注解 @HistrixCommand

—旦调用服务方法失败并抛出了超时或错误信息后,会自动调用@HystrixCommand标注好的fallbackMethod调用类中的指定方法。

在@HistrixCommand 指定超时或异常要回调的方法,同时可以指定配置参数,例如使用@HistrixCommand 中的属性commandProperties 指定默认超时时间,如:

fallbackMethod:指定回调方法是findByIdTimeout
commandProperties: 指定@HystrixProperty​​​ ​的默认值是默认超时时间是3s

@HystrixCommand(fallbackMethod = "findByIdTimeout", commandProperties = {
        @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "3000")
})

2、回调(兜底降级)方法

在商品服务ProductController 中增加回调方法findByIdTimeout( ) 和deleteOrderByIdException( ),当访问ProductController 中的 findById( )和deleteOrderById( ) 发生超时 或 异常时,会调用回调方法。

3、具体代码

降级配置 和回调(兜底降级)方法的具体代码如下:

import com.hwadee.springcloud.entity.Product;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.math.BigDecimal;
@RestController
@RequestMapping("/product")
public class ProductController {
    //方便后面讲负载均衡,查看ip,此处获取配置中的端口号和ip
    @Value("${server.port}")
    private String port;
    @Value("${spring.cloud.client.ip-address}")
    private String ip;
    @RequestMapping("/buy/{id}")
    @HystrixCommand(fallbackMethod = "findByIdTimeout", commandProperties = {
            @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "3000")
    })
    public Product findById(@PathVariable Long id) {
        Product product = new Product();
        product.setId(id);
        // 后面需要测试负载均衡,所以返回 ip 地址及端口号
        product.setName("当前访问商品服务地址:" + ip + ":" + port + "  " + "查询商品订单,订单号:" + id);
        product.setPrice(new BigDecimal(50000.0));
        System.out.println(product);
        //测试超时熔断
        try {
            Thread.sleep(5000);
            //测试并发熔断
            //Thread.sleep(500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return product;
    }
    @RequestMapping(value = "/delete/{id}")
    @HystrixCommand(fallbackMethod = "deleteOrderByIdException")
    public Product deleteOrderById(@PathVariable Long id) {
        Product product = new Product();
        product.setId(id);
        // 后面需要测试负载均衡,所以返回 ip 地址及端口号
        product.setName("当前访问商品服务地址:" + ip + ":" + port + "  " + "从购物车删除订单,订单号:" + id);
        product.setPrice(new BigDecimal(10000.0));
        System.out.println(product);
        //测试异常熔断
        System.out.println(10 / 0);
        return product;
    }
    public Product findByIdTimeout(Long id) {
        Product product = new Product();
        product.setId(id);
        product.setName("当前访问商品服务地址:" + ip + ":" + port + "  " + "访问 超时 进行降级服务");
        product.setPrice(new BigDecimal(10000.0));
        System.out.println(product);
        return product;
    }
    public Product deleteOrderByIdException(Long id) {
        Product product = new Product();
        product.setId(id);
        product.setName("当前访问商品服务地址:" + ip + ":" + port + "  " + "访问 异常 进行降级服务");
        product.setPrice(new BigDecimal(10000.0));
        System.out.println(product);
        return product;
    }
}

4、主启动类激活Hstrix

在商品服务的主启动类 ProductServerApplication 中使用注解@EnableCircuitBreaker 进行激活Hystrix,代码如下

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
@SpringBootApplication
@EnableEurekaClient// 启动 eureka 客户端
@EnableCircuitBreaker // 主启动类激活 Hystrix
public class ProductServerApplication {
    public static void main(String[] args) {
        SpringApplication.run(ProductServerApplication.class, args);
    }
}

5、进行测试

将商品服务中ProductController 和 ProductServerApplication复制到 其他所有 商品服务中,进行更新代码。

分别访问:http://localhost:9001/product/buy/1http://localhost:9001/product/delete/1 查看超时和异常服务降级。看浏览器和内部结果。

三、 订单服务 Hystrix的 局部降级

1、降级配置

注解 @HistrixCommand

在订单服务 OrderController 中的方法上增加降级配置的注解 @HistrixCommand

2、回调(兜底降级)方法

在订单服务 OrderController 定义 回调方法 buyTimeout( Long id) 、deleteOrderException( Long id),并设置超时服务,超时服务要比将商品服务ProductController 中的 findById( ) 超时时间短。例如:ProductController 中的 findById( ) 超时时间是 3s ,则订单服务 OrderController 定义 回调方法 buyTimeout( ) 设定的超时时间应是 <3s 。

3、具体代码

降级配置 和回调(兜底降级)方法的具体代码如下:

import com.hwadee.springcloud.entity.Product;
import com.hwadee.springcloud.service.IOrderFeignService;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/order")
public class OrderController {
    @Autowired
    IOrderFeignService orderFeignService;
    @RequestMapping("/buy/{id}")
    @HystrixCommand(fallbackMethod = "buyTimeout", commandProperties = {
            @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "1500")
    })
    public Product buy(@PathVariable Long id) {
        System.out.println("进入OrderController的buy方法, orderFeignService 准备调用远端接口 findById");
        Product product = orderFeignService.findOrderById(id);
        return product;
    }
    @RequestMapping(value = "/delete/{id}")
    @HystrixCommand(fallbackMethod = "deleteOrderException")
    public Product deleteOrderById(@PathVariable Long id) {
        System.out.println("进入OrderController的deleteOrderById方法, orderFeignService 准备调用远端接口deleteOrderById");
        Product product = orderFeignService.deleteOrderById(id);
        int i =10/0;
        return product;
    }
    public Product buyTimeout( Long id) {
        Product product = new Product();
        product.setId(id);
        product.setName("当前订单服务访问/order/buy/1 超时:"+id);
        return product;
    }
    public Product deleteOrderException( Long id) {
        Product product = orderFeignService.deleteOrderById(id);
        product.setName("当前订单服务访问/order/delete/1 10/0异常:"+id);
        return product;
    }
}

4、将商品服务中的超时时间为正常

将商品服务ProductController 中的 findById( ) 超时时间为正常,即程序超时时间是2s,熔断等待时间是3s,并且要比 订单服务 OrderController 定义 回调方法 buyTimeout( ) 中的熔断时间大,代码如下:

@HystrixCommand(fallbackMethod = "findByIdTimeout", commandProperties = {

// 正常超时时间是 3s 比OrderController 中定义的超时时间长。

@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "3000") }) public Product findById(@PathVariable Long id) { 。。。。。

// 超时时间 2s

Thread.sleep(2000); 。。。。。

return product;

}

完整代码如下:

import com.hwadee.springcloud.entity.Product;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.math.BigDecimal;
@RestController
@RequestMapping("/product")
public class ProductController {
    //方便后面讲负载均衡,查看ip,此处获取配置中的端口号和ip
    @Value("${server.port}")
    private String port;
    @Value("${spring.cloud.client.ip-address}")
    private String ip;
    @RequestMapping("/buy/{id}")
    @HystrixCommand(fallbackMethod = "findByIdTimeout", commandProperties = {
            @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "3000")
    })
    public Product findById(@PathVariable Long id) {
        Product product = new Product();
        product.setId(id);
        // 后面需要测试负载均衡,所以返回 ip 地址及端口号
        product.setName("当前访问商品服务地址:" + ip + ":" + port + "  " + "查询商品订单,订单号:" + id);
        product.setPrice(new BigDecimal(10000.0));
        System.out.println(product);
        //测试超时熔断
        try {
            Thread.sleep(5000);
            //测试并发熔断
            //Thread.sleep(500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return product;
    }
    @RequestMapping(value = "/delete/{id}")
    @HystrixCommand(fallbackMethod = "deleteOrderByIdException")
    public Product deleteOrderById(@PathVariable Long id) {
        Product product = new Product();
        product.setId(id);
        // 后面需要测试负载均衡,所以返回 ip 地址及端口号
        product.setName("当前访问商品服务地址:" + ip + ":" + port + "  " + "从购物车删除订单,订单号:" + id);
        product.setPrice(new BigDecimal(10000.0));
        System.out.println(product);
        //测试异常熔断
        System.out.println(10 / 0);
        return product;
    }
    public Product findByIdTimeout(Long id) {
        Product product = new Product();
        product.setId(id);
        product.setName("当前访问商品服务地址:" + ip + ":" + port + "  " + "访问 超时 进行降级服务");
        product.setPrice(new BigDecimal(10000.0));
        System.out.println(product);
        return product;
    }
    public Product deleteOrderByIdException(Long id) {
        Product product = new Product();
        product.setId(id);
        product.setName("当前访问商品服务地址:" + ip + ":" + port + "  " + "访问 异常 进行降级服务");
        product.setPrice(new BigDecimal(10000.0));
        System.out.println(product);
        return product;
    }
}

5、主启动类激活Hstrix

在订单服务的主启动类 OrderServerApplication 中使用注解@EnableCircuitBreaker 或 注解@EnableHystrix进行激活Hystrix,注意:@EnableHystrix包括了注解@EnableCircuitBreaker ,代码如下

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
@SpringBootApplication
@EnableEurekaClient// 启动 eureka 客户端
@EnableFeignClients  // 启动 feign
@EnableCircuitBreaker // 或 @EnableHystrix  启动 Hystrix
public class OrderServerApplication {
    public static void main(String[] args) {
        SpringApplication.run(OrderServerApplication.class, args);
    }
}

6、进行测试

分别访问:http://localhost:9000/order/buy/1http://localhost:9000/order/delete/1 查看超时和异常服务降级。

到此这篇关于SpringCloud hystrix断路器与服务降级全面介绍的文章就介绍到这了,更多相关SpringCloud hystrix断路器内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • SpringCloud断路器Hystrix原理及用法解析

    这篇文章主要介绍了SpringCloud断路器Hystrix原理及用法解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 在分布式环境中,许多服务依赖项中的一些必然会失败.Hystrix是一个库,通过添加延迟容忍和容错逻辑,帮助你控制这些分布式服务之间的交互.Hystrix通过隔离服务之间的访问点.停止级联失败和提供回退选项来实现这一点,所有这些都可以提高系统的整体弹性 两个比较重要的类 HystrixCommand HystrixObserv

  • SpringCloud中的断路器(Hystrix)和断路器监控(Dashboard)

    前言 本篇主要介绍的是SpringCloud中的断路器(Hystrix)和断路器指标看板(Dashboard)的相关使用知识. SpringCloud Hystrix Hystrix 介绍 Netflix创建了一个名为Hystrix的库,它实现了断路器模式.主要的目的是为了解决服务雪崩效应的一个组件,是保护服务高可用的最后一道防线. 开发准备 开发环境 •JDK:1.8 •SpringBoot:2.1.1.RELEASE •SpringCloud:Finchley 注:不一定非要用上述的版本,可

  • 详解SpringCloud微服务架构之Hystrix断路器

    一:什么是Hystrix 在分布式环境中,许多服务依赖项中的一些将不可避免地失败.Hystrix是一个库,通过添加延迟容差和容错逻辑来帮助您控制这些分布式服务之间的交互.Hystrix通过隔离服务之间的访问点,停止其间的级联故障以及提供回退选项,从而提高系统的整体弹性. Hystrix旨在执行以下操作 1:对通过第三方客户端库访问(通常通过网络)的依赖关系提供保护并控制延迟和故障. 2:隔离复杂分布式系统中的级联故障. 3:快速发现故障,尽快恢复. 4:回退,尽可能优雅地降级. 5:启用近实时监

  • SpringCloud hystrix断路器与局部降级全面介绍

    目录 服务降级 一.Hystrix的服务使用前的问题 1.ProductController 中方法异常和超时 2.访问查看效果 3.问题分析 二. 商品服务 Hystrix的 局部降级 1.降级配置 2.回调(兜底降级)方法 3.具体代码 4.主启动类激活Hstrix 5.进行测试 三. 订单服务 Hystrix的 局部降级 1.降级配置 2.回调(兜底降级)方法 3.具体代码 4.将商品服务中的超时时间为正常 5.主启动类激活Hstrix 6.进行测试 服务降级 服务压力剧增的时候,根据当前

  • SpringCloud Hystrix熔断器使用方法介绍

    目录 Hystrix(hi si ju ke si)概述 Hystix 主要功能 隔离 Hystrix 降级 Hystrix降级-服务提供方 初始化程序和Fiegn程序一致 Hystrix降级-服务消费方 provider与Fiegin一致 Hystrix 熔断 Hystrix 熔断监控 Turbine聚合监控 搭建监控模块 修改被监控模块 启动测试 Hystrix(hi si ju ke si)概述 Hystix 是 Netflix 开源的一个延迟和容错库,用于隔离访问远程服务.第三方库,防止

  • springcloud使用Hystrix进行微服务降级管理

    前言:目前我们的项目是微服务架构,基于dubbo框架,服务之间的调用是通过rpc调用的.刚开始没有任何问题,项目运行健康.良好.可是过了一段时间,线上总有人反应查询订单失败,等过了一段时间才能查到.这是怎么回事呢?打开后台的日志一看出现了一些RpcException和TimeOutException,原来是远程调用超时了,可能某个服务在请求的高发期访问数据库异常,IO阻塞,返回接口异常了.后来这个问题越来越频繁,如何解决这个棘手的问题呢? 一:Hystrix是什么? 1.1:基本解释 Hystr

  • SpringCloud hystrix服务降级学习笔记

    目录 一.Hystrix简介 1.Hystrix是什么 2.Hystrix能干什么 二.服务熔断 1.服务熔断简介 2.配置pom.xml 3.配置application.yaml 4.修改Controller 5.修改启动类 6.效果图 三.服务降级 1.什么是服务降级 2.DeptClientFailBackFactory类 3.添加注解 4.修改application.yaml 5.效果图 四.DashBorder 1.新建一个module 2.pom.xml配置 3.配置applicat

  • SpringCloud Hystrix的使用

    简介 在分布式系统中,服务与服务之间依赖错综复杂,一种不可避免的情况就是某些服务将会出现失败.Hystrix是一个库,它提供了服务与服务之间的容错功能,主要体现在延迟容错和容错,从而做到控制分布式系统中的联动故障.Hystrix通过隔离服务的访问点,阻止联动故障,并提供故障的解决方案,从而提高了这个分布式系统的弹性. 面对的问题: 一个应用一般会依赖多个服务,每个服务由于网络不可靠,机房的不可靠等等不稳定的因素,总会导致服务的故障,如果我们不对这些故障做处理,就会进而导致整个系统的不可用. 服务

  • spring cloud Hystrix断路器的使用(熔断器)

    1.Hystrix客户端 Netflix已经创建了一个名为Hystrix的库,实现了断路器的模式.在microservice架构通常有多个层的服务调用. 低水平的服务的服务失败会导致级联故障一直给到用户.当调用一个特定的服务达到一定阈值(默认5秒失败20次),打开断路器.在错误的情况下和一个开启的断路回滚应可以由开发人员提供. 有一个断路器阻止级联失败并且允许关闭服务一段时间进行愈合.回滚会被其他hystrix保护调用,静态数据或健全的空值. 代码如下: @SpringBootApplicati

  • Springcloud Config配置中心使用与相关介绍

    目录 Springcloud Config 什么是springcloud Config config服务端的配置使用 config客户端的相关问题 config客户端的配置使用 动态刷新问题 config客户端的遗留问题 Springcloud Config 什么是springcloud Config   简单来说,Spring Cloud Config就是我们通常意义上的配置中心,也就是微服务项目中,每一个微服务都需要配置相应的配置,如果不同服务的配置文件有相同的配置,如果这些相同配置需要修改

  • SpringCloud Gateway HttpWebHandlerAdapter链路调用请求流程介绍

    目录 前言 web容器 前言 上一节我们说到从HttpWebHandlerAdapter的handle方法说起到DispatcherHandler的调用流程 那么HttpWebHandlerAdapter的handle方法是从哪里来调用的呢? 我们可以找下看哪些类使用了HttpHandler 通过这些类的名字,我们可以发现,HttpHandler 往下就是具体的 Web 容器了,也就是说有具体的 Web 容器来接受请求,然后通过调用 HttpWebHandlerAdapter#handler 来

  • 详解Spring Cloud Hystrix断路器实现容错和降级

    简介 Spring cloud提供了Hystrix容错库用以在服务不可用时,对配置了断路器的方法实行降级策略,临时调用备用方法.这篇文章将创建一个产品微服务,注册到eureka服务注册中心,然后我们使用web客户端访问/products API来获取产品列表,当产品服务故障时,则调用本地备用方法,以降级但正常提供服务. 基础环境 JDK 1.8 Maven 3.3.9 IntelliJ 2018.1 Git:项目源码 添加产品服务 在intelliJ中创建一个新的maven项目,使用如下配置 g

随机推荐