假设现在有这么一个工程 mall4cloud,它有两个模块,order-openfeign、user。
order-openfeign 通过 feign 调用 user。
uer 对外提供服务:
@RestController
@RequestMapping("/user")
public class UserController {
@RequestMapping("/findUserName/{id}")
public String findUserName(@PathVariable String id) {
try {
// 模拟处理超时
Thread.sleep(6000);
} catch (Exception ignored) {
}
return "小王";
}
}
order-openfeign 调用 user:
@FeignClient(value = "user-service", path = "/user")
public interface UserFeignService {
@RequestMapping("/findUserName/{id}")
String findUserName(@PathVariable("id") String id);
}
----------------------------------------------------
@RestController
@RequestMapping("/order")
public class OrderController {
@Autowired
private UserFeignService userFeignService;
@RequestMapping("/placeOrderTimeout/{userId}")
public String placeOrderTimeout(@PathVariable String userId) {
String username = userFeignService.findUserName(userId);
return "用户[" + username + "]下单成功!";
}
}
一、超时配置
1.1、配置参数
OpenFeign 使用两个超时参数:
- connectTimeout
定义:connectTimeout 指的是客户端尝试与服务器建立连接时允许消耗的最大时间。若在该时间内无法成功建立连接,就会抛出连接超时异常。
作用场景:它主要用于处理网络连接阶段可能出现的问题,像服务器未启动、网络故障、防火墙阻止等情况。设置合理的连接超时时间能够避免客户端长时间处于等待连接的状态。
- readTimeout
定义:readTimeout 是指客户端在与服务器成功建立连接后,从服务器读取数据时允许的最长时间。若在该时间内无法完成数据读取,就会抛出读取超时异常。
作用场景:它主要用于处理数据传输阶段可能出现的问题,例如服务器响应缓慢、网络拥塞、数据量过大等情况。设置合理的读取超时时间能够避免客户端长时间等待服务器响应。
- 总结
发生阶段不同:connectTimeout 发生在网络连接阶段,而 readTimeout 发生在连接建立后的数据读取阶段。
处理问题不同:connectTimeout 主要处理连接失败的问题,readTimeout 主要处理数据读取缓慢或中断的问题。
设置目的不同:合理设置 connectTimeout 可避免客户端长时间等待连接,合理设置 readTimeout 可避免客户端长时间等待服务器响应。
1.2、配置方式
- JavaBean 配置方式
- yml 配置方式
二、yml 配置方式
2.1、order-openfeign yml 配置
feign:
client:
config:
default: # 全局生效
logger-level: BASIC
user-service: # 服务名
logger-level: FULL
connect-timeout: 3000 # 连接超时时间
read-timeout: 5000 # 请求处理超时时间
注意!
不同版本的 springcloud 配置会有不同。我的版本是
<spring.cloud.version>2021.0.5</spring.cloud.version>
2.2、调用测试
浏览器调用 http://127.0.0.1:8011/order/placeOrderTimeout/1
order-openfeign 控制台报:
三、JavaBean 配置方式
去掉 yml 中的配置。
3.1、新建一个超时配置类
// 注意这里不能 @Configuration
public class FeignTimeoutConfig {
@Bean
public Request.Options options() {
// Options 的第一个参数是连接的超时时间(ms)
// 第二个参数是请求处理的超时时间(ms)
return new Request.Options(3000, 5000);
}
}
3.2、Feign 客户端 @FeignClient 注解 configuration 属性引用配置类
@FeignClient(value = "user-service", path = "/user", configuration = FeignTimeoutConfig.class)
public interface UserFeignService {
@RequestMapping("/findUserName/{id}")
String findUserName(@PathVariable("id") String id);
}
3.3、调用测试
http://127.0.0.1:8011/order/placeOrderTimeout/1
效果是一样的。
