SpringCloud学习记录——4.熔断机制

1.前言

经过上一篇博客的Ribbon和OpenFeign学习后,接下来我们正式开始熔断机制的学习,目前常用的服务间调用组件有Hystrix,这里我们就重点来学习一下这个组件的使用。

2.Hystrix整合Ribbon

我们知道大量请求会阻塞在Tomcat服务器上,影响其它整个服务.在复杂的分布式架构的应用程序有很多的依赖,都会不可避免地在某些时候失败.高并发的依赖失败时如果没有隔离措施,当前应用服务就有被拖垮的风险。
Spring Cloud Netflix Hystrix就是隔离措施的一种实现,可以设置在某种超时或者失败情形下断开依赖调用或者返回指定逻辑,从而提高分布式系统的稳定性。
生活中举个例子,如电力过载保护器,当电流过大的的时候,出问题,过载器会自动断开,从而保护电器不受烧坏。因此Hystrix请求熔断的机制跟电力过载保护器的原理很类似。
比如:订单系统请求库存系统,结果一个请求过去,因为各种原因,网络超时,在规定几秒内没反应,或者服务本身就挂了,这时候更多的请求来了,不断的请求库存服务,不断的创建线程,因为没有返回,也就资源没有释放。


Hystrix特性

  • 请求熔断
    当请求后端服务失败数量超过一定比例(默认50%), 断路器会切换到开路状态(Open). 这时所有请求会直接失败而不会发送到后端服务. 断路器保持在开路状态一段时间后(默认5秒), 自动切换到半开路状态(HALF-OPEN)。
  • 服务降级
    当请求后端服务出现异常的时候, 服务降级就是用来提供一个基础服务,以便告诉后面的请求不要再来了。
  • 依赖隔离
    在Hystrix中, 主要通过线程池来实现资源隔离. 通常在使用的时候我们会根据调用的远程服务划分出多个线程池.比如说,一个服务调用两外两个服务,你如果调用两个服务都用一个线程池,那么如果一个服务卡在哪里,资源没被释放后面的请求又来了,导致后面的请求都卡在哪里等待,导致你依赖的A服务把你卡在哪里,耗尽了资源,也导致了你另外一个B服务也不可用了。这时如果依赖隔离,某一个服务调用A B两个服务,如果这时我有100个线程可用,我给A服务分配50个,给B服务分配50个,这样就算A服务挂了,我的B服务依然可以用。
  • 请求缓存
    比如一个请求过来请求我userId=1的数据,你后面的请求也过来请求同样的数据,这时我不会继续走原来的那条请求链路了,而是把第一次请求缓存过了,把第一次的请求结果返回给后面的请求。
  • 请求合并
    我依赖于某一个服务,我要调用N次,比如说查数据库的时候,我发了N条请求发了N条SQL然后拿到一堆结果,这时候我们可以把多个请求合并成一个请求,发送一个查询多条数据的SQL的请求,这样我们只需查询一次数据库,提升了效率。

事实上,Hystrix一般需要与Ribbon和OpenFeign配合使用,因为OpenFeign的内部已集成Hystrix,只需要调用相应api即可,所以这里首先演示Ribbon与OpenFeign的配合使用。

  1. 像之前一样建立名为hystrix-client的模块,同样记得在选择依赖时选择Spring Web、Eureka Discovery、Ribbon,Hystrix,如图所示:
    在这里插入图片描述
  2. 修改配置文件application.yml,代码如下:
server:
  port: 18766
eureka:
  instance:
    hostname: localhost
  client:
    service-url:
      defaultZone: http://${eureka.instance.hostname}:18761/eureka/
spring:
  application:
    name: service-hystrix
  1. 修改启动类,使用注解@EnableCircuitBreaker开启断路器的支持。代码如下:
package com.springclouddemo.hystrixclient;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;

@SpringBootApplication
@EnableDiscoveryClient
@EnableCircuitBreaker
public class HystrixClientApplication {

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

