Fallback多级降级,Request Cache减压。你知道是怎么实现的吗?

1496 篇文章 10 订阅
1494 篇文章 14 订阅

Hystrix介绍

Hystrix是一个用于处理分布式系统的延迟和容错的开源库,在分布式系统里,许多依赖不可避免地会调用失败,比如超时、异常等,Hystrix能保证在一个依赖出问题的情况下,不会导致整体服务失败,避免级联故障,以提高分布式系统的弹性。

“断路器”本身是一种开关装置,当某个服务单元发生故障之后,通过断路器的故障监控(类似熔断保险丝),向调用方返回一个符合预期的、可处理的备选响应(FallBack),而不长时间的等待或者抛出调用方法无法处理的异常,这样就保证了服务调用方的线程不会被长时间、不必要地占用,从而避免了故障在分布式系统中的蔓延,乃至雪崩。

github地址: https://github.com/Netflix/Hystrix

服务降级

所谓降级,就是当某个服务出现异常之后,服务器将不再被调用,此时服务端可以自己准备一个本地的fallback回调,返回一个缺省值。 这样做,虽然服务水平下降,但好歹可用,比直接挂掉要强,当然这也要看适合的业务场景。

可能出现服务降级的情况:

  1. 程序运行异常

  2. 服务超时

  3. 服务熔断触发服务降级

  4. 线程池/信号量打满也会导致服务降级

版本说明

Java : 1.8 Spring Boot : 2.1.5.RELEASE Spring Cloud: Greenwich.SR1

项目说明

eureka-server:eureka服务中心 feign-client :feign生产者 feign-client-intf:feign接口提供者 hystrix-fallback:hystrix降级demo

eureka-server 前面文章已经提供不再粘贴出来了

feign-client-intf:feign接口提供者

pom.xml

 
 

<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency> </dependencies> 1234567891011

server接口提供

 
 

@FeignClient("feign-client") public interface IService { @GetMapping("/sayHi") public String sayHi(); @PostMapping("/sayHi") public Friend sayHiPost(@RequestBody Friend friend); @GetMapping("/retry") public String retry(@RequestParam(name = "timeout") int timeout); @GetMapping("/error") public String error(); } 12345678910111213141516

Friend实体类

 
 

@Data public class Friend { private String name; private String port; } 12345678

feign-client :feign生产者

pom.xml

 
 

dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>com.imooc</groupId> <artifactId>feign-client-intf</artifactId> <version>${project.version}</version> </dependency> </dependencies> 1234567891011121314151617181920212223

application.properties

 
 

spring.application.name=feign-client server.port=40006 eureka.client.serviceUrl.defaultZone=http://localhost:20000/eureka/ 12345

Controller

 
 

@RestController public class Controller implements IService { Logger log = LoggerFactory.getLogger(Controller.class); @Value("${server.port}") private String port; @GetMapping("/sayHi2") public String sayHi2() { return "This is " + port; } @Override public String sayHi() { return "This is " + port; } @Override public Friend sayHiPost(@RequestBody Friend friend) { log.info("You are " + friend.getName()); friend.setPort(port); return friend; } @Override public String retry(@RequestParam(name = "timeout") int timeout) { System.out.println("timeout"+timeout); while (--timeout >= 0) { try { Thread.sleep(1000); } catch (InterruptedException e) { } } log.info("retry " + port); return port; } @Override public String error() { throw new RuntimeException("black sheep"); } } 1234567891011121314151617181920212223242526272829303132333435363738394041424344

FeignClientApplication启动类

 
 

@EnableDiscoveryClient @SpringBootApplication public class FeignClientApplication { public static void main(String[] args) { new SpringApplicationBuilder(FeignClientApplication.class) .web(WebApplicationType.SERVLET) .run(args); } } 1234567891011

hystrix-fallback:hystrix降级demo

编辑切换为居中

添加图片注释,不超过 140 字(可选)

pom.xml

 
 

dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>com.imooc</groupId> <artifactId>feign-client-intf</artifactId> <version>${project.version}</version> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-hystrix</artifactId> </dependency> </dependencies> 12345678910111213141516171819202122232425262728

application.properties

 
 

spring.application.name=hystrix-consumer server.port=50001 spring.main.allow-bean-definition-overriding=true eureka.client.serviceUrl.defaultZone=http://localhost:20000/eureka/ # 开启Feign下面的Hystrix功能 feign.hystrix.enabled=true # 是否开启服务降级 hystrix.command.default.fallback.enabled=true # 全局超时 hystrix.command.default.execution.timeout.enabled=true # 超时时间 hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=3000 # 超时以后终止线程 hystrix.command.default.execution.isolation.thread.interruptOnTimeout=true # 取消的时候终止线程 hystrix.command.default.execution.isolation.thread.interruptOnFutureCancel=true # hystrix.command.MyService#retry(int).execution.isolation.thread.timeoutInMilliseconds=3000 # 每台机器最大重试次数 feign-client.ribbon.MaxAutoRetries=0 # 可以再重试几台机器 feign-client.ribbon.MaxAutoRetriesNextServer=0 # 连接超时 feign-client.ribbon.ConnectTimeout=1000 # 业务处理超时 feign-client.ribbon.ReadTimeout=8000 # 在所有HTTP Method进行重试 feign-client.ribbon.OkToRetryOnAllOperations=false 1234567891011121314151617181920212223242526272829303132

Controller

 
 

