0

我的应用程序习惯性地向 Twitter API 请求用户的时间线(用户的推文)。

顺便说一句,我正在使用 twitter gem 并配置了一个 Twitter 客户端,以使我的应用程序能够发出请求:

client = Twitter::REST::Client.new do |config|
  config.consumer_key        = ENV["TWITTER_CONSUMER_KEY"]
  config.consumer_secret     = ENV["TWITTER_CONSUMER_SECRET"]
  config.access_token        = ENV["TWITTER_ACCESS_TOKEN"]
  config.access_token_secret = ENV["TWITTER_ACCESS_TOKEN_SECRET"]
end

我发出请求的端点https://api.twitter.com/1.1/statuses/user_timeline.json——每 15 分钟有 900 个请求的速率限制。

如果我理解正确,有 2 种常用方法可以确定我的应用程序是否已达到其速率限制——但这两种方法都不是我需要的:

第一种方法:

这是我编写的一个函数,它试图请求用户的推文,如果应用程序有速率限制,它将引发异常。

def get_tweets_from_TwitterAPI(twitter_handle)
  tweets = []
  begin
    tweets = CLIENT.user_timeline(twitter_handle)
  rescue Twitter::Error::TooManyRequests => error
    raise error
  end
  return tweets
end

这种方法的问题是,在我向 Twitter API 发出请求之前,我想知道我的应用程序可以安全地发出多少请求。我担心这种方法会让我的应用程序在达到速率限制后很久才 ping Twitter API,这会使我的应用程序受到 Twitter 的惩罚性行为(例如,我的应用程序被列入黑名单。)

第二种方法 第二种方法是向这个 Twitter 端点发出请求——该端点https://api.twitter.com/1.1/application/rate_limit_status.json将有关给定速率限制的应用程序状态的数据发送回何处。

但同样,这个端点也有自己的速率限制(每 15 分钟 180 个请求)——这不是很高。我的应用程序会超过这个限制。在理想情况下,我想在向 API 发出请求之前确定我的应用程序当前的速率限制状态。所以:

def start_tweets_fetch
  number_of_requests_in_last_15 minutes = WHERE DO I GET THIS NUMBER FROM??
  if number_of_requests_in_last_15 minutes <= 900
    get_tweets_from_TwitterAPI(twitter_handle)
  end
end

我想我必须增加一些我已经保存到我的数据库中的数字来跟踪对 API 的请求。或者有没有更简单的方法?

4

2 回答 2

1

我不能代表您正在使用的 gem,但是一种无需额外调用 rate_limit_status 端点即可跟踪请求限制的方法是检查每个 API 调用的X-Rate-Limit-Remaining标头。不过,我不知道您正在使用的 Ruby gem 上是否有这些数据。

于 2018-09-10T12:05:38.903 回答
0

编辑

这是对Andy Piper 的回答的回应,我认为这是跟踪剩余电话的最简单方法。

假设您正在使用这个 Twitter gem,看起来来自 gem 的每个响应都会使用来自 Andy 建议的速率限制标头的信息填充一个Twitter::RateLimit对象。

您应该能够像这样访问该信息:

tweets = CLIENT.user_timeline(twitter_handle)

remaining_calls = tweets.rate_limit.remaining

从那里您可以保存该值以在下次要发出请求时对其进行检查。如何保存和检查取决于您,但我的其余答案可能仍然有用。


注意:我以前没有尝试过这种方法,但如果我不永久存储请求日志,这是我在你的情况下会尝试的第一件事。

一种方法可能是使用 Rails 内置的Cache API。这将允许您将所需的任何值存储在缓存存储中,该存储应该比数据库更快更轻。

number_of_requests_in_last_15 = Rails.cache.fetch("twitter_requests", expires_in: 15.minutes) { 0 }
if number_of_requests_in_last_15 minutes <= 900
  get_tweets_from_TwitterAPI(twitter_handle)
  Rails.cache.increment("twitter_requests")
end

让我们分解一下

Rails.cache.fetch("twitter_requests", expires_in: 15.minutes) { 0 }

  • fetchon 方法将Rails.cache尝试提取 key 的值twitter_requests
  • 如果键不存在,它将评估块并将返回值设置为键的新值并返回。在这种情况下,如果键twitter_requests不存在,则新键值为0.
  • expires_in: 15.minutes传递给 fetch 方法的选项表示twitter_requests每 15 分钟自动清除此键 ( )。

Rails.cache.increment("twitter_requests")

  • 将键中的值增加twitter_requests1。

笔记

  • 默认情况下,Rails 将使用内存数据存储。这应该可以正常工作,但是每次重新启动 rails 服务器时,缓存中存储的任何值都会被重置。
  • 缓存的后端是可配置的,并且可以更改为其他流行的系统(即 memcache、redis),但这些系统也需要运行并可由 Rails 访问。
  • 您可能希望在调用 API 之前增加缓存,以减少在检查缓存和增加缓存之间缓存过期的机会。增加一个不存在的键将返回nil
于 2018-09-10T06:57:56.103 回答