Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/313.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 403(超出速率限制)用于核心报告API v3_Java_Multithreading_Google Analytics Api - Fatal编程技术网

Java 403(超出速率限制)用于核心报告API v3

Java 403(超出速率限制)用于核心报告API v3,java,multithreading,google-analytics-api,Java,Multithreading,Google Analytics Api,我们有一个多线程Java应用程序,它从CoreV3API提取数据 我们使用Guava的RateLimiter和JDK的信号量来达到每个IP地址10个RPS和10个配置文件并发请求的限制 下面是一段代码片段: private static final int MAX_CONCURRENT_REQUESTS=6; 私有静态最终int MAX_REQUESTS_PER_SECOND=6; 私有静态最终信号量信号量=新信号量(最大并发请求); 私有静态最终速率限制器RATE\u LIMITER=速率限

我们有一个多线程Java应用程序,它从CoreV3API提取数据

我们使用Guava的RateLimiter和JDK的信号量来达到每个IP地址10个RPS和10个配置文件并发请求的限制

下面是一段代码片段:


private static final int MAX_CONCURRENT_REQUESTS=6;
私有静态最终int MAX_REQUESTS_PER_SECOND=6;
私有静态最终信号量信号量=新信号量(最大并发请求);
私有静态最终速率限制器RATE\u LIMITER=速率限制器.create(每秒最大请求数);
private T execute(AnalyticsRequest请求)引发IOException{
试一试{
信号量。获取不间断();
速率限制器。获取();
返回请求。execute();
}最后{
SEMAPHORE.release();
}
}

但是,当多个线程同时获得5XX错误代码时,所有后续请求都会在相当长的一段时间内以403(RateLimitExcepended)错误终止

每个单独的线程都使用指数退避算法来重新发送失败的请求


在继续使用多线程的同时,我们应该如何避免RateLimitOvered的问题

一旦开始使用
5XX
,您需要一种全局退避的方法。您每小时只能收到“10个失败的
5XX
请求”和“每天50个失败的
5XX
请求”,请参阅。@Matt,谢谢您的回复。也许,你也有一个建议,如何做到这一点(一旦我开始获得5XX,全球范围内退出)?提前感谢。因此错误率限制是特定于视图(配置文件)的,因此可能需要在“问题视图”的所有线程之间存储一个共享数组以及一个单独的全局5XX RateLimiter对象。如果预期的请求在该视图数组中包含viewId,请等待5XX RateLimiter信号量变为可用。我在Java中没有做过太多的多线程处理,但希望设计思想能给你一些帮助。你可以尝试添加一个随机引用器,这在某些情况下是有用的。不久前,我曾尝试使用C#对API进行多线程处理,但最终将其删除。API不允许您每秒向同一个ViewId发出超过10个请求。但是,请查看V4 api,它允许每秒有更多的请求,这可能为多线程提供了一个选项。谷歌最近还添加了一个功能,如果你遇到500多个错误,他们会暂时阻止你(暂时没有定义),因此尝试强制执行是个坏主意。@DaImTo quotaUser将阻止我们获得
UserRateLimitOver
(这是我们从未遇到过的),但不会阻止我们获得
UserRateLimitOver,这导致
403 ratelimited超过了
。一旦开始获得
5XX
,您需要一种全局退出的方法。您每小时只能收到“10个失败的
5XX
请求”和“每天50个失败的
5XX
请求”,请参阅。@Matt,谢谢您的回复。也许,你也有一个建议,如何做到这一点(一旦我开始获得5XX,全球范围内退出)?提前感谢。因此错误率限制是特定于视图(配置文件)的,因此可能需要在“问题视图”的所有线程之间存储一个共享数组以及一个单独的全局5XX RateLimiter对象。如果预期的请求在该视图数组中包含viewId,请等待5XX RateLimiter信号量变为可用。我在Java中没有做过太多的多线程处理,但希望设计思想能给你一些帮助。你可以尝试添加一个随机引用器,这在某些情况下是有用的。不久前,我曾尝试使用C#对API进行多线程处理,但最终将其删除。API不允许您每秒向同一个ViewId发出超过10个请求。但是,请查看V4 api,它允许每秒有更多的请求,这可能为多线程提供了一个选项。谷歌最近还增加了一项功能,如果你遇到500多个错误,它们会暂时阻止你(暂时没有定义),因此尝试强制执行是个坏主意。@DaImTo quotaUser将阻止我们获得
userRateLimitExceed
(这是我们从未遇到过的),但不会阻止我们获得
403 RateLimitExceed
private static final int MAX_CONCURRENT_REQUESTS = 6;
private static final int MAX_REQUESTS_PER_SECOND = 6;

private static final Semaphore SEMAPHORE = new Semaphore(MAX_CONCURRENT_REQUESTS);
private static final RateLimiter RATE_LIMITER = RateLimiter.create(MAX_REQUESTS_PER_SECOND);

private <T extends GenericJson> T execute(AnalyticsRequest<T> request) throws IOException {
    try {
        SEMAPHORE.acquireUninterruptibly();
        RATE_LIMITER.acquire();
        return request.execute();
    } finally {
        SEMAPHORE.release();
    }
}