Gmail API Users.Messages.get引发超出用户速率限制 [英] Gmail API Users.Messages.get throws User Rate Limit Exceeded

查看:66
本文介绍了Gmail API Users.Messages.get引发超出用户速率限制的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

尝试使用RESTFul API从Gmail中获取邮件,但出现此错误: 超出用户速率限制

Trying to get message from the Gmail using RESTFul API and I'm getting this error : User Rate Limit Exceeded

同时,我实现了节流(当Google说在1秒钟内不再有25个调用时,在1秒钟内不会再有5个),并且在遇到任何异常甚至我遇到的所有情况时,也会实现指数回退仍然得到这个例外.

While, I'm implemented throttling (no more 5 gets in 1 sec, when google says that no more 25 calls in 1 sec) and also exponential backoff when I'm getting any exception and even with all this I'm still getting this exception.

那么,这里可能是什么问题?

So, what could be the issue here ?

谢谢

推荐答案

Google API有一个明确定义的配额,这是Gmail的配额:

There is a well defined quota for Google APIs, here is the one for Gmail: https://developers.google.com/gmail/api/v1/reference/quota#per-method_quota_usage

这里有一个小的实用程序类来处理配额(对于单线程,线程安全的实现要复杂一些):

Here is a small utility class to handle the quota (for single threads, the thread safe implementation is a bit more complex):

public class ApilRateLimiter {

    private long timeSliceEnd;
    private final int quotaPerSecond;
    private int quotaRemaining;

    public ApilRateLimiter(final int quotaPerSecond) {
        this.quotaPerSecond = quotaPerSecond;
        this.quotaRemaining = quotaPerSecond;
        this.timeSliceEnd = System.currentTimeMillis() + 1_000L;
    }

    public void reserve(final int quotaReserved) throws InterruptedException {
        if (quotaReserved > quotaPerSecond) {
            throw new IllegalArgumentException(
                "reservation would never be successful as quota requested is greater than quota per second");
        }           
        final long currentTime = System.currentTimeMillis();
        if (currentTime >= timeSliceEnd) {
            this.timeSliceEnd = currentTime + 1_000L;
            this.quotaRemaining = quotaPerSecond - quotaReserved;
        } else if (quotaReserved <= quotaRemaining) {
            quotaRemaining -= quotaReserved;
        } else {
            Thread.sleep(timeSliceEnd - currentTime);
            reserve(quotaReserved);
        }
    }
}

以及Gmail配额的定义:

and the definition for the Gmail quotas:

public interface GmailApiLimits {

    int QUOTA_PER_SECOND = 250;

    int DRAFTS_CREATE = 10;
    int DRAFTS_DELETE = 10;
    int DRAFTS_GET = 5;
    int DRAFTS_LIST = 5;
    int DRAFTS_SEND = 100;
    int DRAFTS_UPDATE = 15;
    int GETPROFILE = 1;
    int HISTORY_LIST = 2;
    int LABELS_CREATE = 5;
    int LABELS_DELETE = 5;
    int LABELS_GET = 1;
    int LABELS_LIST = 1;
    int LABELS_UPDATE = 5;
    int MESSAGES_ATTACHMENTS_GET = 5;
    int MESSAGES_BATCHDELETE = 50;
    int MESSAGES_DELETE = 10;
    int MESSAGES_GET = 5;
    int MESSAGES_IMPORT = 100;
    int MESSAGES_INSERT = 25;
    int MESSAGES_LIST = 5;
    int MESSAGES_MODIFY = 5;
    int MESSAGES_SEND = 100;
    int MESSAGES_TRASH = 5;
    int MESSAGES_UNTRASH = 5;
    int STOP = 50;
    int THREADS_DELETE = 20;
    int THREADS_GET = 10;
    int THREADS_LIST = 10;
    int THREADS_MODIFY = 10;
    int THREADS_TRASH = 10;
    int THREADS_UNTRASH = 10;
    int WATCH = 100;
}

您可以像这样使用它:

this.apiRateLimiter = new ApilRateLimiter(GmailApiLimits.QUOTA_PER_SECOND);
...
apiRateLimiter.reserve(GmailApiLimits.MESSAGES_LIST);
gmailApi.users().messages().list("me")...execute();
...
apiRateLimiter.reserve(GmailApiLimits.MESSAGES_GET);
gmailApi.users().messages().get("me"...execute();
...

基本上,您在调用Gmail API之前先调用reserve().如果第二秒有剩余配额,储备金将立即返还,否则它将一直休眠直到第二秒结束.

Basically, you call reserve() before you make a Gmail API call. If there is quota left for the second, reserve returns right away, otherwise it sleeps until the second is over.

这篇关于Gmail API Users.Messages.get引发超出用户速率限制的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