okhttp3添加拦截器
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 );
}
/**
* 重建新的HttpUrl,需要重新设置的url部分
*/
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;
}
}
}