一起来学SpringCloud 断路器Hystrix

序言

在微服务架构中,根据业务来拆分成一个个的服务,服务与服务之间可以通过 RPC 相互调用,在 Spring Cloud 中可以用 RestTemplate + RibbonFeign 来调用。为了保证其高可用,单个服务通常会集群部署。由于网络原因或者自身的原因,服务并不能保证 100% 可用,如果单个服务出现问题,调用这个服务就会出现线程阻塞,此时若有大量的请求涌入,Servlet 容器的线程资源会被消耗完毕,导致服务瘫痪。服务与服务之间的依赖性,故障会传播,会对整个微服务系统造成灾难性的严重后果,这就是服务故障的 “雪崩” 效应。 为了解决这个问题,业界提出了熔断器模型。

Netflix 开源了 Hystrix 组件,实现了熔断器模式。

此文章仅限入门 SpringCloud版本为 Greenwich

当然 Hystrix 已经进入维护阶段了,也就是说不再会有新功能产出,但是已经足够成熟。Spring Cloud 正在孵化自己的熔断器 Resilience4j ,最近阿里的 Sentinel 也发布了可用于生产的版本。

使用

首先呢加入如下依赖

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
        </dependency>
    </dependencies>

在yml里配置一下注册中心

server:
  port: 7001
spring:
  application:
    name: spring-cloud-action-server-order
eureka:
  instance:
    prefer-ip-address: true
    instance-id: ${spring.cloud.client.ip-address}:${spring.application.instance_id:${server.port}}
    hostname: localhost
  client:
    service-url:
      defaultZone: http://${eureka.instance.hostname}:8761/eureka/

然后呢是启动类

@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
@EnableHystrix
public class OrderApplication {
    public static void main(String[] args) {
        SpringApplication.run(ATestApplication.class, args);
    }
}

其实还有一个注解可以 同时包含@EnableDiscoveryClient 、@EnableDiscoveryClient、@EnableHystrix 换成@SpringCloudApplication就行了

@SpringCloudApplication
@EnableFeignClients
public class OrderApplication {
    public static void main(String[] args) {
        SpringApplication.run(OrderApplication.class, args);
    }
}

在Ribbon中使用

在 Ribbon 调用方法上增加 @HystrixCommand 注解并指定 fallbackMethod 熔断方法

@RestController
public class OrderController {

    @Autowired
    private RestTemplate restTemplate;

    @HystrixCommand(fallbackMethod = "getProductsError")
    @GetMapping
    public String getOrder() {
        return restTemplate.getForObject("http://SPRING-CLOUD-ACTION-SERVER-B/getProducts, String.class);
    }

    public String getProductsError(String message) {
        return "Hi,your request error.";
    }
}

怎么测试呢? 当我关闭 spring-cloud-action-server-product 服务时,访问@HystrixCommand 注解标注的接口时候,我们发现直接返回了getProductsError 里的内容,就表示服务已经熔断。

这里说一点高级用法,如果想使用Hystrix 的详细配置,可以 使用@HystrixCommandcommandProperties 属性与@HystrixProperty注释列表一起使用 。

比如设置一个超时

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

或者这样使用

@HystrixCommand(commandProperties = {@HystrixProperty(name = HystrixPropertiesManager.EXECUTION_ISOLATION_THREAD_TIMEOUT_IN_MILLISECONDS, value = "15000")})

Hystrix 还而已通过信号量来实现限流,等功能,具体可以在 其 github仓库的wiki 里详细的看到。

Feign 中使用熔断器

Feign 是自带熔断器的,但默认是关闭的。需要在配置文件中配置打开它,在配置文件增加以下代码

feign:
  hystrix:
    enabled: true

然后在Feign的接口中增加forback指定类

@FeignClient(value = "spring-cloud-action-server-product",fallback =ProductService.FallbackProductService.class )
public interface ProductService {
    @GetMapping("/getProducts")
    String getProducts();
   
    @Component
    class FallbackProductService implements ProductService {
        @Override
        public String query() {
            return "访问出现问题";
        }
    }
}

然后在调用Feign的时候也就会带有熔断的效果啦。

仪表盘

除了隔离依赖服务的调用以外,Hystrix还提供了近实时的监控,Hystrix会实时、累加地记录所有关于HystrixCommand的执行信息,包括每秒执行多少请求多少成功,多少失败等。Netflix通过hystrix-metrics-event-stream项目实现了对以上指标的监控。

添加依赖

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

然后在启动类中加入

@SpringCloudApplication
@EnableFeignClients
@EnableHystrixDashboard
public class OrderApplication {
    public static void main(String[] args) {
        SpringApplication.run(OrderApplication.class, args);
    }
}

然后加入 HystrixMetricsStreamServlet 的配置

@Configuration
public class HystrixDashboardConfig {

    @Bean
    public ServletRegistrationBean getServlet() {
        HystrixMetricsStreamServlet streamServlet = new HystrixMetricsStreamServlet();
        ServletRegistrationBean registrationBean = new ServletRegistrationBean(streamServlet);
        registrationBean.setLoadOnStartup(1);
        registrationBean.addUrlMappings("/hystrix.stream");
        registrationBean.setName("HystrixMetricsStreamServlet");
        return registrationBean;
    }
}

打开项目 访问 http://localhost:7001/hystrix 就可以啦

输入相应的玩意设置一下标题就可以进入控制台了,只要触发了Hystrix熔断 就会显示在控制台中。

给一个详细的说明图解

什么情况下会触发 fallback 方法

名字描述触发fallback
EMIT值传递NO
SUCCESS执行完成,没有错误NO
FAILURE执行抛出异常YES
TIMEOUT执行开始,但没有在允许的时间内完成YES
BAD_REQUEST执行抛出HystrixBadRequestExceptionNO
SHORT_CIRCUITED断路器打开,不尝试执行YES
THREAD_POOL_REJECTED线程池拒绝,不尝试执行YES
SEMAPHORE_REJECTED信号量拒绝,不尝试执行YES

fallback 方法在什么情况下会抛出异常

名字描述抛异常
FALLBACK_EMITFallback值传递NO
FALLBACK_SUCCESSFallback执行完成,没有错误NO
FALLBACK_FAILUREFallback执行抛出出错YES
FALLBACK_REJECTEDFallback信号量拒绝,不尝试执行YES
FALLBACK_MISSING没有Fallback实例YES

注意

Hystrix在执行他的逻辑的时候,其实做了来回的线程切换,所以说很容易导致一些问题,比如ThreadLocal 或者 Spring 声明式事物的失效。所以是用需要仔细考虑。

此文章仅限入门,切记啊不会用找不到多去官网看文档!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值