SpringCloud的超时配置和Hystrix的作用

目录

一、SpringCloud超时配置参数

1.1 ribbon配置参数

1.2 hystrix配置参数

1.3 测试代码

二、对比各个超时时间

2.1 测试数据

2.2 测试分析

三、Hystrix的作用


一、SpringCloud超时配置参数

1.1 ribbon配置参数

# ribbon配置
ribbon:
  OkToRetryOnAllOperations: false # 所有请求重试,默认false
  ReadTimeout: 3000               # 负载均衡超时时间,默认值5000ms
  ConnectTimeout: 1000            # 请求连接的超时时间,默认值2000ms
  MaxAutoRetries: 0               # 当前实例的重试次数,默认0
  MaxAutoRetriesNextServer: 1     # 切换实例的重试次数,默认1

1.2 hystrix配置参数

# hystrix开启
feign:
  hystrix:
    enabled: true
hystrix:
  command:
    default:  # default全局有效,service id指定应用有效
      execution:
        timeout:
          # true则超时根据熔断超时,false则ribbon控制
          enabled: true
        isolation:
          thread:
            timeoutInMilliseconds: 1500 # 断路器超时时间,默认1000ms

1.3 测试代码

这里有两个服务instance-demo、instance-test,instance-demo通过feign调用instance-test,以下是两个服务的相关代码。

a. instance-demo

package com.common.instance.demo.controller;

import com.common.instance.demo.core.Response;
import com.common.instance.demo.feign.FeignMongoDbService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;

/**
 * @description Hystrix测试
 * @author TCM
 * @version 1.0
 * @date 2021/3/23 22:21
 **/
@RestController
@RequestMapping("/feign/hystrix")
@Api(tags = "Hystrix测试")
public class FeignHystrixController {

    @Resource
    private FeignMongoDbService feignMongoDbService;

    @GetMapping("/timeOut")
    @ApiOperation("Hystrix超时测试")
    public Response<String> timeOut(int mills) {
        return feignMongoDbService.timeOut(mills);
    }


}
package com.common.instance.demo.feign;

import com.common.instance.demo.core.Response;
import com.common.instance.demo.entity.OverScreenJob;
import com.common.instance.demo.feign.fallback.HystrixServiceFallBack;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;

import java.util.List;

/**
 * @description feign调用mongodb
 * @author tcm
 * @version 1.0.0
 * @date 2021/1/15 16:49
 **/
@FeignClient(name = "instance-test", fallback = HystrixServiceFallBack.class)
public interface FeignMongoDbService {

    @PostMapping(value = "instance-test/test/mongodb/listAll")
    Response<List<OverScreenJob>> listAll();

    @GetMapping(value = "instance-test/hystrix/timeOut")
    Response<String> timeOut(@RequestParam(value = "mills") int mills);

}
package com.common.instance.demo.feign.fallback;

import com.common.instance.demo.core.Response;
import com.common.instance.demo.entity.OverScreenJob;
import com.common.instance.demo.feign.FeignMongoDbService;
import org.springframework.stereotype.Component;

import java.util.List;

/**
 * @description 调用feign熔断
 * @author TCM
 * @version 1.0
 * @date 2021/3/24 19:59
 **/
@Component
public class HystrixServiceFallBack implements FeignMongoDbService {

    @Override
    public Response<List<OverScreenJob>> listAll() {
        return null;
    }

    @Override
    public Response<String> timeOut(int mills) {
        return Response.success("进入熔断");
    }

}

b instance-test

package com.common.instance.test.controller;

import com.common.instance.test.core.Response;
import com.log.util.LogUtil;
import io.swagger.annotations.Api;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @description Hystrix测试
 * @author TCM
 * @version 1.0
 * @date 2021/3/23 22:01
 **/
@RestController
@RequestMapping("/hystrix")
@Api(tags = "Hystrix测试")
public class HystrixController {

    @Value("${spring.cloud.client.ip-address}")
    private String ipAddress;

    /**
     * 测试超时重试机制
     * @param mills 超时设置
     * @return
     */
    @GetMapping("/timeOut")
    public Response<String> timeOut(int mills) {
        LogUtil.info(String.format("client服务-%s [timeOut方法]收到请求,阻塞%sms", ipAddress, mills));
        try {
            Thread.sleep(mills);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return Response.success(String.format("client服务-%s 请求ok!!!", ipAddress));
    }

}

 

二、对比各个超时时间

本章节,根据配置参数,以表格的形式列出测试表格并分析。

2.1 测试数据

 

样例配置参数传值/ms结果是否熔断
test1hystrix:
  command:
    default:  # default全局有效,service id指定应用有效
      execution:
        timeout:
          # true则超时根据熔断超时,false则ribbon控制
          enabled: true
        isolation:
          thread:
           
timeoutInMilliseconds: 5000 # 断路器超时时间,默认1000ms
# ribbon配置
ribbon:
  OkToRetryOnAllOperations: false     # 所有请求重试,默认false
 
ReadTimeout: 1000                          # 负载均衡超时时间,默认值5000ms
  ConnectTimeout: 3000                     # 请求连接的超时时间,默认值2000ms

  MaxAutoRetries: 0                           # 当前实例的重试次数,默认0
  MaxAutoRetriesNextServer: 1          # 切换实例的重试次数,默认1
900client服务-192.168.1.3 请求ok!!!NO
1200进入熔断YES
2000进入熔断YES
4000进入熔断YES
6000进入熔断YES
test2hystrix:
  command:
    default:  # default全局有效,service id指定应用有效
      execution:
        timeout:
          # true则超时根据熔断超时,false则ribbon控制
          enabled: true
        isolation:
          thread:
            timeoutInMilliseconds: 900 # 断路器超时时间,默认1000ms
# ribbon配置
ribbon:
  OkToRetryOnAllOperations: false     # 所有请求重试,默认false
 
ReadTimeout: 1000                          # 负载均衡超时时间,默认值5000ms
  ConnectTimeout: 3000                     # 请求连接的超时时间,默认值2000ms

