首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >处理HTTP 429错误的最佳方法

处理HTTP 429错误的最佳方法
EN

Stack Overflow用户
提问于 2017-12-27 03:56:24
回答 2查看 12.3K关注 0票数 3

我遇到了一个api,如果你在5分钟内点击超过250次,它将返回429,太多请求,响应。计数每五分钟重置一次,所以我的处理方式如下:

代码语言:javascript
复制
try
{
    return request.GetResponse();  
}
catch (Exception e)
{
    if (e.Message.Contains("429"))
    {
        System.Threading.Thread.Sleep(5 * 60 * 1000);
        return request.GetResponse();
    }
    else
    {
        throw new Exception(e.Message);
    }
}

这是处理这种情况的正确方法吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-12-27 04:13:29

这里要考虑的一件事是,如果您开始超过限制,您正在使用的api可能会“惩罚”您。我认为最好的做法是主动控制你的api请求,这样你就永远不会收到429错误。

我们开始在我们的应用程序上遇到同样的事情(429个错误),来自我们正在消费的api。此特定api的限制是每60秒10个。我们实现了一个throttle()函数,它使用嵌入了日期/时间的内存缓存。我们使用的api还跟踪基于帐户的使用情况。你可能不需要这个。但这是我们用来限制我们的请求的一个片段,以确保我们总是在限制之下:

代码语言:javascript
复制
    private void throttle()
    {
        var maxPerPeriod = 250;
        //If you utilize multiple accounts, you can throttle per account. If not, don't use this:
        var keyPrefix = "a_unique_id_for_the_basis_of_throttling";
        var intervalPeriod = 300000;//5 minutes
        var sleepInterval = 5000;//period to "sleep" before trying again (if the limits have been reached)
        var recentTransactions = MemoryCache.Default.Count(x => x.Key.StartsWith(keyPrefix));
        while (recentTransactions >= maxPerPeriod)
        {
            System.Threading.Thread.Sleep(sleepInterval);
            recentTransactions = MemoryCache.Default.Count(x => x.Key.StartsWith(keyPrefix));
        }
        var key = keyPrefix + "_" + DateTime.Now.ToUniversalTime().ToString("yyyyMMddHHmm");
        var existing = MemoryCache.Default.Where(x => x.Key.StartsWith(key));
        if (existing != null && existing.Any())
        {
            var counter = 2;
            var last = existing.OrderBy(x => x.Key).Last();
            var pieces = last.Key.Split('_');
            if (pieces.Count() > 2)
            {
                var lastCount = 0;
                if (int.TryParse(pieces[2], out lastCount))
                {
                    counter = lastCount + 1;
                }
            }
            key = key + "_" + counter;
        }
        var policy = new CacheItemPolicy
        {
            AbsoluteExpiration = DateTimeOffset.UtcNow.AddMilliseconds(intervalPeriod)
        };
        MemoryCache.Default.Set(key, 1, policy);
    }

我们在代码中使用这个throttle()函数,如下所示:

代码语言:javascript
复制
    public override void DoAction()
    {
        throttle();
        var url = ContentUri;
        var request = (HttpWebRequest)WebRequest.Create(url);
        request.Method = "GET";
        request.Headers.Add("Authorization", "Bearer " + AccessToken);
        request.Accept = "application/json";
        WebResponse response = request.GetResponse();
        var dataStream = new MemoryStream();
        using (Stream responseStream = request.GetResponse().GetResponseStream())
        {
            //DO STUFF WITH THE DOWNLOADED DATA HERE...
        }
        dataStream.Close();
        response.Close();
    }

它本质上是在缓存中跟踪您的请求。如果已经达到限制,它会暂停,直到经过足够的时间,使您仍然在限制之下。

票数 4
EN

Stack Overflow用户

发布于 2017-12-27 04:11:01

您不应该在异常类上进行字符串解析。反过来,异常类永远不应该将重要信息放到消息字段中。您对异常的整个捕获和重新抛出也是错误的。因此,在前面,你应该阅读有关正确的异常处理的知识。这里有两篇我经常链接的文章:

http://blogs.msdn.com/b/ericlippert/archive/2008/09/10/vexing-exceptions.aspx http://www.codeproject.com/Articles/9538/Exception-Handling-Best-Practices-in-NET

除非我上错了Network类,否则我认为您应该使用catch WebExceptions only。我认为这就是您应该如何从这个函数中获得HTTP错误代码的方法,但我并不是很确定。

更好的做法是完全避免异常。所以我不得不问:为什么你要如此频繁地连续调用那个函数呢?是否没有适合批量检索的函数?该服务是否打算像这样实现自动化?

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47983158

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档