OkHttpClient 的简单配置,包含重试,线程池
@Configuration
public class OkHttpConfig {
@Bean("deSourceOkHttp")
public OkHttpClient okHttpClient() {
return new OkHttpClient.Builder()
.connectTimeout(60, TimeUnit.SECONDS)
.readTimeout(30, TimeUnit.SECONDS)
.writeTimeout(30, TimeUnit.SECONDS)
.addInterceptor(new SmartRetryInterceptor(3,1000,true))
.connectionPool(new ConnectionPool(50, 1, TimeUnit.MINUTES))
.addInterceptor(chain -> chain.proceed(chain.request().newBuilder()
.addHeader("Accept", "application/json")
.addHeader("Content-Type", "application/json")
.build()))
.build();
}
}
重试
public class SmartRetryInterceptor implements Interceptor {
private final int maxRetries;
private final long baseDelayMs;
private final boolean enableJitter;
public SmartRetryInterceptor(int maxRetries, long baseDelayMs, boolean enableJitter) {
this.maxRetries = maxRetries;
this.baseDelayMs = baseDelayMs;
this.enableJitter = enableJitter;
}
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
Response response = null;
IOException exception = null;
for (int i = 0; i <= maxRetries; i++) {
try {
response = chain.proceed(request);
if (isSuccessfulOrShouldNotRetry(response)) {
return response;
}
} catch (IOException e) {
exception = e;
}
// 如果是幂等请求或满足特定条件,才重试
if (isIdempotent(request) && i < maxRetries) {
long delay = baseDelayMs * (1 << i); // 指数退避
if (enableJitter) {
delay += new Random().nextInt((int) (baseDelayMs * 0.5));
}
try {
Thread.sleep(delay);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new IOException("重试中断", e);
}
} else {
break;
}
}
if (response != null) {
return response;
}
throw exception;
}
private boolean isSuccessfulOrShouldNotRetry(Response response) {
return response.isSuccessful() || !shouldRetry(response.code());
}
private boolean shouldRetry(int code) {
return retryhttpCpde.containsKey(code);
}
private boolean isIdempotent(Request request) {
String method = request.method();
return "GET".equals(method) || "POST".equals(method) ;
}
}