    @Bean
    @LoadBalanced
    RestTemplate restTemplate() {
        return new RestTemplate();
    }
}
  1. 接下来,创建一个HiService类,表示要远程调用的接口服务,注意这里的uri名字要和调用的application-name相同,即上一篇博客中eureka-client中配置过的。除此之外,使用注解@HystrixCommand来提供服务降级,注解参数fallbackMethod提供降级服务,代码如下:
package com.springclouddemo.hystrixclient.service;

import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

/**
 * @author 莫息涛
 * @Description: Ribbon的测试服务类
 * @date 2020/2/24 11:54
 */
@Service
public class HiService {

    @Autowired
    RestTemplate restTemplate;

    @HystrixCommand(fallbackMethod = "hiServiceError")
    public String hiService() {
        return restTemplate.getForObject("http://SERVICE-HI/hi",String.class);  //注册的服务名称
    }

    public String hiServiceError(){
        return "Error";
    }
}
  1. 创建一个HiController,调用HiService的方法,代码如下:
package com.springclouddemo.ribbonclient.controller;

import com.springclouddemo.ribbonclient.service.HiService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author 莫息涛
 * @Description: Ribbon的对外测试接口
 * @date 2020/2/24 11:54
 */
@RestController
public class HiController {

    @Autowired
    HiService hiService;

    @RequestMapping(value = "/hi")
    public String hi(){
        return hiService.hiService();
    }
}
  1. 按照顺序依次启动eureka-servereureka-clienthystrix-client,访问注册中心页面,可以看到整合了hystrix的ribbon模块已经启动,如图所示:
    在这里插入图片描述
  2. 访问http://localhost:18766/hi,可以看到如下显示结果,说明整合了hystrix的ribbon配置成功,如图所示:
    在这里插入图片描述
  3. 关闭eureka-client,然后再次访问http://localhost:18766/hi,可以看到如下显示结果,说明hystrix配置的降级服务成功,如图所示:
    在这里插入图片描述

3.Hystrix整合OpenFeign

我们讲完了Ribbon与Hystrix的结合,那么接下来看看Feign中又是怎么使用Hystrix的。
因为OpenFeign内置了Hystrix的功能,所以我们不需要引入特殊的包。我们先来创建一个降级的服务。
用这篇博客写好的OpenFeign样例在上面进行扩展

  1. 新建一个fallback包,用于存放降级服务的相应方法,再新建HiFallback,作为降级服务的HiInterface 实现类,代码如下:
package com.springclouddemo.openfeignclient.fallback;

import com.springclouddemo.openfeignclient.Interface.HiInterface;
import org.springframework.stereotype.Component;

/**
 * @author 莫息涛
 * @Description: 测试的降级服务
 * @date 2020/2/24 18:28
 */
@Component
public class HiFallback implements HiInterface {
    @Override
    public String hi() {
        return "Error";
    }
}
  1. 修改HiInterface,添加降级服务的fallback属性,代码如下:
package com.springclouddemo.openfeignclient.Interface;

import com.springclouddemo.openfeignclient.fallback.HiFallback;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

/**
 * @author 莫息涛
 * @Description: Feign的测试接口
 * @date 2020/2/24 10:48
 */
@FeignClient(value = "service-hi",fallback = HiFallback.class)
public interface HiInterface {

    @RequestMapping(value = "/hi",method = RequestMethod.GET)
    String hi();
}
  1. 修改application.yaml,由于Feign默认的Hystrix是关闭的,我们需要在配置文件中开启,代码如下:
server:
  port: 18764
eureka:
  instance:
    hostname: localhost
  client:
    service-url:
      defaultZone: http://${eureka.instance.hostname}:18761/eureka/
spring:
  application:
    name: service-openfeign
feign:
  hystrix:
    enabled: true
  1. 按照顺序依次启动eureka-servereureka-clientopenfeign-client,访问注册中心页面,可以看到整合了hystrix的openfeign模块已经启动,如图所示:
    在这里插入图片描述
  2. 访问http://localhost:18764/hi,可以看到如下显示结果,说明整合了hystrix的openfeign配置成功,如图所示:
    在这里插入图片描述
  3. 关闭eureka-client,然后再次访问http://localhost:18764/hi,可以看到如下显示结果,说明hystrix配置的降级服务成功,如图所示:
    在这里插入图片描述
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

赈川

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值