Hytrix 消费者抛出超时且无回退可用异常

发布于 2025-01-11 07:20:36 字数 4547 浏览 0 评论 0原文

我正在尝试测试消费者和提供商服务的 hytrix 超时回退策略。
依赖版本:

spring-cloud-starter-openfeign = 2.2.1.RELEASE
spring-cloud-starter-netflix-hystrix = 2.2.1.RELEASE

我将 @HystrixCommand 放入消费者的控制器方法,其超时阈值设置为 3 秒,并将消费者的服务类绑定到提供者的应用程序名称。
在提供者的服务类中,我将 @HystrixCommand 放入其服务方法之一,其超时阈值是 5 秒,比消费者的超时阈值要长。
我在提供者的服务方法中使用了路径变量来设置睡眠时间,这样我就不必每次都修改并重新启动。
代码如下:

  1. 消费者
  • application.yml
server:
  port: 80

eureka:
  client:
    register-with-eureka: false
    service-url:
      defaultZone: http://eureka7001.com:7001/eureka/

feign:
  hystrix:
    enabled: true
  • 控制器类:
public class OrderHystirxController {
    @Resource
    private PaymentHystrixService paymentHystrixService;

    @GetMapping("/consumer/payment/hystrix/ok/{id}")
    public String paymentInfo_OK(@PathVariable("id") Integer id) {
        return paymentHystrixService.paymentInfo_OK(id);
    }

    @GetMapping("/consumer/payment/hystrix/timeout/{id}")
    @HystrixCommand(fallbackMethod = "paymentTimeOutFallbackMethod", commandProperties = {
            @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "3000")
    })
    public String paymentInfo_TimeOut(@PathVariable("id") Integer id) {
        String result = paymentHystrixService.paymentInfo_TimeOut(id);
        return result;
    }

    // fallback method
    public String paymentTimeOutFallbackMethod(@PathVariable("id") Integer id) {
        return "Client Timeout";
    }
  • 服务接口:
@Component
@FeignClient(value = "CLOUD-PROVIDER-HYSTRIX-PAYMENT")
public interface PaymentHystrixService
{
    @GetMapping("/payment/hystrix/ok/{id}")
    String paymentInfo_OK(@PathVariable("id") Integer id);

    @GetMapping("/payment/hystrix/timeout/{id}")
    String paymentInfo_TimeOut(@PathVariable("id") Integer id);
}
  1. 提供者
  • application.yml
server:
  port: 8001

spring:
  application:
    name: cloud-provider-hystrix-payment

eureka:
  client:
    register-with-eureka: true
    fetch-registry: true
    service-url:
      defaultZone: http://eureka7001.com:7001/eureka
  • 控制器
@RestController
public class PaymentController
{
    @Autowired
    private PaymentService paymentService;

    @GetMapping("/payment/hystrix/ok/{id}")
    public String paymentInfo_OK(@PathVariable("id") Integer id)
    {
        String result = paymentService.paymentInfo_OK(id);
        System.out.println("****result: "+result);
        return result;
    }

    @GetMapping("/payment/hystrix/timeout/{id}")
    public String paymentInfo_TimeOut(@PathVariable("id") Integer id) throws InterruptedException
    {
        String result = paymentService.paymentInfo_TimeOut(id);
        System.out.println("****result: "+result);
        return result;
    }
}
  • 服务
@Service
public class PaymentService {
    public String paymentInfo_OK(Integer id) {
        return "线程池:" + Thread.currentThread().getName() + " paymentInfo_OK,id: " + id;
    }

    @HystrixCommand(fallbackMethod = "paymentInfo_TimeOutHandler", commandProperties = {
            @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "5000")
    })
    public String paymentInfo_TimeOut(Integer id) {
        long outTime = (long) id;
        try {
            TimeUnit.SECONDS.sleep(outTime);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        return "线程池:" + Thread.currentThread().getName() + " paymentInfo_TimeOut,id: " + id + "  耗时: " + outTime;
    }

    // fallback method
    public String paymentInfo_TimeOutHandler(Integer id) {
        return "Server Timeout:" + "\t当前线程池名字" + Thread.currentThread().getName();
    }
}

当直接通过提供者的 url 访问时,一切都按预期进行。
但是当通过消费者的 url "/consumer/ payment/hystrix/timeout/{id}" 访问时,它并没有按预期进行。
我认为应该是这样的:

  1. id(timeout) 设置为低于 3,不会发生超时
  2. id(timeout) 设置为超过 3,消费者会超时

但发生的情况是:

  1. id(timeout) 设置为 0,不会发生超时
  2. id(timeout) ) 设置为 1 或以上,消费者超时

如果我尝试捕获消费者的 paymentInfo_TimeOut 方法,它会打印:

com.netflix.hystrix.exception.HystrixRuntimeException: PaymentHystrixService#paymentInfo_TimeOut(Integer) timed-out and no fallback available.

