问题描述
|
我正在努力解决这一问题,我们将不胜感激!
我有两个Rails应用,我们将它们称为“客户端”和“服务”,它们都是非常简单的普通REST接口-这是基本方案:
客户端向服务发出POST /resources.json请求
服务运行创建资源并向客户端返回ID的过程
同样,所有这些非常简单,只是服务处理非常耗时,可能需要几分钟。如果发生这种情况,则在服务正确处理请求并以200/201响应时,在发出请求后正好60秒(无论ActiveResource :: Base.timeout设置为什么)上,客户端都会引发EOFError。这是我们在日志中看到的(按时间顺序):
C 00:00:00: POST /resources.json
S 00:00:00: Received POST /resources.json => resources#create
C 00:01:00: EOFError: end of file reached
/usr/ruby1.8.7/lib/ruby/1.8/net/protocol.rb:135:in `sysread\'
/usr/ruby1.8.7/lib/ruby/1.8/net/protocol.rb:135:in `rbuf_fill\'
/usr/ruby1.8.7/lib/ruby/1.8/timeout.rb:62:in `timeout\'
...
S 00:02:23: Response POST /resources.json,201,after 143s
显然,服务响应从未到达客户端。我将错误追溯到套接字级别,并在脚本中重新创建了方案,在该脚本中,我打开Tcpsocket并尝试检索数据。由于我什么都没要求,所以我什么也回不了,我的要求应该在70秒后超时(请参阅底部的完整脚本):
Timeout::timeout(70) { Tcpsocket.open(domain,80).sysread(16384) }
这些是几个领域的结果:
www.amazon.com => Timeout after 70s
github.com => EOFError after 60s
www.nytimes.com => Timeout after 70s
www.mozilla.org => EOFError after 13s
www.googlelabs.com => Timeout after 70s
maps.google.com => Timeout after 70s
如您所见,有些服务器允许我们“等待”整整70秒,而另一些服务器则终止了我们的连接,从而引发EOFErrors。当我们针对服务进行此测试时,我们(预期)在60秒后收到了EOFError。
有人知道为什么会这样吗?有什么方法可以防止这些情况或延长服务器端的超时时间?因为我们的服务继续“工作”,所以即使关闭套接字后,我也认为必须在代理级别终止它?
每个提示将不胜感激!
PS:完整脚本:
require \'socket\'
require \'benchmark\'
require \'timeout\'
def test_socket(domain)
puts \"Connecting to #{domain}\"
message = nil
time = Benchmark.realtime do
begin
Timeout::timeout(70) { Tcpsocket.open(domain,80).sysread(16384) }
message = \"Successfully received data\" # Should never happen
rescue => e
message = \"Server terminated connection: #{e.class} #{e.message}\"
rescue Timeout::Error
message = \"Controlled client-side timeout\"
end
end
puts \" #{message} after #{time.round}s\"
end
test_socket \'www.amazon.com\'
test_socket \'github.com\'
test_socket \'www.nytimes.com\'
test_socket \'www.mozilla.org\'
test_socket \'www.googlelabs.com\'
test_socket \'maps.google.com\'
解决方法
我知道这已经快一年了,但是如果其他人发现了这个,我想添加一个可能的罪魁祸首。
亚马逊的ELB将在60秒后终止空闲连接,因此,如果您在ELB后面使用EC2,则ELB可能是服务器端的问题。
我在这里可以找到的唯一\“ documentation \”是https://forums.aws.amazon.com/thread.jspa?threadID=33427&start=50&tstart=50,但这总比没有好
, 每个服务器决定何时关闭连接。这取决于服务器端软件及其设置。您无法控制。