springCloud(6)---断路器Hystrix

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/sinat_23490433/article/details/89186254

学习断路器Hystrix之前,先引入一个问题:

什么是“雪崩效应”?

在微服务架构中,根据业务将应用拆分为一个个的服务,服务与服务之间通过rpc远程调用技术相互调用。

在springCloud中可以用ribbon+restTemplate和Feign这2种方式进行调用

为了保证应用程序的高可用性,单个服务通常会集群部署,由于网络原因或自身原因,服务并不能保证100%的可用。

如果出现单个服务故障,调用这个服务就会出现线程阻塞,此时如果有大量的客户请求涌入,servlet容器的线程资源就会被消耗完毕,导致服务瘫痪。而服务与服务之间的依赖性,故障会传播,会对整个微服务的系统造成灾难性的后果。

2、为了解决雪崩效应导致整个服务系统的瘫痪,在springCloud中引入了断路器模型

在微服务架构中,一个请求需要调用多个服务是非常常见的,如下图

上图中,一个客户端的请求访问应用程序,应用程序需要调用多个服务才能完成。如用户购买商品,需要调用订单服务和库存服务以及物流服务。如果此时库存系统由于自身原因出现故障,由于服务与服务之间的依赖性,故障会传播,导致物流服务和订单服务等都出现故障,为了解决这个问题,在springCloud中引入了Hystrix断路器。

引入断路器后,如下图所示:

当服务故障时,断路器会打开,可避免连锁故障,fallBack方法可以直接返回一个固定值

方式1、在ribbon中实现断路器步骤如下:

第一步、在eureka-ribbon中进行改造,首先在pom.xml中加入spring-cloud-starter-netflix-hystix的依赖,如下:

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

第二步、在启动类中加入@EnableHystrix注解开启Hystrix

package com.cn.eurekaribbon;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.hystrix.EnableHystrix;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.web.client.RestTemplate;

@SpringBootApplication
@EnableEurekaClient
@EnableDiscoveryClient //通过该注解向服务中心注册
@EnableHystrix         //开启Hystrix
@ComponentScan({"com.cn.service","com.cn.controller"})
public class EurekaRibbonApplication {

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

   @Bean  //向ioc容器中注入一个bean
   @LoadBalanced  //表明这个restTemplate开启了负载均衡的功能
   RestTemplate restTemplate(){
      return new RestTemplate();
   }

}

第三步、改造RibboService,代码如下:

package com.cn.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;

/**
 * 写一个测试服务类,通过之前注入到IOC容器中的restTemplate来消费
 * eureka-client项目中的service-client1服务的/hello接口
 * 本示例:直接用程序名替代了具体的url地址,在ribbon中它会根据服务名来选择具体的服务实例
 * 根据服务实例在请求的时候会用具体的url替换掉服务名
 * */
@Service
public class RibbonService {
    @Autowired
    RestTemplate restTemplate;
    @HystrixCommand(fallbackMethod = "hiError") //该注解对该方法创建了熔断的功能,并指定了fallbackMethod熔断方法
                                                //熔断方法为hiError
    public String ribbonService(String name){
        return restTemplate.getForObject("http://SERVICE-CLIENT1/hello?name="+name,String.class);
    }
    //熔断方法,直接返回一个字符串消息提示错误
    public String hiError(String name){
        return "hi,"+name+" sorry,error!";
    }
}

第四步、测试

启动eureka-ribbon工程,当我们访问http://localhost:8503/hi?name=zhangsan,浏览器显示如下:

此时关闭eureka-client工程,当我们再次访问http://localhost:8503/hi?name=zhangsan,浏览器显示如下:

说明:当eureka-client工程不可用,eureka-ribbon调用eureka-client的API接口时,会执行快速失败,直接返回一个字符串,而不是等待响应超时,这很好的控制了容器的线程阻塞。

 

方式2、在Feign方式下实现断路器

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

第一步、在eureka-feign中的配置文件中新增如下代码,打开feign自带的断路器

feign:
  hystrix:
    enabled: true

第二步、对eureka-feign工程进行改造,只需要在IFeignService的的接口的注解上加上fallback的指定类即可,如下:

package com.cn.service;

import com.cn.Hystrix.IFeignServiceHystrix;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;

/**
 * 定义一个feign接口
 * */
@FeignClient(value = "service-client1",fallback = IFeignServiceHystrix.class)
public interface IFeignService {
    @RequestMapping(value = "/hello",method = RequestMethod.GET)
    String sayHelloFromClientOne(@RequestParam(value="name")String name);
}

第三步、创建包com.cn.hystrix,并在该包下创建类

package com.cn.Hystrix;

import com.cn.service.IFeignService;
import org.springframework.stereotype.Component;

@Component  //实现IFeignService接口,并注入到IOC容器中
public class IFeignServiceHystrix implements IFeignService {

    @Override
    public String sayHelloFromClientOne(String name) {
        return "sorry"+name;
    }
}

第四步、测试

启动eureka-feign工程,当我们访问http://localhost:8505/hi?name=zhangsan,浏览器显示如下:

此时关闭eureka-client工程,当我们再次访问http://localhost:8505/hi?name=zhangsan,浏览器显示如下:

说明:当eureka-client工程不可用,eureka-feign调用eureka-client的API接口时,会执行快速失败,直接返回一个字符串,而不是等待响应超时,这很好的控制了容器的线程阻塞。

猜你喜欢

转载自blog.csdn.net/sinat_23490433/article/details/89186254
今日推荐