Hytrix consumer throws timed-out and no fallback available exception

2.1k Views Asked by At

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.

0

There are 0 best solutions below