Hytrix 消费者抛出超时且无回退可用异常
我正在尝试测试消费者和提供商服务的 hytrix 超时回退策略。
依赖版本:
spring-cloud-starter-openfeign = 2.2.1.RELEASE
spring-cloud-starter-netflix-hystrix = 2.2.1.RELEASE
我将 @HystrixCommand 放入消费者的控制器方法,其超时阈值设置为 3 秒,并将消费者的服务类绑定到提供者的应用程序名称。
在提供者的服务类中,我将 @HystrixCommand 放入其服务方法之一,其超时阈值是 5 秒,比消费者的超时阈值要长。
我在提供者的服务方法中使用了路径变量来设置睡眠时间,这样我就不必每次都修改并重新启动。
代码如下:
- 消费者
- 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);
}
- 提供者
- 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}"
访问时,它并没有按预期进行。
我认为应该是这样的:
- id(timeout) 设置为低于 3,不会发生超时
- id(timeout) 设置为超过 3,消费者会超时
但发生的情况是:
- id(timeout) 设置为 0,不会发生超时
- 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:
- 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);
}
- 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:
- id(timeout) set to below 3, no timeout occurs
- id(timeout) set to over 3, consumer timeout occurs
But what happened is:
- id(timeout) set to 0, no timeout occurs
- 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论