SpringCloud Hystrix介绍以及基于RestTemplate与Feign的改造
一、Hystrix介绍
Hystrix 是Netfix的一个开源的延迟和容错库,用于隔离访问远程系统、服务或者第三方库,防止服务级联失败,从而提升系统的可用性与容错性。Hystrix主要通过以下几点实现延迟和容错。
- 包裹请求:使用@HystrixCommand注解将接口进行包装成一个对象,对第三方系统或者外部依赖进行提供。并且包装的对象将单独运行在一个线程中。此处采用命令模式(设计模式)。
- 跳闸机制:当某个服务的错误率超过一定阈值时,Hystrix可以自动或手动跳闸,停止请求改服务一段时间。
- 资源隔离:Hystrix为每个依赖(依赖即接口,微服务中接口在其上游接口下即为上游接口的依赖)都维护了一个小型的线程池(或者信号量)。如果改线程池已满,发往该依赖的请求会被立即拒绝,而不是排队等待,从而加速失败判定。
- 监控:Hystrix可以近乎实施的监控运行指标和配置的变化,例如成功、失败、超时、以及拒绝的请求信息。
- 回退机制:当请求失败、超时、被拒绝,或当断路器打开时,执行回退逻辑(fallback)。回退逻辑由开发人员定义,例如可以返回一个缺省的返回值。
- 自我修复:断路器打开一段时间后,会自动进入一个“半开”状态。
二、基于RestTemplate调用的消费者工程改造
1,pom引入hystrix的依赖 (新版本的Eureka也支持Hystrix,jar包中包含了Hystrix的模块依赖)
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
2,在启动类上添加@EnableCircuitBreaker激活Hystrix
@SpringBootApplication
@EnableEurekaClient
@EnableCircuitBreaker
public class RestOrderApplication {
3,配置熔断触发的降级逻辑
在Controller中添加接口降级逻辑,该方法需要与被保护降级的方法参数返回值一致。
/*** 降级方法,需要和降级的方法入参和返回值一致* @param id* @return*/public CommonResult<Payment> getPaymentFallBack( Long id){System.out.println("触发了降级逻辑");return new CommonResult<>(400,"触发了FallBack降级逻辑。。。",null);}
4,在需要保护的接口上配置@HystrixCommand注解
在需要保护降级的方法上使用@HystrixCommand注解,并指定其失败时的降级函数。
/*** 使用注解配置熔断保护* @param id* @return*/@HystrixCommand(fallbackMethod = "getPaymentFallBack")@GetMapping("/consumer/product/get/{id}")public CommonResult<Payment> getPayment(@PathVariable("id") Long id){CommonResult<Payment> commonResult = restTemplate.getForObject("http://cloud-payment-service/payment/get/"+id,CommonResult.class);return commonResult;}
------- 本项目完整结构代码如下(本项目为消费者工程,注册中心使用的Eureka):--------
1.pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><parent><artifactId>SpringCloud</artifactId><groupId>com.xiaohui.springCloud</groupId><version>1.0-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><artifactId>hystrix_order_service_rest</artifactId><dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-hystrix</artifactId></dependency><dependency><groupId>com.xiaohui.springCloud</groupId><artifactId>cloud-api-common</artifactId><version>${project.version}</version></dependency><!-- Eureka 客户端 --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</artifactId></dependency><dependency><groupId>org.springframework.retry</groupId><artifactId>spring-retry</artifactId></dependency><!-- web依赖开始 --><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><!-- web依赖结束 --><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency></dependencies>
</project>
2,application.yml
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds 指定了触发降级时的超时时间
server:port: 80 #服务端口
spring:application:name: cloud-order-rest-service #服务名称
eureka:client:register-with-eureka: truefetch-registry: trueservice-url:defaultZone: http://eureka1.com:9000/eureka/instance:prefer-ip-address: true #使用ip进行注册instance-id: ${spring.cloud.client.ip-address}:${server.port} #向注册中心注册服务IDlease-renewal-interval-in-seconds: 5 #发送心跳间隔时间 秒lease-expiration-duration-in-seconds: 10 # 服务续约时间 10秒内没有发送心跳(宕机)hystrix:command:default:execution:isolation:thread:timeoutInMilliseconds: 1000
3,主启动类
package com.xiaohui.hystrix;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;@SpringBootApplication
@EnableEurekaClient
@EnableCircuitBreaker
public class RestOrderApplication {public static void main(String[] args) {SpringApplication.run(RestOrderApplication.class,args);}
}
4,配置类
package com.xiaohui.hystrix.config;import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;/**** 相当于 spring的 application.xml bean注解相当于 bean 标签*/
@Configuration
public class ApplicationContextConfig {@LoadBalanced@Beanpublic RestTemplate getRestTemplate(){return new RestTemplate();}
}
5,业务类(重点)
在Controller中
public CommonResult<Payment> getPaymentFallBack( Long id) 方法为 public CommonResult<Payment> getPayment(@PathVariable("id") Long id) 的降级方法。
public CommonResult<Payment> defaultFallBack() 方法为 该Controller的全局降级方法。
当方法指定了降级方法则会走方法指定的降级逻辑方法。没有指定的则走全局的降级方法。
package com.xiaohui.hystrix.controller;import com.netflix.hystrix.contrib.javanica.annotation.DefaultProperties;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.xiaohui.springcloud.entities.CommonResult;
import com.xiaohui.springcloud.entities.Payment;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;@RestController
@DefaultProperties(defaultFallback = "defaultFallBack")
public class OrderController {@Autowiredprivate RestTemplate restTemplate;/*** 使用注解配置熔断保护* @param id* @return*/@HystrixCommand(fallbackMethod = "getPaymentFallBack")@GetMapping("/consumer/product/get/{id}")public CommonResult<Payment> getPayment(@PathVariable("id") Long id){CommonResult<Payment> commonResult = restTemplate.getForObject("http://cloud-payment-service/payment/get/"+id,CommonResult.class);return commonResult;}@HystrixCommand@GetMapping("/consumer/product/get2/{id}")public CommonResult<Payment> getPayment2(@PathVariable("id") Long id){CommonResult<Payment> commonResult = restTemplate.getForObject("http://cloud-payment-service/payment/get/"+id,CommonResult.class);return commonResult;}/*** 降级方法,需要和降级的方法入参和返回值一致* @param id* @return*/public CommonResult<Payment> getPaymentFallBack( Long id){System.out.println("触发了降级逻辑");return new CommonResult<>(400,"触发了FallBack降级逻辑。。。",null);}/*** 统一降级方法不需要入参* @return*/public CommonResult<Payment> defaultFallBack(){System.out.println("触发了统一降级逻辑");return new CommonResult<>(400,"触发了defaultFallBack降级逻辑。。。",null);}}
三、基于Feign调用的消费者工程改造
1,依赖:由于Feign依赖中包含了Hystrix,已经对Hystrix有了支持,所以不需要在新引入依赖。
2,在配置文件中开启Hystrix。
feign.hystrix.enabled=ture
3,添加feignclient接口实现类,实现降级方法
@Component
public class ProductFeignClientFallBack implements ProductFeignClient {@Overridepublic CommonResult getPayment(Long id) {System.out.println("Feign 降级处理逻辑..");return new CommonResult(404,"Feign 降级处理逻辑..",null);}@Overridepublic CommonResult getPaymentTimeout() {System.out.println("Feign timeOut降级处理逻辑...");return new CommonResult(404,"Feign timeOut降级处理逻辑....",null);}
}
4,Feignclient接口中使用@FeignClient注解添加指定 fallback实现类。其中name为feign的配置为调用接口服务名。
@FeignClient(name="CLOUD-PAYMENT-SERVICE" ,fallback = ProductFeignClientFallBack.class)
public interface ProductFeignClient {@RequestMapping(value="/payment/get/{id}",method = RequestMethod.GET)CommonResult getPayment(@PathVariable("id") Long id);@GetMapping("/payment/get/timeout")CommonResult getPaymentTimeout();
}
Feign的项目完整文件目录如下:
1,pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><parent><artifactId>SpringCloud</artifactId><groupId>com.xiaohui.springCloud</groupId><version>1.0-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><artifactId>openfeign_order_service</artifactId><dependencies><dependency><groupId>com.xiaohui.springCloud</groupId><artifactId>cloud-api-common</artifactId><version>${project.version}</version></dependency><!-- springCloud 整合的openFeign --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId></dependency><!-- Eureka 客户端 --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</artifactId></dependency><dependency><groupId>org.springframework.retry</groupId><artifactId>spring-retry</artifactId></dependency><!-- web依赖开始 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- web依赖结束 --><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><!-- 健康检查监控 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-hystrix</artifactId></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId></dependency></dependencies>
</project>
2,application.yml
server:port: 9001spring:application:name: openfeign-order-serviceeureka:client:register-with-eureka: truefetch-registry: trueservice-url:defaultZone: http://eureka1.com:9000/eureka/instance:prefer-ip-address: true #使用ip进行注册instance-id: ${spring.cloud.client.ip-address}:${server.port} #向注册中心注册服务IDlease-renewal-interval-in-seconds: 5 #发送心跳间隔时间 秒lease-expiration-duration-in-seconds: 10 # 服务续约时间 10秒内没有发送心跳(宕机)#CLOUD-PAYMENT-SERVICE:
# ribbon:
# NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule#Feign 日志输出配置
feign:client:config:CLOUD-PAYMENT-SERVICE:loggerLevel: FULLconnectTimeout: 5000readTimeout: 5000#开启对hystrix 支持,默认falsehystrix:enabled: truelogging:level:com.xiaohui.springcloud.service.ProductFeignClient: debug
3,启动类(启动类可以不加@EnableCircuitBreaker注解)
package com.xiaohui.springcloud;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
import org.springframework.cloud.netflix.hystrix.dashboard.EnableHystrixDashboard;
import org.springframework.cloud.openfeign.EnableFeignClients;@SpringBootApplication
@EnableFeignClients
public class OrderApplication {public static void main(String[] args) {SpringApplication.run(OrderApplication.class,args);}
}
4,业务类
Feign接口类
package com.xiaohui.springcloud.service;import com.xiaohui.springcloud.entities.CommonResult;
import com.xiaohui.springcloud.service.impl.ProductFeignClientFallBack;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;@FeignClient(name="CLOUD-PAYMENT-SERVICE" ,fallback = ProductFeignClientFallBack.class)
public interface ProductFeignClient {@RequestMapping(value="/payment/get/{id}",method = RequestMethod.GET)CommonResult getPayment(@PathVariable("id") Long id);@GetMapping("/payment/get/timeout")CommonResult getPaymentTimeout();
}
Feign 接口降级实现类
package com.xiaohui.springcloud.service.impl;import com.xiaohui.springcloud.entities.CommonResult;
import com.xiaohui.springcloud.service.ProductFeignClient;
import org.springframework.stereotype.Component;@Component
public class ProductFeignClientFallBack implements ProductFeignClient {@Overridepublic CommonResult getPayment(Long id) {System.out.println("Feign 降级处理逻辑..");return new CommonResult(404,"Feign 降级处理逻辑..",null);}@Overridepublic CommonResult getPaymentTimeout() {System.out.println("Feign timeOut降级处理逻辑...");return new CommonResult(404,"Feign timeOut降级处理逻辑....",null);}
}
Controller类
package com.xiaohui.springcloud.controller;import com.xiaohui.springcloud.entities.CommonResult;
import com.xiaohui.springcloud.entities.Payment;
import com.xiaohui.springcloud.service.ProductFeignClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;@RestController
public class OrderController {@Autowiredprivate ProductFeignClient productFeignClient;@GetMapping("/consumer/payment/get/{id}")public CommonResult<Payment> getPayment(@PathVariable("id") Long id){return productFeignClient.getPayment(id);}@GetMapping("/consumer/payment/get/timeout")public CommonResult getPaymentTimeout(){return productFeignClient.getPaymentTimeout();}
}
只启动Eureka和消费者工程调用测试:根据现象可以看到没有对应的生产者方法时会执行实现的降级方法。
SpringCloud Hystrix介绍以及基于RestTemplate与Feign的改造相关推荐
- Nacos概述,下载与安装,初始化配置,服务注册应用,RestTemplate,Feign
Idea中启动Nacos 第一步:打开服务编辑配置,例如: 第二步:添加Shell Script,例如: 第三步:添加nacos相关信息,例如: Nacos概述 Nacos(DynamicNaming ...
- Spring Cloud Hystrix介绍
Hystrix 介绍 Hystrix [hɪst'rɪks],中文含义是豪猪,因其背上长满棘刺,从而拥有了自我保护的能力.SpringCloud Hystrix是Netflix开源的一款容错框架,具备 ...
- SpringCloud Hystrix熔断器
SpringCloud Hystrix熔断器 15.Hystrix熔断器:简介及作用 目标:理解Hystrix的作用 介绍:Hystrix,英文意思是豪猪,全身是刺,看起来就不好惹,是一种保护机制. ...
- SpringCloud-19-Spring Cloud Hystrix介绍和服务端降级
8 Hystrix:Spring Cloud服务熔断与降级组件 8.1 分布式系统面临的问题 复杂分布式体系结构中的应用程序往往由多个服务组成,这些服务之间相互依赖,依赖关系错综复杂,每个依赖关系在某 ...
- SpringCloud使用Sofa-lookout监控(基于Eureka)
本文介绍SpringCloud使用Sofa-lookout,基于Eureka服务发现. 1.前景 本文属于是前几篇文章的后续,其实一开始感觉这个没有什么必要写的,但是最近一个朋友问我关于这个的问题,所 ...
- SpringCloud系列之服务消费Ribbon和Feign区别
在业界,一般有两种微服务的实践方法:基于dubbo的微服务架构.基于Spring Cloud的微服务架构.从概念上来讲,Dubbo和Spring Cloud并不能放在一起对比,因为Dubbo仅仅是一个 ...
- 深入了解SpringCloud Hystrix
雪崩效应即在多个服务节点当中,如果有一个服务不可用而这个不可用的服务导致整个应用资源都耗在这里,进而影响整个系统的崩溃.在分布式环境中,不可避免地会出现雪崩效应.Hystrix是一个netflix实现 ...
- springcloud Hystrix Dashboard微服务监控
springcloud Hystrix Dashboard微服务监控简介 Hystrix监控 除了隔离依赖服务的调用以外,Hystrix还提供了近实时的监控,Hystrix会实时.累加地记录所有关于 ...
- springcloud hystrix实战(二)
我们前面介绍完了springcloud hystrix的相关作用,大家也有了一个认识,这个熔断器的作用这个就不在重复. 下面我们就接着进行代码实战,我们是接着之前的微服务的工程继续的,如果有什么不明白 ...
最新文章
- swift学习笔记之-析构过程
- python xpath语法-XPath语法和lxml模块(数据提取)
- 移动测试中游戏和应用的不同之处
- python Django数据库保存操作
- (一)梳理前端知识体系,搞定大厂必考面试题
- MySQL用户及权限管理
- 仿苹果涂鸦软件_这些iPhone自带软件,学会一个少装十几个APP,16G手机也够用
- 单元测试框架之Robolectric踩坑
- java 吃豆豆游戏背景底纹_java swing开发简单的大鱼吃豆子小游戏,可用于毕业设计(附详细设计文档)...
- ISO镜像安装WIN10到NVME固态硬盘,无法找到新加装的NVME硬盘(驱动器)
- ST-link无法下载—— “ access port fault. check the access port selection and ensure it fits the debugging
- PHP运行出现502是什么原因,php出现502错误怎么解决
- Fisher information解释和数学意义
- 将python脚本打包为exe可执行文件
- 计算机领域的所有SCI一区期刊,这是最顶级期刊了
- FS4052A是一个4.0-23V宽电压输入,2A充电电流单电池 同步降压锂离子电池充电器
- 前端开发:npm run serve和npm run dev的区别
- 50个Bootstrap扩展插件
- html5第九章上机1制作照片墙,\ HTML5开发项目实战:照片墙
- 推荐Bandicam(高清录像工具)