Gem 如何关闭 Faraday (Net::http) 在 readtime_out 时会重发请求的机制

cakejuju · 2016年10月01日 · 最后由 cakejuju 回复于 2016年10月02日 · 1101 次阅读

具体描述:

用faraday发送请求时,若服务端的响应时间超过了配置faraday对象的readtime_out时间,faraday会再次发送请求,导致服务端收到两笔一样的请求。重发的动作在http的文档中并没有很清楚的说明,我是在项目运作过程中发现了这个情况,然后本地测试了一下(用faraday调用自己的服务,服务端故意加了sleep时间)。

http参数的文档链接

虽然说把readtime_out这个参数设置的足够大可以很大程度上避免这个问题。但在对端服务器性能很差的时候会导致线程阻塞的时间太长。所以就想找能否强制不让faraday去重发,但始终没有找到这个参数或者配置。后来尝试用Net::http包来直接做发送,发现还是有一样的问题。因为faraday其实也是调用了Net::http中的方法。。
 def start  # :yield: http
   raise IOError, 'HTTP session already opened' if @started
   if block_given?
     begin
       do_start
       return yield(self)
     ensure
       do_finish
     end
   end
   do_start
   self
 end

 def do_start
   connect
   @started = true
 end
 private :do_start

 def connect
   ....
end

上面为http类中的部分方法 net::http gem的github 链接。在请求出现readtime_out时 do_start方法只调用一次,但connect方法确被调用了两次(connect方法较长,其中用socket来发请求),关键是始终没发现为什么会这样。。
uri = URI.parse(url + path)
http = Net::HTTP.new(uri.host, uri.port)
http.read_timeout = 60
http.open_timeout = 60
http.keep_alive_timeout = 0
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE 
这是我目前所使用的配置,keep_alive_timeout可以忽略,本来以为是这个参数在作怪,因为java中有个keep_ailve的东东,但发现怎么设置也没用。
有熟悉faraday的朋友给出些建议吗?
共收到 2 条回复
def connection
  @connection ||= Faraday.new( ssl: { verify: false } ) do |conn|
    conn.request  :multipart
    conn.request  :url_encoded
    conn.request  :retry, max: 2, interval: 0.05,
                  interval_randomness: 0.5, backoff_factor: 2,
                  exceptions: [Faraday::TimeoutError, Timeout::Error]
    conn.response :logger
    conn.adapter  :typhoeus
    conn.options.open_timeout = 10
    conn.options.timeout = 10
  end
end

#1楼 @mimosa 谢谢!按照你给的配置把adapter换成了typhoeus, retry max设置为0,不会resend了。

huacnlee 关闭了讨论 10月03日 10:26
需要 登录 后方可回复, 如果你还没有账号请点击这里 注册