前提:
阅读本文前请先参考《SpringCloud微服务服务间调用之OpenFeign介绍(一) 》
问题由来
使用Feign可以完成服务间调用,但是总存在一种情况:服务提供方的服务特别慢,但是服务提供方是正常的运行,如果我们自定义设置timeou,就出现feign.RetryableException: Read timed out executing GET http://user-service/v1/usersWithSleep/2?sleepTimeMillis=6000 异常, 导致无法继续工作
那么如何设置timeout?
解决办法
官方文档:
1, https://github.com/Netflix/ribbon
2,https://cloud.spring.io/spring-cloud-static/spring-cloud-netflix/2.0.2.RELEASE/single/spring-cloud-netflix.html#spring-cloud-ribbon
3,https://github.com/Netflix/ribbon/wiki/Programmers-Guide
完完整代码这这里, user-servcie, feignusercommodity-service, 欢迎加星,fork。
主要使用consul 1.2.0, Spring Boot 2.0.1, Spring Cloud Finchley.RELEASE。
从文档2可以看到 “ Feign already uses Ribbon, so, if you use @FeignClient, this section also applies.”
配置文件application.properties中设置ribbon的timeout
ribbon.ConnectTimeout=30000
ribbon.ReadTimeout=7000
代码简要说明,user-servcie有个接口A可以根据userId查询用户,但是sleep之后才返回,sleep由调用方提供(我的示例代码只是为了演示timeout效果,实际中有的接口可能需要查询数据库并对查询结果进行各种转换导致接口比较慢)
feignusercommodity-service服务会调用user-servcie的接口A,当你传入的sleep较小时,可以正常返回,但是当sleep较大时,因为ribbon.ReadTimeout限制就会出现feign.RetryableException: Read timed out executing GET http://user-service/v1/usersWithSleep/2?sleepTimeMillis={yourSleepTime}
效果截图
第一张截图
user-server服务工作正常,http://localhost:7001/v1/usersWithSleep/2?sleepTimeMillis=6000一直都能返回数据,就是等待时间较长,
当我们没有设置ribbon.ReadTimeout=7000时,调用feignusercommodity-service的http://localhost:7010/my/usersWithSleep/2?sleepTimeMillis=6000出现异常,如下图
第二张截图
当我们在feignusercommodity-service的配置文件中设置ribbon.ReadTimeout=7000后,调用feignusercommodity-service的http://localhost:7010/my/usersWithSleep/2?sleepTimeMillis=6000正常,如下图
第二张截图
当我们在feignusercommodity-service的配置文件中设置ribbon.ReadTimeout=7000后,调用feignusercommodity-service的http://localhost:7010/my/usersWithSleep/2?sleepTimeMillis=7001出现异常,如下图