chap05-Hystrix-1-熔断器简介以及环境搭建

熔断器

在微服务架构中,我们将系统拆分成了很多服务单元,各单元的应用通过服务注册与订阅的方式相互依赖。 由于单元都在不同的进程中运行,依赖通过远程调用的方式执行,这样就有可能因为网络原因或是依赖服务自身问题出现调用故障或延迟,而这些问题会直接导致调用方的对外服务也出现延迟,若此时调用方的请求不断增加,最后就会因等待出现故障的依赖方响应形成任务积压,最终导致自身服务的瘫痪。

为了解决这样的问题,产生了断路器等一系列的服务保护机制。

断路器本身是一种开关装置,用于电路上保护线路过载,当线路中有电器发生短路时,断路器能够及时切断故障电路,放置发生过载、发热甚至起火等严重后果。

在分布式架构中,断路器模式的作用也是类似的,当某个服务单元发生故障时,通过断路器的故障监控,向调用方返回一个错误响应,而不是长时间的等待。这样就不会是的线程因为调用故障服务被长时间占用不释放,避免了故障在分布式系统中蔓延。

Spring Cloud Hystrix实现了断路器、线程隔离等一些列的服务保护功能。它具备服务降级、服务熔断、线程和信号隔离、请求缓存、请求合并以及服务监控等强大功能。

快速入门

在开始使用Hystrix实现断路器之前,我们先用之前实现的一些内容作为基础,构建一个如下的服务调用关系。
在这里插入图片描述

  • Eureka注册中心peer1:1111,peer2:1112
  • 服务提供者(CLOUD-EUREKA-CLIENT):启动两个服务实例localhost:8080, localhost8081
  • 服务消费者(RIBBON-CLIENT):使用Ribbon实现的服务消费,localhost:9000

正常启动

当所有2个服务实例都正常启用,通过http://localhost:9000/ribbon-consumer可以获取如下图信息:
在这里插入图片描述

关闭一个服务实例

关闭一个节点s43:9999,当请求轮询到该节点时,请求报错:
在这里插入图片描述

当一个节点挂掉之后,并不会被立即从服务清单中剔除,而是在下个同步周期时才会被同步,标记为不可用(剔除).

加入熔断器

  1. 添加maven依赖

    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
    </dependency>
    
  2. 在应用主类上添加@EnableCircuitBreaker注解。

    @SpringBootApplication
    @EnableDiscoveryClient
    @EnableCircuitBreaker
    public class RibbonHystrixApplication {
        public static void main(String[] args) {
            SpringApplication.run(RibbonHystrixApplication.class, args);
        }
    
    
        @Bean
        @LoadBalanced
        public RestTemplate restTemplate(){
            return new RestTemplate();
        }
    }
    

    或者使用@SpringCloudApplication注解:

    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @Inherited
    @SpringBootApplication
    @EnableDiscoveryClient
    @EnableCircuitBreaker
    public @interface SpringCloudApplication {
    }
    
  3. Client改造消费方式。

a. 新增HelloService,使用@HystrixCommand指定回调函数。

@Service
public class HelloService {

    @Autowired
    private RestTemplate restTemplate;

    @HystrixCommand(fallbackMethod = "helloFallback")
    public String helloService(){
        return restTemplate.getForEntity("http://EUREKA-ECHO-SERVICE/test/hello",String.class).getBody();
    }

    public String helloFallback(){
        return "error";
    }
}

b. controller中直接调用HelloService来调用服务.

c. 将关闭的服务实例重新启用,使用http://localhost:9000/ribbon-consumer访问---- 正常

d.重新关闭服务实例,当轮询到该实例后,页面请求结果如下图:
在这里插入图片描述

除了断开服务实例来模拟某个节点无法访问的情况,还可以通过模拟服务阻塞(长时间未响应)`的情况。

改造服务提供者CLOUD-EUREKA-CLIENT/hello方法:

@RequestMapping("/hello")
public String hello() throws InterruptedException {
    int sleepTime = new Random().nextInt(3000);
    logger.info("sleep{}ms", sleepTime);
    Thread.sleep(sleepTime);

    return "hello world";
}

当服务提供者sleep超过2000ms时,服务调用者RIBBON-CONSUMER会因为调用超时的服务而触发熔断,并调用返回逻辑。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值