crm开发定制SpringCloud Feign整合Hystrix实现服务降级、熔断、hystrix、ribbon超时时间问题

了解

  • 支持Hystrix

  • Feigncrm开发定制是一个声明式的伪RPC的REST客户端,crm开发定制基于接口的注解方式,crm开发定制很方便客户端配置。

  • Spring Cloud集成和Eureka以在使用Feigncrm开发定制时提供负载均衡的http客户端。

  • crm开发定制基于开源框架Netflix实现了Spring Cloud Hystrix,crm开发定制该框架的目标在于通过crm开发定制控制哪些访问远程系统、服务等,crm开发定制从而对于网络延迟和故crm开发定制障提供更强大的容错能力。

crm开发定制服务熔断和降级的区别

  • 服务降级: crm开发定制当服务调用出现响应时间过长或者运行出差或者宕机,就会调用服务降级方法快速响应。

  • 服务熔断: 在一定时间内服务调用失败(报错、、宕机)达到一定次数,才会启动服务熔断,进而调用服务降级方法快速响应。

  • 可以理解为,服务降级是服务出现问题或超时后给予用户的一种响应方式,一种行为;

  • 而服务熔断则是一种服务的状态。

服务降级每次都会先调用原服务方法,调用失败才会执行服务降级方法;服务熔断状态会直接调用服务降级方法。

实现

先把我的boot和cloud版本贴上

<spring-boot.version>2.3.4.RELEASE</spring-boot.version><spring-cloud.version>Hoxton.SR6</spring-cloud.version>
  • 1
  • 2

引入依赖

<dependency>    <groupId>org.springframework.cloud</groupId>    <artifactId>spring-cloud-starter-openfeign</artifactId></dependency><dependency>    <groupId>org.springframework.cloud</groupId>    <artifactId>spring-cloud-starter-netflix-hystrix</artifactId></dependency>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

Feign客户端

暴露一个调用接口,调用时,执行feign远程调用webflux项目的服务

