1

我一直在尝试使用 Perl AnyEvent HTTP 模块和以下代码发出异步请求。

my $headers = {
    'Accept'         => 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
    'Accept-Language'=> 'en-us,en;q=0.5',
    'Connection'     => 'keep-alive'
};

$request = http_request (
    GET => "$url",
    timeout => 5, # seconds
    # persistent => 1,
    # keepalive => 1,
    headers => $headers,
    proxy => $proxyRef,
    sub {
        my ($body, $hdr) = @_;
    }
);

我不断从请求中得到以下响应:

{ 
  'Reason' => 'Connection timed out',
  'URL' => 'url requested',
  'Status' => 595
};

我一直在检查 AnyEvent 文档以了解此错误的原因,但没有成功。在这个问题上找不到其他有用的线程,除了超时重试的建议,这会产生相同的结果。一个简单的 'wget' 可以在同一个 URL 上工作并且它还活着。谁能指出如何调试这个问题?

4

1 回答 1

2

“连接超时”错误表示底层 tcp 连接超时。也就是说,当 AnyEvent::HTTP 尝试连接到 Web 服务器或代理时,连接请求超时(通常在大约 30 秒后)。没有办法以可移植的方式影响此超时。

具体来说,问题不是请求本身的问题(还没有进入那个阶段),也不是DNS解析的问题,也不是服务器拒绝连接的问题。问题是服务器没有响应,即它被关闭,你和服务器之间的互联网连接失败,或者防火墙默默地阻止了连接。

更新

我刚刚收到一个用户的报告,该用户由于一个稍微不同的问题而遇到了这个问题——他启动了一个 HTTP 请求,而不是返回到事件循环,他阻止他的程序的时间超过了超时时间(使用sleep)。换句话说,他启动了一个 HTTP 请求,然后阻止了事件库的工作。当控制最终返回时,AnyEvent::HTTP 立即超时,因为它无法及时创建连接。

看到您的超时非常小,这很可能是原因 - AnyEvent::HTTP 无法知道连接超时是因为服务器/网络延迟还是因为它根本无法获得足够的 CPU 时间来执行所需的请求时间。

在这种情况下,解决方法是要么将超时时间延长到更长,这样即使 CPU 时间很少,也有足够的时间,或者通过运行事件循环来重组程序以基于事件的方式编写,然后使用计时器而不是睡眠。

于 2013-12-29T00:10:02.260 回答