  MaxAutoRetries: 0                           # 当前实例的重试次数,默认0
  MaxAutoRetriesNextServer: 1          # 切换实例的重试次数,默认1
600client服务-192.168.1.3 请求ok!!!NO
800client服务-192.168.1.3 请求ok!!!NO
900进入熔断YES
1200进入熔断YES
2000进入熔断YES
test3hystrix:
  command:
    default:  # default全局有效,service id指定应用有效
      execution:
        timeout:
          # true则超时根据熔断超时,false则ribbon控制
          enabled: true
        isolation:
          thread:
            timeoutInMilliseconds: 5000 # 断路器超时时间,默认1000ms
# ribbon配置
ribbon:
  OkToRetryOnAllOperations: false     # 所有请求重试,默认false

  ReadTimeout: 3000                          # 负载均衡超时时间,默认值5000ms
  ConnectTimeout: 1000                     # 请求连接的超时时间,默认值2000ms

  MaxAutoRetries: 0                           # 当前实例的重试次数,默认0
  MaxAutoRetriesNextServer: 1          # 切换实例的重试次数,默认1
900client服务-192.168.1.3 请求ok!!!NO
1200client服务-192.168.1.4 请求ok!!!NO
2000client服务-192.168.1.5 请求ok!!!NO
4000进入熔断YES
6000进入熔断YES
test4hystrix:
  command:
    default:  # default全局有效,service id指定应用有效
      execution:
        timeout:
          # true则超时根据熔断超时,false则ribbon控制
          enabled: true
        isolation:
          thread:
           
timeoutInMilliseconds: 1500 # 断路器超时时间,默认1000ms
# ribbon配置
ribbon:
  OkToRetryOnAllOperations: false     # 所有请求重试,默认false

  ReadTimeout: 3000                          # 负载均衡超时时间,默认值5000ms
  ConnectTimeout: 1000                     # 请求连接的超时时间,默认值2000ms

  MaxAutoRetries: 0                           # 当前实例的重试次数,默认0
  MaxAutoRetriesNextServer: 1          # 切换实例的重试次数,默认1
900client服务-192.168.1.3 请求ok!!!NO
1200client服务-192.168.1.4 请求ok!!!NO
1600进入熔断YES
2000进入熔断YES
4000进入熔断YES
test5hystrix:
  command:
    default:  # default全局有效,service id指定应用有效
      execution:
        timeout:
          # true则超时根据熔断超时,false则ribbon控制
          enabled: false
        isolation:
          thread:
            timeoutInMilliseconds: 5000 # 断路器超时时间,默认1000ms
# ribbon配置
ribbon:
  OkToRetryOnAllOperations: false     # 所有请求重试,默认false

  ReadTimeout: 2500                          # 负载均衡超时时间,默认值5000ms
  ConnectTimeout: 1000                     # 请求连接的超时时间,默认值2000ms

  MaxAutoRetries: 0                           # 当前实例的重试次数,默认0
  MaxAutoRetriesNextServer: 1          # 切换实例的重试次数,默认1
900client服务-192.168.1.3 请求ok!!!NO
1200client服务-192.168.1.4 请求ok!!!NO
2400client服务-192.168.1.5 请求ok!!!NO
2600进入熔断YES
4000进入熔断YES

 

2.2 测试分析

a.test1与test2对比:hystrix.command.default.execution.timeout.enabled=true时, timeoutInMilliseconds与ribbon.ReadTimeout起作用,谁值小谁其作用;

b.test1与test3对比:hystrix.command.default.execution.timeout.enabled=true时, ConnectTimeout不起作用;timeoutInMilliseconds与ribbon.ReadTimeout起作用,谁值小谁其作用;

c.test1与test5对比:hystrix.command.default.execution.timeout.enabled=false时,ConnectTimeout起作用,ReadTimeout > ConnectTimeout。

以上测试结果,是可以理解的。ribbon负责一个服务多个实例之间的切换,到达多实例负载均衡;而Hystrix是ribbon负载均衡后,确定的某一个实例来处理请求。从层级上说,先有ribbon后有hystrix。所以hystrix.command.default.execution.timeout.enabled=false(即Hystrix超时没有开启),这样ribbon超时配置就其作用了。与此同时,ReadTimeout > ConnectTimeout原因是可以切换实例重试。

hystrix.command.default.execution.timeout.enabled=true(即Hystrix超时开启),这样ribbon和hystrix共同起作用,但是谁的值小谁熔断。

三、Hystrix的作用

如上图所示,假如每秒有10000个请求订单服务,每个请求都要通过feign调用积分、仓储、库存服务。由于积分服务网络慢或宕机,这样所有请求都卡在积分服务,那么订单服务也就卡住了,这就是微服务中的服务雪崩问题。此时Hystrix作用就来了,因积分服务不能即时响应导致了超出配置的超时时间,这样feign调用就会发生熔断,返回对应的fallback处理,从而不影响接下来的流程,整个订单服务也不会因为积分服务的异常而卡住。

由上图可知,调用积分、仓储、库存服务的订单服务,都会为每个服务开一个线程池,独立处理各自的服务,还不影响其他服务的调用,进行服务的隔离作用。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值