【问题标题】:Ruby error Net::ReadTimeoutRuby 错误 Net::ReadTimeout
【发布时间】:2013-11-16 20:44:32
【问题描述】:

我正在使用 httparty 进行一系列 API 调用。前两个 API 调用成功,但第三个失败。它暂停大约 60 秒(默认超时时间),然后返回此错误:

/Users/luigi/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/net/protocol.rb:158:in `rescue in rbuf_fill': Net::ReadTimeout (Net::ReadTimeout)
    from /Users/luigi/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/net/protocol.rb:152:in `rbuf_fill'
    from /Users/luigi/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/net/protocol.rb:134:in `readuntil'
    from /Users/luigi/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/net/protocol.rb:144:in `readline'
    from /Users/luigi/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/net/http/response.rb:39:in `read_status_line'
    from /Users/luigi/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/net/http/response.rb:28:in `read_new'
    from /Users/luigi/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/net/http.rb:1406:in `block in transport_request'
    from /Users/luigi/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/net/http.rb:1403:in `catch'
    from /Users/luigi/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/net/http.rb:1403:in `transport_request'
    from /Users/luigi/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/net/http.rb:1376:in `request'
    from /Users/luigi/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/net/http.rb:1369:in `block in request'
    from /Users/luigi/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/net/http.rb:852:in `start'
    from /Users/luigi/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/net/http.rb:1367:in `request'
    from /Users/luigi/.rvm/gems/ruby-2.0.0-p247@pdf/gems/httparty-0.12.0/lib/httparty/request.rb:93:in `perform'
    from /Users/luigi/.rvm/gems/ruby-2.0.0-p247@pdf/gems/httparty-0.12.0/lib/httparty.rb:486:in `perform_request'
    from /Users/luigi/.rvm/gems/ruby-2.0.0-p247@pdf/gems/httparty-0.12.0/lib/httparty.rb:423:in `get'
    from /Users/jmccann/.rvm/gems/ruby-2.0.0-p247@pdf/gems/httparty-0.12.0/lib/httparty.rb:518:in `get'

我的问题是为什么会这样?此错误是否表示 API 错误,或者我可以采取什么措施来导致它?

我的代码:

这是有效的调用:

url = HTTParty.get("https://dev.test.com#{call}",
    :basic_auth => auth,
    :headers => {'Accept' => 'application/json' } )

这是无效的调用:

url = HTTParty.get("https://dev.test.com#{call}",
    :basic_auth => auth,
    :headers => {'Accept' => 'application/json' } )

唯一改变的是实际的call,但根据 API 文档,它们都是有效的调用。

【问题讨论】:

  • 是的,我的团队也得到了它:/home/travis/.rvm/rubies/ruby-2.0.0-p353/lib/ruby/2.0.0/net/protocol.rb: 158:in `rescue in rbuf_fill': Net::ReadTimeout (Net::ReadTimeout)
  • 你有没有想过这个问题?我也有这个问题。
  • 我没有 - 不幸的是,我什至不记得我究竟在哪里遇到了这个问题来尝试复制它。我最终切换到typhoeus gem,它在我的应用程序中运行良好。如果您在切换到typhoeus 时需要任何帮助,请告诉我,我很乐意为您写一些东西。
  • 也许是 API 端的速率限制?例如,如果您调用的 API 限制了一秒钟内的调用次数,就可能出现这种情况。
  • 您可以使用 tcpdump -i 通过 grep 对您尝试与之通信的 IP 地址进行管道传输,以查看它是否会暴露任何问题。可能不是,因为您使用的是 SSL/HTTPS。您可以考虑使用像 charles 这样的代理来坐在它们之间

标签: ruby api timeout httparty


【解决方案1】:

来自 Ruby 文档:http://ruby-doc.org/stdlib-2.1.2/libdoc/net/http/rdoc/Net/HTTP.html

等待读取一个块的秒数(通过一次 read(2) 调用)。 可以使用任何数字,包括小数秒的浮点数。 如果 HTTP 对象在这么多秒内无法读取数据, 它引发了一个 Net::ReadTimeout 异常。默认值为 60 秒。

call 是什么?服务端点是否不同?你在翻阅记录吗? API 通常会限制调用者的速率以防止 DDOS 攻击。您可以尝试将您的 api 调用包装在一些重试逻辑中或添加一些睡眠代码。

【讨论】:

  • @Luigi - 你是如何处理这个问题的?我也有同样的问题
  • 我在 sidekiq 工作人员访问第三方 API 时遇到了这个错误。如果您排队工作,我会查看 Sidekiq 的延迟扩展:github.com/mperham/sidekiq/wiki/Delayed-extensions
  • @Luigi 我使用了这个 gem:github.com/ooyala/retries 来处理重试。您可以控制要允许的重试次数以及它将挽救的异常。
  • @jaysqrd 或任何人告诉我,我们如何将大量记录作为帖子上传到 API?大约 1 lac 记录,理想情况下我们无法在单个 API 调用中发送。但我们可以在多个调用中发送限制集合。是否允许 API 进行多次调用。
  • @Rajuakula 抱歉回复晚了。 API 是否支持批量处理您的数据?
猜你喜欢
  • 2014-12-08
  • 1970-01-01
  • 2018-12-12
  • 1970-01-01
  • 2013-11-01
  • 2016-06-05
  • 1970-01-01
  • 1970-01-01
  • 2015-02-06
相关资源
最近更新 更多