Feign源码分析,其实现类在 SynchronousMethodHandler,实现方法是public Object invoke(Object[] argv) ,它的代码分析如下:
1.构造请求数据,将对象转换为json:
RequestTemplate template = buildTemplateFromArgs.create(argv);
2.发送请求进行执行(执行成功会解码响应数据):
executeAndDecode(template, options);
3. 执行请求会有重试机制:
Retryer retryer = this.retryer.clone();
while (true) {
try {
return executeAndDecode(template, options);
} catch (RetryableException e) {
try {
retryer.continueOrPropagate(e);
} catch (RetryableException th) {
Throwable cause = th.getCause();
// 重试结束 或则 不允许重试,则通过抛异常的形式终止
if (propagationPolicy == UNWRAP && cause != null) {
throw cause;
} else {
throw th;
}
}
if (logLevel != Logger.Level.NONE) {
logger.logRetry(metadata.configKey(), logLevel);
}
continue;
}
}
4. Retryer是重试器,其实现方法有两种,第一种是系统默认实现方式,第二种是可以自定义重试器,一般少用,通过默认实现重试类Default可以看到其构造函数中的重试次数为5。
public Default() {
this(100, SECONDS.toMillis(1), 5);
}
public Default(long period, long maxPeriod, int maxAttempts) {
this.period = period;
this.maxPeriod = maxPeriod;
this.maxAttempts = maxAttempts;
this.attempt = 1;
}
因此解决Feign调用的幂等性问题最简单也就最常用的就是让Feign不重试。