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

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

一:Hystrix是什么?

1.1:基本解释

Hystrix最开始由Netflix(看过美剧的都知道,它是一个美剧影视制作的巨头公司)开源的,后来由Spring Cloud Hystrix基于这款框架实现了断路器、线程隔离等一系列服务保护功能,该框架的目标在于通过控制访问远程系统、服务和第三方库的节点,从而延迟和故障提供更强大的容错能力。hystrix具备服务降级、服务熔断、线程和信号隔离、请求缓存、请求合并以及服务监控等强大功能。起到了微服务的保护机制,防止某个单元出现故障.从而引起依赖关系引发故障的蔓延,最终导致整个系统的瘫痪。

1.2:断路器的概念

断路器本身是一个开关装置,用在电路上保护线路过载,当线路中有电器发生短路的时候。“断路器”能够及时切断故障,防止发生过载、发热甚至起火等严重后果。当分布式架构中,断路器模式起到的作用也是类似的。当某个服务发生故障的时候,通过断路器的故障监控向调用方返回一个错误响应,而不是长时间的线程挂机,无限等待。这样就不会使线程因故障服务被长时间占用不释放,避免了故障在分布式系统中的蔓延。如下图是现实中的断路器,它是一个开关装置:

二:Hystrix解决超时问题

2.1:问题

假设我们前端提供了用户查询订单的功能,首先请求映射到OrderController,控制器通过调用服务orderService获取订单信息,前端传过来两个参数:一个是订单id,一个是用户id,orderService需要通过用户id调取用户服务来获取用户的相关信息返回给订单服务去组装信息,假设这里是通过http请求的,我们有一个单独的工程叫做:userService部署在其他的服务器上。但是这个服务器宕机了,这时候订单服务调取用户信息就失败了,然后查询订单整个请求就失败了!由一个服务的宕机就导致整个查询都失败了,牵一发而动全身。流程见下图:

2.2:使用Hystrix进行服务降级

2.2.1:引入hystrix依赖 这里引入了spring-cloud-starter-netflix-hystrix,springboot的starter里面整合了hystrix

<properties>
    <java.version>1.8</java.version>
    <spring-cloud.version>Greenwich.SR1</spring-cloud.version>
  </properties>

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

    <dependency>
      <groupId>cn.hutool</groupId>
      <artifactId>hutool-all</artifactId>
      <version>4.5.1</version>
    </dependency>

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

  <dependencyManagement>
    <dependencies>
      <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-dependencies</artifactId>
        <version>${spring-cloud.version}</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>
    </dependencies>
  </dependencyManagement>

2.2.2:模拟订单请求

首先通过OrderController映射/order请求,获取前端传入的参数orderId和useId,然后调用orderDetailService方法,

@RestController
public class OrderController {

  @Resource
  private OrderService orderService;

  /**
   * 获取订单信息
   *
   * @param orderNo
   * @return
   */
  @PostMapping("/order")
  public ResultVo<OrderDetail> getOrderInfo(@RequestParam("orderId") Long orderNo, @RequestParam("userId") Long userId) {

    OrderDetail orderDetail = orderService.orderDetailService(orderNo, userId);
    ResultVo resultVo = new ResultVo<>();
    resultVo.setCode(100);
    resultVo.setMessage("请求成功");
    resultVo.setData(orderDetail);
    return resultVo;
  }
}

2.2.3:订单服务调取其他服务

这里引入了RestTemplate,它是一个spring封装的http映射请求工具类,然后通过http请求访问url = "http://192.168.80.153:8070/user/getUser"获取用户名,将值给订单对象。不过假如在这其中发生了调用异常,请求用户服务异常的话,那么返回给前端就是一串空的订单信息,导致用户看到的订单为空。在使用hystrix之后,可以用@HystrixCommand(fallbackMethod = "orderFallBack")注解,在fallbackMethod中指定回退的方法,这里必须注意在@HystrixCommand上的方法其指定的回调方法必须和原方法的参数保持一致,这里包括参数类型、参数个数、参数顺序。我们在回调用法中模拟去查询缓存数据,返回给订单。有人又要问了,如果查询缓存服务器再异常呢?不排除这种可能性。如果是这样的话,依然可以使用@HystrixCommand注解在回调方法中,再指定其他的回调方法:

