第十二章 Spring Cloud 断路器(Hystrix)

在微服务架构当中,根据业务来拆分成一个一个的微服务,服务和服务之间可以相互调用(RPC),Spring Cloud可以用RestTemplate+Ribbon和Feign来实现,为了保证高可用,单个服务会集群部署,由于网络或者自身原因,服务并不能保证100%可用,如果单个服务出现问题,调用这个服务就会出现阻塞,此时如果有大量的请求涌入,Servlet容器就会被消耗完毕,由于服务和服务之间有依赖姓,因此故障会进行传播,从而对整个系统造成灾难性的后果。
为了解决整个问题,就需要断路器。

1、断路器简介

Netflix开源了Hystrix组件,实现了断路器模式,SpringCloud对这一组件进行了整合。 在微服务架构中,一个请求需要调用多个服务是非常常见的,如下图:
在这里插入图片描述
较底层的服务如果出现故障,会导致连锁故障。当对特定的服务的调用的不可用达到一个阀值(Hystric 是5秒20次) 断路器将会被打开。
在这里插入图片描述

2、准备工作

本篇文章是基于 Spring Cloud 服务消费者(Feign) 来实现的。

3、在Ribbon当中使用断路器

第一步:添加依赖

在spring-cloud-consumer-ribbon项目当中添加依赖,代码如下:

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

第二步:在入口类Application当中添加注解

在入口类Application添加注解@EnableHystrix

第三步:改造HelloService

改造HelloService类,在sayHelloFromProvider方法上加上@HystrixCommand注解。该注解对该方法创建了熔断器的功能,并指定了fallbackMethod熔断方法,熔断方法直接返回了一个字符串,字符串为"hi,"+name+",sorry,error!",代码如下:

package com.brimen.springcloudconsumerribbon.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;
@Service
public class HelloService {
    @Autowired
    RestTemplate restTemplate;

    @HystrixCommand(fallbackMethod = "helloError")
    public String sayHelloFromProvider(String name) {
        return restTemplate.getForObject("http://spring-cloud-provide/hello/gethello?name=" + name, String.class);
    }
    public String helloError(String name){
        return "hi,"+name+",sorry,error!";
    }
}

第四步:启动工程

依次启动spring-cloud-eureka、spring-cloud-provide和spring-cloud-consumer-ribbon工程

第五步:访问spring-cloud-consumer-ribbo的接口

打开浏览器,访问:http://localhost:8082/hello/gethello
在这里插入图片描述

第六步:关闭spring-cloud-provide工程

关闭spring-cloud-provide工程,再次进行访问:http://localhost:8082/hello/gethello
在这里插入图片描述
这说明spring-cloud-provide工程不可用,当spring-cloud-consumer-ribbo调用spring-cloud-provide的接口时,执行失败,因此调用了断路器的方法

4、在Feign当中使用断路器

第一步:在配置文件当中进行配置

Feign当中是自带断路器的,在D版本之后之后,它没有默认打开,需要在配置文件当中进行配置,配置如下:

eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8080/eureka/ #1
server:
  port: 8084
spring:
  application:
    name: spring-cloud-consumer-feign #2
feign:
  hystrix:
    enabled: true #3

#1、服务注册中心的地址
#2、服务的名称,作为其它服务调用的服务名
#3、开启断路器

第二步:改造Service接口

package com.brimen.springcloudconsumerfeign.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.client.RestTemplate;

@FeignClient(value = "spring-cloud-provide",fallback =  HelloHystrixService.class)
public interface HelloService {

    @RequestMapping(value = "/hello/gethello",method = RequestMethod.GET)
    String sayHelloFromProvider(@RequestParam(value = "name") String name);
}

创建一个回调的类HelloHystrixService

package com.brimen.springcloudconsumerfeign.service;

import org.springframework.stereotype.Component;

@Component
public class HelloHystrixService implements HelloService {

    @Override
    public String sayHelloFromProvider(String name) {
        return "hi,"+name+",sorry,error!";
    }
}

第三步:启动程序并访问

依次启动spring-cloud-eureka、spring-cloud-provide和spring-cloud-consumer-feign
访问spring-cloud-consumer-feign的接口:http://localhost:8084/hello/gethello
结果如下:
在这里插入图片描述
结果:在spring-cloud-provide能访问的情况下,能够正常访问到接口并收到数据

第四步:将spring-cloud-provide服务关闭

重新访问http://localhost:8084/hello/gethello,发现断路器已经起作用,调用的是HelloHystrixService里面的回调方法。
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_24630433/article/details/88262267