我有一个应用程序脚本,我循环访问我的Google Analytics帐户,直到我到达
某个档案。
if (profileItems[i].getName() == "Dev Test" )
与其他功能相比(请参阅下文)我拨打Google Analytics API并始终获得抛出异常:异常:配额错误:超出用户速率
function getReportDataForProfile(profileId) {
var tableId = 'ga:' + profileId;
var startDate = getLastNdays(14); // 2 weeks (a fortnight) ago.
var endDate = getLastNdays(0); // Today.
var optArgs = {
'dimensions': 'ga:keyword', // Comma separated list of dimensions.
'sort': '-ga:visits,ga:keyword', // Sort by visits descending, then keyword.
'segment': 'dynamic::ga:isMobile==Yes', // Process only mobile traffic.
'filters': 'ga:source==google', // Display only google traffic.
'start-index': '1',
'max-results': '250' // Display the first 250 results.
};
//
//Exponential Backoff
//
for (var n=0; n<6; n++) {
try {
var results = Analytics.Data.Ga.get(
tableId, // Table id (format ga:xxxxxx).
startDate, // Start-date (format yyyy-MM-dd).
endDate, // End-date (format yyyy-MM-dd).
'ga:visits,ga:pageviews', // Comma seperated list of metrics.
optArgs);
} catch(e) {
if (n == 5) {
//var results = e;
//throw new Error('Quota ERROR');
throw (e)
}
Utilities.sleep((Math.pow(2,n)*1000) + (Math.round(Math.random() * 1000)));
}
}
return results;
}
任何想法发生了什么?
答案 0 :(得分:2)
也许您超出了每秒每个配置文件的最大请求数。看起来它设置为10(https://developers.google.com/analytics/devguides/reporting/core/v3/limits-quotas)
答案 1 :(得分:2)
这确实是因为您不允许每秒查询超过10个请求。我在这里发布一个解决方案(即使这是一个老问题),因为它可以帮助其他人:
/**
* CallLimiter
* @param {Number} numberOfCalls how many calls per duration are we allowed to do
* @param {Number} duration duration in ms
*/
function CallLimiter(numberOfCalls, duration){
var lastCall = 0;
var tokens = 0;
return function limiter(f){
var now = +new Date();
if (now - lastCall > duration) {
tokens = numberOfCalls;
}
if (tokens <= 0) {
tokens = numberOfCalls;
// wait for `duration` before calling limiter(f) again
return setTimeout(limiter.bind(this, f), duration);
}
tokens--;
lastCall = now;
f();
};
}
以下是如何使用它:
// Stub...
var Analytics = {Data: {Ga:{get:function(cb){
cb();
}}}};
function app(){
// Wrap the api call inside a limiter
limiter(function(){
Analytics.Data.Ga.get(function(err, data){
// do something with the data...
// ... then, loop if necessary
app();
});
});
}
// Start
app();
这是一个阻止Scala版本:
class CallLimiter(rate: Throttler.Rate) {
var lastCall = 0
var duration = rate.duration.toMillis
var current_tokens = 0
def apply[A](f: () => A): A = {
val d = new Date().getTime
if (d - lastCall > duration) {
current_tokens = rate.numberOfCalls
}
if (current_tokens <= 0) {
// wait for `duration` before calling f()
Thread.sleep(duration)
current_tokens = rate.numberOfCalls
}
current_tokens = current_tokens - 1
lastCall = d
f()
}
}
使用方法:
import akka.contrib.throttle.Throttler
val limiter = new CallLimiter(new Rate(10, Duration(1, TimeUnit.SECONDS)))
val accounts = limiter(() => analytics.management().accounts().list().execute().getItems)
答案 2 :(得分:1)
您可以更新&#34;每用户费率限制&#34;您自己在开发者控制台的配额部分。
此限制旨在保护您免遭意外使用。
您可以在此处了解详情: https://developers.google.com/console/help/new/#cappingusage