new OkHttpClient.Builder().addInterceptor(new PollInterceptor(urls)).build()
添加日志拦截器:
HttpLoggingInterceptor httpLoggingInterceptor = new HttpLoggingInterceptor(); httpLoggingInterceptor.setLevel(Level.BODY);new OkHttpClient.Builder().addInterceptor(httpLoggingInterceptor).build()
自定义轮询负载均衡拦截器话不多说直接上代码:
public class PollInterceptor implements Interceptor { // url private final String[] urls; // url size private final int size; // 计数:下次轮询服务下标 private final AtomicInteger nextUrlCyclicCounter; public PollInterceptor(String[] urls) { this.urls = urls; this.size = urls.length; this.nextUrlCyclicCounter = new AtomicInteger(0); } @Override public Response intercept(Chain chain) throws IOException { // 获取原始的originalRequest Request originalRequest = chain.request(); // 不需要负载均衡 if (size < 2) { return chain.proceed(originalRequest); } // 获取老的url HttpUrl oldUrl = originalRequest.url(); // 获取originalRequest的创建者builder Request.Builder builder = originalRequest.newBuilder(); // 重建新的HttpUrl,需要重新设置的url部分 HttpUrl newHttpUrl = getHttpUrl(oldUrl); // 获取新newRequest Request newRequest = builder.url(newHttpUrl).build(); // 请求 return chain.proceed(newRequest ); } public HttpUrl getHttpUrl(HttpUrl oldUrl) { // 获取url下标 int index = incrementAndGetModulo(); // 获取新的url HttpUrl baseURL = HttpUrl.parse(urls[index]); // 重建新的HttpUrl,需要重新设置的url部分 assert baseURL != null; return oldUrl.newBuilder() .scheme(baseURL.scheme())// http协议如:http或者https .host(baseURL.host())// 主机地址 .port(baseURL.port())// 端口 .build(); } public int incrementAndGetModulo() { for (; ; ) { int current = nextUrlCyclicCounter.get(); int next = (current + 1) % size; if (nextUrlCyclicCounter.compareAndSet(current, next)) { return next; } } }}
其中核心代码:public int incrementAndGetModulo() { for (; ; ) { int current = nextUrlCyclicCounter.get(); int next = (current + 1) % size; if (nextUrlCyclicCounter.compareAndSet(current, next)) { return next; } } }