Okhttp攔截器實現軟負載
阿新 • • 發佈:2019-03-26
問題
Okhttp Client需要在不同的伺服器ip之間訪問介面。
思路
在攔截器中,發現介面服務不可用的情況下面,替換備用的ip服務地址,再次訪問後臺介面。
Interceptor
package com.zyl.interceptor; import okhttp3.Interceptor; import okhttp3.Request; import okhttp3.Response; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import java.io.IOException; import java.util.List; public class RetryAndChangeIpInterceptor implements Interceptor { protected static final Log logger = LogFactory.getLog(RetryAndChangeIpInterceptor.class); private int RetryCount; private String FirstIP; private List<String> SERVERS; public RetryAndChangeIpInterceptor(String firsrIP, List<String> sERVERS, int tryCount) { FirstIP = firsrIP; SERVERS = sERVERS; RetryCount = tryCount; } @Override public Response intercept(Chain chain) throws IOException { Request request = chain.request(); // try the request IOException exception = null; Response response = null; try { response = doRequest(chain, request); } catch (IOException e) { exception = e; } int tryCount = 0; String url = request.url().toString(); while ((response == null || !response.isSuccessful()) && tryCount <= RetryCount) { url = switchServer(url); Request newRequest = request.newBuilder().url(url).build(); logger.debug("intercept : Request is not successful - " + tryCount); tryCount++; // retry the request try { response = doRequest(chain, newRequest); } catch (IOException e) { exception = e; } } if (response == null || !response.isSuccessful()) { if (exception != null) { throw exception; } else if (response != null) { throw new IOException(String.format("介面響應程式碼:%s", response.code())); } else { throw new IOException(); } } return response; } private Response doRequest(Chain chain, Request request) throws IOException { return chain.proceed(request); } private String switchServer(String url) { String newUrlString = url; if (url.contains(FirstIP)) { for (String server : SERVERS) { if (!FirstIP.equals(server)) { newUrlString = url.replace(FirstIP, server); break; } } } else { for (String server : SERVERS) { if (url.contains(server)) { newUrlString = url.replace(server, FirstIP); break; } } } return newUrlString; } }
OkHttp3
List<String> serverList = new ArrayList<>(); serverList.add("10.158.17.61"); OkHttpClient okhttpClient = new OkHttpClient.Builder() .addInterceptor(new RetryAndChangeIpInterceptor("10.158.17.60", serverList, 1))//新增失敗重試及重定向攔截器 .retryOnConnectionFailure(true)//允許失敗重試 .connectTimeout(10, TimeUnit.SECONDS) .readTimeout(10, TimeUnit.SECONDS) .build(); String url = "http://10.158.17.60:80/hello"; Request requestOk = new Request.Builder() .url(url) .get() .build(); responseOk = okhttpClient.newCall(requestOk).execute();
總結
okhttp的攔截器機制靈活,okhttp本身也支援多ip,翻了半天只看關於okhttp路由的文件資料,沒有找到具體的使用。