SpringCloud深入学习(六)——Hystrix与Feign的整合,实现降级、超时、熔断的配置使用

一、回顾

上一期我博客主要写了RestTemplate结合Hystrix实现降级、超时、限流、熔断的操作。
SpringCloud深入学习(五)——Hystrix的简介以及降级、限流、超时、熔断机制
其中针对Feign和Hystrix的结合使用,只简单说明了下失败请求fallback函数的使用问题,针对其他如降级、超时、限流、熔断等暂未作详细的说明。
(本来是准备写在一篇博客中的,只是那一篇博客内容过多,想了下还是分出来比较好)。

所以这一节专门做详细说明吧。

二、feign的大致讲解

我们上一篇博客中,说明了下如何去配置Hystrix,做请求出问题时,fallback函数的触发,如下列代码所示:

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;


@FeignClient(value="app-bunana-product",fallback=FallbackHystrix.class)
public interface ConsumerFeignClient {
	@RequestMapping("/product/getProduct")
	public String getTest1ByFeign(@RequestParam("name") String name);
}

以及使用到的fallback函数类:

import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import cn.linkpower.feignService.ConsumerFeignClient;

@Component 
public class FallbackHystrix implements ConsumerFeignClient {

	@Override
	public String getTest1ByFeign(String name) {
		return "服务错误,请联系开发者";
	}

}

[问1:]为什么直接再Feign,也就是在@FeignClient中定义fallback引入FallbackHystrix.class 就能实现呢?

我们可以看下Feign的引入依赖文件信息:
在这里插入图片描述
在Feign中,本身就默认引入了Hystrix。
SpringCloud默认已为Feign整合了Hystrix,只要Hystrix在项目的classpath中, Feign默认就会用断路器包裹所有方法

[问2:]为什么Feign整合Hystrix时,我们需要在配置文件中开启Hystrix?但为什么有些时候我没看见有配置也能用,有时候又不行?

从Spring Cloud Dalston开始,Feign默认是不开启Hystrix的。因此,如使用 Dalston及以上版本请务必额外设置属性:feign.hystrix.enabled=true,否则断路器不会 生效。

三、Feign实现部分接口不降级

我们上面已经阐述了,在D版本及以上默认不开启Hystrix实现降级操作,当我们需要采取Hystrix实现降级操作时,我们则需要增加一个全局的配置。

feign.hystrix.enabled=true

但是并非每一个接口都需要降级。
[问1:]为什么说不是每一个接口都需要降级?

当我们配置了降级操作时,
Hystrix会默认配置超时时间为1秒;
默认分配5000ms内达到错误次数20次触发熔断;
默认创建10个线程的线程池大小,实现限流。

如果此时我们的项目中,Feign接口很多,默认10个线程(未使用时,会默认存活一个线程),这样我们服务器的资源占用依旧还是很大的。
所以并不是所有的接口我们都需要采取Hystrix实现保护操作,但Feign开启全局后,使用Feign就会自带Hystrix。
[问2:]既然使用Feign会自带Hystrix,我们要使用Hystrix就必须开启Feign支持Hystrix。但我们如何设置某些接口不适用Hystrix呢?
此时我们只需要新增一个配置类,在指定的不使用Hystrix的接口上,增加其配置调用即可。
[问3:]那怎么做呢?

  • 配置全局使用Hystrix。
