Okhttp interceptor realizes soft load

Posted by NewbieBryan on Sat, 30 Nov 2019 18:15:09 +0100

problem

Okhttp Client needs to access the interface between different server ip.

thinking

In the interceptor, if the interface service is found to be unavailable, replace the standby ip service address and access the background interface again.

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("Interface response code:%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))//Add failed retry and redirection interceptor
        .retryOnConnectionFailure(true)//Allow failed retries
        .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();

summary

The interceptor mechanism of okhttp is flexible, and okhttp itself supports mult ip le IPS. After half a day, I only read the documents about okhttp routing, but did not find the specific use.

Reference resources

Topics: Front-end OkHttp Apache Java