@Service
public class OrderService {
  @Autowired
  private RestTemplate restTemplate;
  /**
   * 根据订单id获取订单详情
   *
   * @param orderId
   * @param userId
   * @return
   */
  @HystrixCommand(fallbackMethod = "orderFallBack")
  public OrderDetail orderDetailService(Long orderId, Long userId) {

    if (Objects.isNull(orderId)) {
      return null;
    }

    OrderDetail orderDetail = OrderDBSource.getOrderDB().get(orderId);
    //调用user服务
    final String url = "http://192.168.80.153:8070/user/getUser";
    String userName = "";
    ResponseEntity<String> responseEntity = restTemplate.postForEntity(url, userId, String.class);
    String returnContent = responseEntity.getBody();
    if (Objects.nonNull(responseEntity) && StrUtil.isNotEmpty(returnContent)) {
      userName = returnContent;
    }
    if (ObjectUtil.isNotNull(orderDetail)){
      orderDetail.setUserName(userName);
    }
    return orderDetail;
  }
  /**
   * 异常调用的回调方法
   *
   * @return
   */
  public OrderDetail orderFallBack(Long orderId, Long userId) {
    OrderDetail orderDetail = OrderDBSource.getOrderCache().get(orderId);
    final String unknown = "未知用户";
    orderDetail.setUserName(unknown);
    return orderDetail;
  }
}

2.3.4:模拟测试

为了方便测试,首先我们将请求服务暂时先注释,然后用postman测试看正常的返回应该是这样的,这里使用了备注为数据库获取的订单,表明它没有走回调方法,因为这里没有访问用户url获取用户信息,程序可以正常访问。我再放开

加上获取用户服务的链接,实际上用户服务是无法访问到的,访问的话就会超时,超时会被hystrix捕捉到,然后走fallBack指定的方法,我们来测试一下,可以看到实际上走的是缓存中查询到的订单,可以看到用户服务已经成功的降级了,降级后的订单信息虽然是缓存获取到的,可能会存在延时等问题(当然只要维护好缓存就可以避免这个问题)。但是比没有任何数据带来的用户一点会更好!

三:Hystrix的流程

Hystrix实际上的工作原理是这样的:通过command来解耦请求与返回操作,在具体的实例中就是,Hystrix会对依赖的服务进行观察,通过command.toObservable调用返回一个观察的对象,同时发起一个事件,然后用Subscriber对接受到的事件进行处理。在command命令发出请求后,它通过一系列的判断,顺序依次是缓存是否命中、断路器是否打开、线程池是否占满,然后它才会开始对我们编写的代码进行实际的请求依赖服务的处理,也就是Hystrix.run方法,如果在这其中任一节点出现错误或者抛出异常,它都会返回到fallback方法进行服务降级处理,当降级处理完成之后,它会将结果返回给,际的调用者,经过一系列流程处理的,它的具体工作流程如下:

四:总结

本篇博客讲述了Hystrix是什么?然后解释了Hystrix如何进行服务降级处理以及简单的处理流程,讲到的内容是最为常用的功能,还有一些关于Hystrix的缓存、线程池的隔离技术等由于篇幅的原因,没有详细的讲解到,不过作为一篇入门级的Hystrix教程博客是基本够的。在实际的开发中,如何保持服务的健壮性、服务的可用性、尽量的减少bug,提升用户体验都是我们开发者的使命,这条优化和提升之路永远没有尽头,go ahead!