##feign中使用断路器,默认是没有开启的,需要在配置文件中开启        
feign:
  hystrix:
    enabled: true
  • 增加配置类(与启动类不在一个层级下
    在这里插入图片描述
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;

import feign.Feign;

/**
 * 在不需要使用Feign中Hystrix的接口上增加其注解
 * @author 7651
 *
 */
@Configuration
public class NoFeignHystrixConfig {
	
	@Bean
	@Scope("prototype")
	public Feign.Builder getFeignBuiler(){
		//feignBuilder方法默认返回HystrixFeign.Builder也就是说Feign默认支持Hystrix
        //现在改成Feign.Builder就禁用了Hystrix的支持
		return Feign.builder();
	}
}
  • 将上述配置的类,增加至指定的Feign的接口方法上
    在这里插入图片描述
    我们如何测试呢?
    我们可以制定两个Feign接口,一个进行Hystrix降级操作,一个屏蔽降级操作,分别请求测试即可。
    正常测试:

http://localhost:10001/test2?name=1
在这里插入图片描述

异常测试:

http://localhost:10001/test1?name=1
在这里插入图片描述

[注意:]

四、Feign实现Hystrx的降级配置

由于在Feign中默认引入了Hystrix,所以我们的依赖文件中,并不需要对Hystrix做额外的引入。

<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.1.4.RELEASE</version>
		<relativePath /> <!-- lookup parent from repository -->
	</parent>

	<properties>
		<java.version>1.8</java.version>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
	</properties>

	<!-- 管理依赖 -->
	<dependencyManagement>
		<dependencies>

			<dependency>
				<groupId>org.springframework.cloud</groupId>
				<artifactId>spring-cloud-dependencies</artifactId>
				<version>Finchley.M7</version>
				<type>pom</type>
				<scope>import</scope>
			</dependency>

		</dependencies>
	</dependencyManagement>
	<dependencies>
		<!-- SpringBoot整合Web组件 -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<!-- SpringBoot整合eureka客户端 -->
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
		</dependency>
		<!-- 加入feign -->
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-openfeign</artifactId>
		</dependency>
		
	</dependencies>
	<!-- 注意: 这里必须要添加, 否者各种依赖有问题 -->
	<repositories>
		<repository>
			<id>spring-milestones</id>
			<name>Spring Milestones</name>
			<url>https://repo.spring.io/libs-milestone</url>
			<snapshots>
				<enabled>false</enabled>
			</snapshots>
		</repository>
	</repositories>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>

然后针对具体的接口请求中,我们需要采取Feign接口的方式调用,调用的规则:

Feign接口的传递参数类型,参数个数与使用的接口保持一致!

所以我们编写Feign接口的方式:

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;


@FeignClient(value="app-bunana-product",fallback=ConsumerFallbackHystrix.class)
public interface ConsumerFeignClient {

	// @RequestParam("name")的作用在于使用该接口,可以将前接口传递的数据映射至新接口上
	@RequestMapping("/product/getProduct")
	public String getTest1ByFeign(@RequestParam("name") String name);
}

@Component
class ConsumerFallbackHystrix  implements ConsumerFeignClient {

	@Override
	public String getTest1ByFeign(String name) {
		return "服务错误,请联系开发者";
	}
}

启动Eureka注册中心和Consumer-eureka-feign-hystrix-10001服务。进行接口的请求测试:(详细demo会在文章末尾处展示github下载连接)

五、Feign整合Hystrix实现超时降级配置

上一篇博客中,我们说到Hystrix默认的超时时间为1秒,如果超过默认的请求回应时间,就会触发降级操作。
我们这次设置Consumer的超时时间规则为 2000ms;

hystrix:
  command:
    default:
      execution: ## 超时配置
        isolation:
          thread:
            timeoutInMilliseconds: 2000   #设置请求超时时间,默认1秒,超过指定的时间后,触发降级

同时,我们也给定Product的超时代码

@RestController
@RequestMapping("/product")
public class TestController {
	
	private static Logger log = LoggerFactory.getLogger(TestController.class);
	
	@Value("${server.port}")
	private String port;
	
	@RequestMapping("/getProduct")
	public String getTest1(String name) throws InterruptedException{
		int timeout = new Random().nextInt(3000);
		log.info("此时的超时时间--->{}",String.valueOf(timeout));
		Thread.sleep(timeout);
		return "this is product project getProduct name = "+String.valueOf(name)+",port="+port;
	}
}

启动两者服务并注册至eureka注册中心上,请求接口进行访问测试:

http://localhost:10001/test2?name=1
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
当请求响应时间低于 2000ms时,不会出现降级操作。
当请求响应时间超过 2000ms时,触发降级操作。

[注意:]这里有个坑!
feign底层是 ribbon的封装,所以 直接配置ribbon,ribbon默认超时也是1秒。如果要测试Hystrix,必须要求ribbon的超时时间要大于hystrix的超时时间!
springcloud(七) feign + Hystrix 整合

我的没有配置,能正常测试,若以后出现这种问题,再看此处!

六、Feign整合Hystrix实现熔断配置

相比上一篇博客,我们只需要当请求为 name="1"时,触发熔断操作即可!
先配置Consumer中,熔断的相关参数信息:

#hystrix相关配置
hystrix:
  command:
    default:
      execution: ## 超时配置
        isolation:
          thread:
            timeoutInMilliseconds: 20000   #设置请求超时时间,默认1秒,超过指定的时间后,触发降级
      circuitBreaker:  ##熔断配置 
        requestVolumeThreshold: 3 #达到指定的次数后熔断服务 (默认20次)
        sleepWindowInMilliseconds: 10000 #熔断后,多长时间进行恢复(默认 5000)

我们再定义Product服务中,出现问题的逻辑:

if("1".equalsIgnoreCase(name)){
	throw new NullPointerException();
}

分别启动项目,注册至注册中心中,请求测试:

需要达到的效果:10s内,连续3次错误,触发熔断,隔离后面的请求;
隔离10s后半开释放。

github代码下载

feign动态配置某些接口带Hystrix,某些接口不带Hystrix
Feign整合Hystrix实现熔断配置

猜你喜欢

转载自blog.csdn.net/qq_38322527/article/details/104579353