@RestController public class Controller { @Autowired private MyService myService; @Autowired private RequestCacheService requestCacheService; @GetMapping("/fallback") public String fallback() { return myService.error(); } @GetMapping("/timeout") public String timeout(Integer timeout) { System.out.println(timeout); return myService.retry(timeout); } @GetMapping("/timeout2") @HystrixCommand( fallbackMethod = "timeoutFallback", commandProperties = { @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value="3000") } ) public String timeout2(Integer timeout) { return myService.retry(timeout); } public String timeoutFallback(Integer timeout) { return "success"; } @GetMapping("/cache") public Friend cache(String name) { @Cleanup HystrixRequestContext context = HystrixRequestContext.initializeContext(); Friend friend = requestCacheService.requestCache(name); friend = requestCacheService.requestCache(name); return friend; } } 12345678910111213141516171819202122232425262728293031323334353637383940414243444546

MyService

 
 

@FeignClient(name = "feign-client", fallback = Fallback.class) public interface MyService extends IService { } 1234

Fallback 降级处理类

 
 

@Slf4j @Component public class Fallback implements MyService { @Override //@HystrixCommand(fallbackMethod = "fallback2") public String error() { log.info("Fallback: I'm not a black sheep any more"); throw new RuntimeException("first fallback"); } @HystrixCommand(fallbackMethod = "fallback3") public String fallback2() { log.info("fallback again"); throw new RuntimeException("fallback again"); } public String fallback3() { log.info("fallback again and again"); return "success"; } @Override public String sayHi() { return null; } @Override public Friend sayHiPost(@RequestBody Friend friend) { return null; } @Override public String retry(@RequestParam(name = "timeout") int timeout) { return "You are late !"; } } 123456789101112131415161718192021222324252627282930313233343536373839

RequestCacheService Request Cache减压

 
 

@Slf4j @Service public class RequestCacheService { @Autowired private MyService service; @CacheResult @HystrixCommand(commandKey = "cacheKey") public Friend requestCache(@CacheKey String name) { log.info("request cache " + name); Friend friend = new Friend(); friend.setName(name); friend = service.sayHiPost(friend); log.info("after requesting cache " + name); return friend; } } 1234567891011121314151617181920

HystrixFallbackApplication启动类

 
 

@EnableDiscoveryClient @SpringBootApplication @EnableFeignClients @EnableCircuitBreaker public class HystrixFallbackApplication { public static void main(String[] args) throws NoSuchMethodException { new SpringApplicationBuilder(HystrixFallbackApplication.class) .web(WebApplicationType.SERVLET) .run(args); // System.out.println(Feign.configKey(MyService.class, // MyService.class.getMethod("retry", int.class))); } } 12345678910111213141516

测试

依次启动: eureka-server:eureka服务中心 feign-client :feign生产者 hystrix-fallback:hystrix降级demo

编辑切换为居中

添加图片注释,不超过 140 字(可选)

Fallback多级降级测试

测试步骤: 1.通过postman来调用hystrix-fallback fallback接口

编辑切换为居中

添加图片注释,不超过 140 字(可选)

2.然后通过feign来调用feign-client的error接口来获取一个异常看看能不能降级。

编辑切换为居中

添加图片注释,不超过 140 字(可选)

3.多级降级处理

编辑切换为居中

添加图片注释,不超过 140 字(可选)

postman 放回的结果,然后分析一下结果。

编辑切换为居中

添加图片注释,不超过 140 字(可选)

在feign-client当中 抛出了一个RuntimeException的错误。然后会被hystrix进行降级处理。

编辑切换为居中

添加图片注释,不超过 140 字(可选)

我们再去hystrix-fallback的控制台看看有没有被降级。

编辑切换为居中

添加图片注释,不超过 140 字(可选)

这三条输出对应的就是之前多级处理的打印的结果说明 多级降级是成功的。

Timeout降级测试

1.设置全局的超时时间 超过时间就会Timeout降级 这里我是设置的3s

编辑切换为居中

添加图片注释,不超过 140 字(可选)

2通过postman来调用hystrix-fallback timeout接口

编辑切换为居中

添加图片注释,不超过 140 字(可选)

3.然后通过feign来调用feign-client的retry接口让线程sleep相应的时间

编辑切换为居中

添加图片注释,不超过 140 字(可选)

4.如果没有超时就会retrun 出feign-clien端口号 超时了的话就会进入timeout降级处理类

编辑切换为居中

添加图片注释,不超过 140 字(可选)

5.先测试2s 没有超时的结果

编辑切换为居中

添加图片注释,不超过 140 字(可选)

6.先然后测试3s 超时的结果

编辑切换为居中

添加图片注释,不超过 140 字(可选)

Request Cache减压测试

1.通过postman来调用hystrix-fallback cache接口,然后接口里面连续调用了 两次 requestCacheService.requestCache(name); 如果打印两遍相同的log说明没有被缓存到本地,解压失败。 如果只打印一遍og说明有被缓存到本地,解压成功。

编辑切换为居中

添加图片注释,不超过 140 字(可选)

requestCacheService.requestCache

编辑切换为居中

添加图片注释,不超过 140 字(可选)

调用接口

只打印了一遍Log说明解压成功

以上有问题请指出来!交流学习

                                                资源获取:

大家点赞、收藏、关注、评论啦 、查看👇🏻👇🏻👇🏻微信公众号获取联系方式👇🏻👇🏻👇🏻

 精彩专栏推荐订阅:下方专栏👇🏻👇🏻👇🏻👇🏻

每天学四小时:Java+Spring+JVM+分布式高并发,架构师指日可待

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值