2016-11-15 77 views
8

我正在使用rest-client将POST发送到非常慢的Web服务。我将timeout设置为600秒,并且我确认它已被传递到Net :: HTTP的@read_timeout@open_timeout在AWS Linux上增加RestClient/Net :: HTTP中的连接(2)超时

然而,大约两分钟后,我得到一个低级别的超时错误,Errno::ETIMEDOUT: Connection timed out - connect(2)

回溯的相关部分是

Operation timed out - connect(2) for [myhost] port [myport] 
/Users/dmoles/.rvm/rubies/ruby-2.2.5/lib/ruby/2.2.0/net/http.rb:879:in `initialize' 
/Users/dmoles/.rvm/rubies/ruby-2.2.5/lib/ruby/2.2.0/net/http.rb:879:in `open' 
/Users/dmoles/.rvm/rubies/ruby-2.2.5/lib/ruby/2.2.0/net/http.rb:879:in `block in connect' 
/Users/dmoles/.rvm/rubies/ruby-2.2.5/lib/ruby/2.2.0/timeout.rb:88:in `block in timeout' 
/Users/dmoles/.rvm/rubies/ruby-2.2.5/lib/ruby/2.2.0/timeout.rb:98:in `call' 
/Users/dmoles/.rvm/rubies/ruby-2.2.5/lib/ruby/2.2.0/timeout.rb:98:in `timeout' 
/Users/dmoles/.rvm/rubies/ruby-2.2.5/lib/ruby/2.2.0/net/http.rb:878:in `connect' 
/Users/dmoles/.rvm/rubies/ruby-2.2.5/lib/ruby/2.2.0/net/http.rb:863:in `do_start' 
/Users/dmoles/.rvm/rubies/ruby-2.2.5/lib/ruby/2.2.0/net/http.rb:852:in `start' 
/Users/dmoles/.rvm/gems/ruby-2.2.5/gems/rest-client-2.0.0/lib/restclient/request.rb:766:in `transmit' 
/Users/dmoles/.rvm/gems/ruby-2.2.5/gems/rest-client-2.0.0/lib/restclient/request.rb:215:in `execute' 
/Users/dmoles/.rvm/gems/ruby-2.2.5/gems/rest-client-2.0.0/lib/restclient/request.rb:52:in `execute' 

它看起来像代码抛出错误的行是

TCPSocket.open(conn_address, conn_port, @local_host, @local_port) 

它好像底层connect(2)系统调用有大约两分钟超时,而超时参数p因为Net :: HTTP只能缩短,而不能延长它。有没有办法修改套接字参数来设置更长的超时时间?

修改为添加:这似乎只是我们的AWS Linux服务器上的一个问题 - 在我的MacOS开发机器上,十分钟的超时工作。我假设MacOS/BSD上默认的connect()超时时间较长,但我并不知道。

回答

4

首先,您可以增加tcp_syn_retries配置更新/proc/sys/net/ipv4/tcp_syn_retries文件。参考here

如果不起作用,我认为您需要激活SO_KEEPALIVETCP_USER_TIMEOUT选项。但可能在rest-client中没有该接口。

所以,也许你需要自己制作一个叉子或创建SocketSocket::Option

Mike Perham在他的blog中写道。

1

也许你是从套接字开始。插座需要一段时间才能再次使用,如果您在短时间内连接很多连接,这可能是问题所在。

检查ulimit -n检查打开的文件描述符的最大数量。记住一个套接字是一个文件,你需要改变它来允许打开更多的套接字。要更改打开文件的最大数量,请执行sudo ulimit -n 1000000

欲了解更多信息,请查阅this