Spring Cloud学习笔记【十二】Hystrix的使用和了解

                           Spring Cloud学习笔记【十二】Hystrix的使用和了解


Hystrix [hɪst'rɪks],中文含义是豪猪,因其背上长满棘刺,从而拥有了自我保护的能力。本文所说的Hystrix是Netflix开源的一款容错框架,同样具有自我保护能力。


一、Hystrix简介

Hystrix是由Netflix开源的一个延迟和容错库,用于隔离访问远程系统、服务或者第三方库,防止级联失败,从而提升系统的可用性、容错性与局部应用的弹性,是一个实现了超时机制和断路器模式的工具类库。

二、Hystrix的设计原则

  • 防止任何单独的依赖耗尽资源(线程)
    过载立即切断并快速失败,防止排队
  • 尽可能提供回退以保护用户免受故障
  • 使用隔离技术(例如隔板,泳道和断路器模式)来限制任何一个依赖的影响
  • 通过近实时的指标,监控和告警,确保故障被及时发现
  • 通过动态修改配置属性,确保故障及时恢复
  • 防止整个依赖客户端执行失败,而不仅仅是网络通信

三、Hystrix的工作原理

  • 使用命令模式将所有对外部服务(或依赖关系)的调用包装在HystrixCommand或HystrixObservableCommand对象中,并将该对象放在单独的线程中执行。
  • 每个依赖都维护着一个线程池(或信号量),线程池被耗尽则拒绝请求(而不是让请求排队)。
  • 记录请求成功,失败,超时和线程拒绝。
  • 服务错误百分比超过了阈值,熔断器开关自动打开,一段时间内停止对该服务的所有请求。
  • 请求失败,被拒绝,超时或熔断时执行降级逻辑。
  • 近实时地监控指标和配置的修改。

四、Ribbon中使用熔断器

a.引入依赖

 implementation 'org.springframework.cloud:spring-cloud-starter-netflix-hystrix'

b.添加注解(@EnableHystrix)

@SpringBootApplication
@EnableEurekaClient
@EnableHystrix //开启hystrix功能
public class DemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}

c.编写代码(直接采用最简单的RestTemplate)

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

@RestController
@RequestMapping("/hystrix")
public class HystrixController {

    @Autowired
    private RestTemplate restTemplate;
    
    @RequestMapping("info")
    public String test2() {
        return restTemplate.getForObject("http://CLIENT-SERVICE/order/info", String.class);
    }
    
}
//订单信息模块返回
@RestController
@RequestMapping("/order")
public class OrderController {

    private Log LOGGER = LogFactory.getLog(OrderController.class);

    @GetMapping("/info")
    public String test(HttpServletRequest request) {
        LOGGER.info("address:" + request.getRemoteAddr());
        return "来自订单模块的信息返回:服务端口是9005,调用者的IP来自" + request.getRemoteAddr();
    }
}

正常访问的结果:

d.@HystrixCommand,属性fallbackMethod是熔断时返回的方法。

import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

@RestController
@RequestMapping("/hystrix")
public class HystrixController {

    @Autowired
    private RestTemplate restTemplate;

    @RequestMapping("info")
    @HystrixCommand(fallbackMethod="getDefaultMethod")
    public String test2() {
        return restTemplate.getForObject("http://CLIENT-SERVICE/order/info", String.class);
    }

    public String getDefaultMethod() {
        return "this is the hystrix default method";
    }
}

关闭订单的服务的返回结果是:

五、参数详解之@HystrixCommand

@HystrixCommand不但可以在方法,也可以直接使用在类上面,并且参数对于超时等等可以进行配置,当然也可以直接进行配置文件进行配置。

a.@DefaultProperties()和@HystrixCommand进行配套使用,进行类全局配置使用。

import com.netflix.hystrix.contrib.javanica.annotation.DefaultProperties;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

@RestController
@RequestMapping("/hystrix")
@DefaultProperties(defaultFallback = "calssDefaultFallBack")
public class HystrixController {

    @Autowired
    private RestTemplate restTemplate;

    @RequestMapping("info")
    //@HystrixCommand(fallbackMethod="getDefaultMethod")
    @HystrixCommand
    public String test2() {
        return restTemplate.getForObject("http://CLIENT-SERVICE/order/info", String.class);
    }


    public String getDefaultMethod() {
        return "this is the hystrix default method";
    }

    public String calssDefaultFallBack() {
        return "this is the hystrix class default method";
    }
}

HystrixCommandProperties定义参数类的了解,在Hystrix配置的项都在这个类里面,并且有许多的缺省项。