参考资料《spring cloud微服务实战》

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

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

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

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

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

  • SpringCloud超详细讲解微服务网关Gateway

    目录 前言 微服务网关GateWay介绍 GateWay特性介绍 Gateway 中的相关术语 Gateway实战 1.创建项目gateway 2.创建启动类 3.新增配置文件 4.编程方式实现路由 5.启动验证 总结 前言 上一篇:微服务网关Zuul 上文中,我们介绍了微服务网关Zuul,Zuul 是 Netflix 公司开源的产品,被称为第一代网关,也是 Spring Cloud 前几个版本默认使用的一款提供动态路由微服务网关组件,但是随着 Netflix 公司一系列的停更事件,在最新的 S

  • 浅谈SpringCloud实现简单的微服务架构

    Spring Cloud是一系列框架的有序集合.它利用Spring Boot的开发便利性巧妙地简化了分布式系统基础设施的开发,如服务发现注册.配置中心.消息总线.负载均衡.断路器.数据监控等,都可以用Spring Boot的开发风格做到一键启动和部署.Spring并没有重复制造轮子,它只是将目前各家公司开发的比较成熟.经得起实际考验的服务框架组合起来,通过Spring Boot风格进行再封装屏蔽掉了复杂的配置和实现原理,最终给开发者留出了一套简单易懂.易部署和易维护的分布式系统开发工具包. 接下

  • SpringCloud超详细讲解微服务网关Zuul

    目录 网关的作用 Spring Cloud 网关组件Zuul介绍 Zuul网关实战 1.创建服务 2.创建配置文件 3.创建Zuul过滤器 4.编写启动类 5.启动验证 总结 网关的作用 微服务架构中,服务实例的地址可能经常会发生变化,所以我们不能直接将服务的地址暴露出来.如果每一个微服务都直接暴露接口,会导致一系列的问题,比如调用过于复杂,涉及到账户.权限不能统一处理等.另外基于高内聚低耦合的设计准则来讲,我们也应该将内部系统和外部系统做切割. 因此,这时就需要有一个独立的组件来处理外部的请求

  • springcloud feign调其他微服务时参数是对象的问题

    目录 @RequestBody GET请求多参数的URL 正确写法如下 POST请求包含多个参数 在使用feign调用其它服务时,发现获取的参数是null,当参数是对象是,是执行的Post请求,所以要在方法参数前加@RequestBody, @RequestBody 处理HttpEntity传递过来的数据,一般用来处理非Content-Type: application/x-www-form-urlencoded编码格式的数据. GET请求中,因为没有HttpEntity,所以@RequestB

  • springcloud 服务降级的实现方法

    1 .简介 什么是服务降级?当服务器压力剧增的情况下,根据实际业务情况及流量,对一些服务和页面有策略的不处理或换种简单的方式处理,从而释放服务器资源以保证核心交易正常运作或高效运作. 如果还是不理解,那么可以举个例子:假如目前有很多人想要给我付钱,但我的服务器除了正在运行支付的服务之外,还有一些其它的服务在运行,比如搜索.定时任务和详情等等.然而这些不重要的服务就占用了JVM的不少内存与CPU资源,为了能把钱都收下来(钱才是目标),我设计了一个动态开关,把这些不重要的服务直接在最外层拒掉,这样处

  • 解析SpringCloud简介与微服务架构

    1. 微服务架构 1.1 微服务架构理解 微服务架构(Microservice Architecture)是一种架构概念,旨在通过将功能分解到各个离散的服务中以实现对解决方案的解耦.你可以将其看作是在架构层次而非获取服务的类上应用很多SOLID原则.微服务架构是个很有趣的概念,它的主要作用是将功能分解到离散的各个服务当中,从而降低系统的耦合性,并提供更加灵活的服务支持. 概念:把一个大型的单个应用程序和服务拆分为数个甚至数十个的支持微服务,它可扩展单个组件而不是整个的应用程序堆栈,从而满足服务等

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

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

  • 微服务搭建集成Spring Cloud Turbine详解

    1.概述 本文中,我将向你介绍Spring Cloud Netflix Turbine.它将多个Hystrix Metrics Streams 聚合为一个,以便显示在一个仪表板视图中. 简要介绍Hystrix . 在微服务架构中,我们有许多小应用程序相互通信以完成请求.这些下游服务有可能无法正确响应或完全失败.为了防止发生级联故障,我们为微服务设置了Hystrix回退机制. 每个实现Hystrix的微服务都可以选择公开Hystrix Metrics Streams(通过actuator端点/hy

  • 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

随机推荐