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 とその有効な 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 に答える