b.超时问题

在Order模块添加睡眠时间为2s

@RestController
@RequestMapping("/order")
public class OrderController {

    private Log LOGGER = LogFactory.getLog(OrderController.class);

    @GetMapping("/info")
    public String test(HttpServletRequest request) {
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        LOGGER.info("address:" + request.getRemoteAddr());
        return "来自订单模块的信息返回:服务端口是9005,调用者的IP来自" + request.getRemoteAddr();
    }
}

进行请求发送,结果是返回默认方法

 

可以直接从HystrixCommandProperties类中看到,默认时间是1s,所以出现服务降级了。

  private static final Integer default_executionTimeoutInMilliseconds = 1000; // default => executionTimeoutInMilliseconds: 1000 = 1 second

 进行配置,就可以正常访问

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

 

c.断路器模式配置

private final HystrixProperty<Integer> circuitBreakerRequestVolumeThreshold; // number of requests that must be made within a statisticalWindow before open/close decisions are made using stats
private final HystrixProperty<Integer> circuitBreakerSleepWindowInMilliseconds; // milliseconds after tripping circuit before allowing retry
private final HystrixProperty<Boolean> circuitBreakerEnabled; // Whether circuit breaker should be enabled.
private final HystrixProperty<Integer> circuitBreakerErrorThresholdPercentage; // % of 'marks' that must be failed to trip the circuit
import com.netflix.hystrix.contrib.javanica.annotation.DefaultProperties;
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.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

@RestController
@RequestMapping("/hystrix")
@DefaultProperties(defaultFallback = "calssDefaultFallBack")
public class HystrixController {

    @Autowired
    private RestTemplate restTemplate;

    @RequestMapping("info")
    //@HystrixCommand(fallbackMethod="getDefaultMethod")
    @HystrixCommand(commandProperties = {
            @HystrixProperty(name = "circuitBreaker.enabled", value = "true"), //设置熔断
            @HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "10"),//断路器的最小请求数
            @HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds", value = "10000"),//时间窗口
            @HystrixProperty(name = "circuitBreaker.errorThresholdPercentage", value = "60")//错误百分比条件

    })
    public String test2(@RequestParam("number") Integer number) {
        if (number % 2 == 0) {
            return "success";
        }
        return restTemplate.getForObject("http://CLIENT-SERVICE/order/info", String.class);
    }


    public String getDefaultMethod() {
        return "this is the hystrix default method";
    }

    public String calssDefaultFallBack() {
        return "this is the hystrix class default method";
    }
}

当错误率在一定时间范围内达到一定的比例是会出现这样的结果,这就是断路器的作用了

在配置文件配置这些也是一样的

六、Feign中使用熔断器

# feign熔断器开关
feign:
  hystrix:
    enabled: true
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;

@FeignClient(name = "CLIENT-SERVICE",fallback = IClientServiceImpl.class)//服务名称
public interface ClientService {
    //请求方式 和 请求地址
    @GetMapping("/order/info")
    String getOrderInfo();
}
@Component//@todo 注解不可少
public class IClientServiceImpl implements ClientService{
    @Override
    public String getOrderInfo() {
        return "this is the feign default method";
    }
}
import com.example.demo.client.ClientService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/test")
public class FeignController {

    @Autowired
    private ClientService clientService;

    @RequestMapping("/orderInfo")
    public String test() {
        return clientService.getOrderInfo();
    }

}

 @FeignClient注解参数说明:

  • name:指定FeignClient的名称,如果项目使用了Ribbon,name属性会作为微服务的名称,用于服务发现。

  • fallback: 定义容错的处理类,当调用远程接口失败或超时时,会调用对应接口的容错逻辑,fallback指定的类必须实现@FeignClient标记的接口。

  • fallbackFactory: 工厂类,用于生成fallback类示例,通过这个属性我们可以实现每个接口通用的容错逻辑,减少重复的代码

  • path: 定义当前FeignClient的统一前缀,类似于注解到类上的@RequestMapping的功能

停掉order服务,打开浏览器访问http://localhost:8080/test/orderInfo,服务正常,截图如下:

七、可视化界面的使用

    implementation 'org.springframework.cloud:spring-cloud-starter-netflix-hystrix-dashboard'

在程序的启动类上加上@EnableHystrixDashboard注解,开启Hystrix Dashboard的功能,2.x的版本有一些区别,需要额外配置这里就不在赘述。

在浏览器上访问http://127.0.0.1:8080/hystrix,浏览器显示的界面如下图所示:

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值