我是否配置了 hystrix 错误?
需要帮助并提前致谢。

I'm trying to test hytrix timeout fallback strategies for both consumer and provider services.
dependency versions:

spring-cloud-starter-openfeign = 2.2.1.RELEASE
spring-cloud-starter-netflix-hystrix = 2.2.1.RELEASE

I put a @HystrixCommand to a consumer's controller method whose timeout threshold is set to 3s, and bind the consumer's service class to the provider's app name.
In the provider's service class, I put a @HystrixCommand to one of its service method whose timeout threshold is 5s, which is longer than that of the consumer's.
I made use of the path variable to set the sleep time in the provider's service method, so I don't have to modify and restart everytime.
Here is the code:

  1. consumer
  • application.yml
server:
  port: 80

eureka:
  client:
    register-with-eureka: false
    service-url:
      defaultZone: http://eureka7001.com:7001/eureka/

feign:
  hystrix:
    enabled: true
  • controller class:
public class OrderHystirxController {
    @Resource
    private PaymentHystrixService paymentHystrixService;

    @GetMapping("/consumer/payment/hystrix/ok/{id}")
    public String paymentInfo_OK(@PathVariable("id") Integer id) {
        return paymentHystrixService.paymentInfo_OK(id);
    }

    @GetMapping("/consumer/payment/hystrix/timeout/{id}")
    @HystrixCommand(fallbackMethod = "paymentTimeOutFallbackMethod", commandProperties = {
            @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "3000")
    })
    public String paymentInfo_TimeOut(@PathVariable("id") Integer id) {
        String result = paymentHystrixService.paymentInfo_TimeOut(id);
        return result;
    }

    // fallback method
    public String paymentTimeOutFallbackMethod(@PathVariable("id") Integer id) {
        return "Client Timeout";
    }
  • service interface:
@Component
@FeignClient(value = "CLOUD-PROVIDER-HYSTRIX-PAYMENT")
public interface PaymentHystrixService
{
    @GetMapping("/payment/hystrix/ok/{id}")
    String paymentInfo_OK(@PathVariable("id") Integer id);

    @GetMapping("/payment/hystrix/timeout/{id}")
    String paymentInfo_TimeOut(@PathVariable("id") Integer id);
}
  1. provider
  • application.yml
server:
  port: 8001

spring:
  application:
    name: cloud-provider-hystrix-payment

eureka:
  client:
    register-with-eureka: true
    fetch-registry: true
    service-url:
      defaultZone: http://eureka7001.com:7001/eureka
  • controller
@RestController
public class PaymentController
{
    @Autowired
    private PaymentService paymentService;

    @GetMapping("/payment/hystrix/ok/{id}")
    public String paymentInfo_OK(@PathVariable("id") Integer id)
    {
        String result = paymentService.paymentInfo_OK(id);
        System.out.println("****result: "+result);
        return result;
    }

    @GetMapping("/payment/hystrix/timeout/{id}")
    public String paymentInfo_TimeOut(@PathVariable("id") Integer id) throws InterruptedException
    {
        String result = paymentService.paymentInfo_TimeOut(id);
        System.out.println("****result: "+result);
        return result;
    }
}
  • service
@Service
public class PaymentService {
    public String paymentInfo_OK(Integer id) {
        return "线程池:" + Thread.currentThread().getName() + " paymentInfo_OK,id: " + id;
    }

    @HystrixCommand(fallbackMethod = "paymentInfo_TimeOutHandler", commandProperties = {
            @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "5000")
    })
    public String paymentInfo_TimeOut(Integer id) {
        long outTime = (long) id;
        try {
            TimeUnit.SECONDS.sleep(outTime);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        return "线程池:" + Thread.currentThread().getName() + " paymentInfo_TimeOut,id: " + id + "  耗时: " + outTime;
    }

    // fallback method
    public String paymentInfo_TimeOutHandler(Integer id) {
        return "Server Timeout:" + "\t当前线程池名字" + Thread.currentThread().getName();
    }
}

When accessed directly via provider's urls, everything went as expected.
But when accessed via consumer's url "/consumer/payment/hystrix/timeout/{id}", it didn't go as expected.
I thought it should be like:

  1. id(timeout) set to below 3, no timeout occurs
  2. id(timeout) set to over 3, consumer timeout occurs

But what happened is:

  1. id(timeout) set to 0, no timeout occurs
  2. id(timeout) set to 1 or above, consumer timeout occurs

If I try-catch the paymentInfo_TimeOut method of the consumer, it prints:

com.netflix.hystrix.exception.HystrixRuntimeException: PaymentHystrixService#paymentInfo_TimeOut(Integer) timed-out and no fallback available.

Did I configure hystrix wrong?
Help needed and thanks in advance.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文