@RestController@RequestMapping("/bus")public class BusinessController {    @Resource    private ToWebFlux toWebFlux;        @RequestMapping("/helloflux")    public String helloflux() {        return toWebFlux.hello();    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

Feign远程调用接口,只实现一个简单的调用

远程调用webflux上的/api/hello接口

@FeignClient(value = "webflux", contextId = "webflux", fallbackFactory = ToWebFluxFallback.class)public interface ToWebFlux {    @RequestMapping("/api/hello")    String hello();}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • value: 指远程服务的名称
  • contextId: 相当于一个标识,避免注册到spring容器后,bean名称重复
  • fallbackFactory: 服务触发降级后执行哪个类的方法

Hystrix服务降级实现

实现 FallbackFactory<Feign客户端类泛型>,重写create()方法

由于我的Feign客户端只有一个接口(函数式接口),就直接采用lambda表达式了

返回一个服务降级的字样~

注意要把此Hystrix服务降级实现 反转到 spring容器里

@Componentpublic class ToWebFluxFallback implements FallbackFactory<ToWebFlux> {    @Override    public ToWebFlux create(Throwable cause) {        return () -> "服务降级了~";    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

启动类打开对Feign和Hystrix的支持

@SpringBootApplication@EnableDiscoveryClient // 服务注册@EnableFeignClients	// Feign支持@EnableHystrix		// Hystrix支持public class BusinessApplication {    public static void main(String[] args) {        SpringApplication.run(BusinessApplication.class, args);    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

支持Hystrix,无论是用 @EnableHystrix还是 @EnableCircuitBreaker都可以,@EnableHystrix是包含了@EnableCircuitBreaker,都能达到开启 Hystrix的作用。

配置文件,开启feign支持hystrix,默认关闭

feign.hystrix.enabled开启feign支持hystrix,在Spring Cloud的E版本之后,默认是关闭的。

# 开启feign支持hystrix,默认关闭feign:  hystrix:    enabled: true
  • 1
  • 2
  • 3
  • 4

Feign服务器端 (也就是服务的提供者)

webflux服务提供者有一个/api/hello的接口

@RestController@RequestMapping("/api")public class HelloController {    @RequestMapping("/hello")    public String hello () {        return "hello webflux";    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

启动

我们只启动一个 Feign客户端的项目,先不启动Feign服务器的,模拟一下直接服务降级

当Feign客户端启动,但是Feign服务端没启动时,Feign远程调用时无需等待,由于服务是熔断状态,直接给我们一个友好响应提示。

现在,我启动 Feign客户端和Feign的服务端,来试一下

可以看到,服务正常调用,并且返回了数据。

扩展

模拟调用超时

如果不配置hystrix和ribbon的超时时间,那么Hystrix与ribbon的默认请求超时时间都是1秒

模拟超时,我在服务端将线程睡眠2秒钟

@RestController@RequestMapping("/api")public class HelloController {    @RequestMapping("/hello")    public String hello () throws InterruptedException {        Thread.sleep(2000); // 模拟超时        return "hello webflux";    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

访问一下


可看到触发了 服务降级~

也就是说,远程调用在一定的时间内,如果没有返回结果,就触发服务降级,不让用户继续等待。

在平时开发中,要注意到这些问题的存在。。




设置调用超时时间

为了加深理解,在设置调用超时时间之前我们先回顾一下,什么是hystrix、ribbon

什么是 ribbon?

Ribbon是Netflix发布的负载均衡器,它有助于控制HTTP和TCP的客户端的行为。为Ribbon配置服务提供者地址后,Ribbon就可基于某种负载均衡算法,自动地帮助服务消费者去请求。Ribbon默认为我们提供了很多负载均衡算法,例如轮询、随机等。当然,我们也可为Ribbon实现自定义的负载均衡算法。

也就是负载均衡,一般集群中用到,根据算法去请求到某一个服务上。

什么是hystrix?

在一个分布式系统里,许多依赖不可避免的会调用失败,比如超时、异常等,如何能够保证在一个依赖出问题的情况下,不会导致整体服务失败,这个就是Hystrix需要做的事情。Hystrix提供了熔断、隔离、Fallback、cache、监控等功能,能够在一个、或多个依赖同时出现问题时保证系统依然可用。

服务降级、熔断,直接给予用户反馈,不让其等待。

  • 假如ribbon超过调用时间,比如我们可以进行retry重试或去连接集群里的其他服务
  • hystrix超过超时时间,实行降级处理操作,给予用户反馈消息

Ribbon超时与Hystrix超时问题,为了确保Ribbon重试的时候不被熔断,我们就需要让Hystrix的超时时间大于Ribbon的超时时间,否则Hystrix命令超时后,该命令直接熔断,重试机制就没有任何意义了。

以下,如果只设置了 hystrix超时时间

feign:   hystrix:     enabled: true # 设置hystrix超时时间hystrix:   command:     default:       execution:         isolation:           thread:             timeoutInMilliseconds: 5000
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

设置后,发现无效。。。同样触发了降级操作。。

因为feign 也有一个超时时间的设置,当然feign底层是ribbon的封装,所以直接配置ribbon,ribbon默认超时也是1秒

配置ribbon超时时间

建议配置Hystrix的超时时间要大于ribbon的超时时间,否则会在接口调用还未完成的时候直接进入回调方法

一般规则

hystrix的超时时间=(1 + MaxAutoRetries + MaxAutoRetriesNextServer) * ReadTimeout 比较好,具体看需求

feign:   hystrix:     enabled: true # hystrix超时时间配置 (如果不配置的话默认是1000毫秒超时)hystrix:   command:     default:       execution:         isolation:           thread:             timeoutInMilliseconds: 15000            # ribbon超时时间配置 (如果不配置的话默认是1000毫秒超时)ribbon:      ReadTimeout: 10000      ConnectTimeout: 10000
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

配置后,再次尝试

已经可以了,模拟线程睡眠2s,超时时间ribbon设置为10s,hystrix设置为15s完全够用,后面根据自己的项目是实际情况去设置即可~

网站建设定制开发 软件系统开发定制 定制软件开发 软件开发定制 定制app开发 app开发定制 app开发定制公司 电商商城定制开发 定制小程序开发 定制开发小程序 客户管理系统开发定制 定制网站 定制开发 crm开发定制 开发公司 小程序开发定制 定制软件 收款定制开发 企业网站定制开发 定制化开发 android系统定制开发 定制小程序开发费用 定制设计 专注app软件定制开发 软件开发定制定制 知名网站建设定制 软件定制开发供应商 应用系统定制开发 软件系统定制开发 企业管理系统定制开发 系统定制开发