如何排队和延迟改装请求以避免达到api速率限制?

时间:2016-12-24 00:00:55

标签: android retrofit rate-limiting

我正在使用实现限制的api。其中一个限制是1个请求/秒。啊。 我有以下情况立即达到极限。

  • 使用api / status

  • 检查api的状态
  • 如果api已启动,请获取用户订阅

  • 从订阅列表中加载页面

有什么我可以插入到改造中,可以将每个网络请求排队到最后一次运行至少1000毫秒?我正在使用/学习rxjava,debounce可以在这里使用吗?

2 个答案:

答案 0 :(得分:4)

你可以限制你的观察力。

    Observable<String> text = ...
text.throttleLast(1, SECONDS)
    .flatMap(retrofitApiCall())
    .subscribe(result -> System.out.println("result: " + result));

另一个解决方案是在okhttp构建器中设置一个调度程序,并添加一个睡眠一秒钟的拦截器。这可能不是最优雅的解决方案,并且会杀死使用异步的一些好处,因为它一次限制您使用一个线程。

OkHttpClient.Builder builder = new OkHttpClient.Builder();


    Dispatcher dispatcher = new Dispatcher();
    dispatcher.setMaxRequests(1);

    Interceptor interceptor = new Interceptor() {
        @Override
        public Response intercept(Chain chain) throws IOException {
            SystemClock.sleep(1000);
            return chain.proceed(chain.request());
        }
    };

    builder.addNetworkInterceptor(interceptor);
    builder.dispatcher(dispatcher);
    builder.build();

答案 1 :(得分:2)

interceptor(来自OkHttpClient)与RateLimiter(来自Guava)组合在一起是避免接收429 HTTP代码的好方法。假设我们希望每秒限制3个呼叫:

import java.io.IOException;

import com.google.common.util.concurrent.RateLimiter;

import okhttp3.Interceptor;
import okhttp3.Response;

public class RateLimitInterceptor implements Interceptor {
    private RateLimiter limiter = RateLimiter.create(3);

    @Override
    public Response intercept(Chain chain) throws IOException {
        limiter.acquire(1);
        return chain.proceed(chain.request());
    }
}