14

urllibを使用して定期的にURLをフェッチするプログラムがあり、次のような断続的なエラーが表示されます。

I / Oエラー(ソケットエラー):[Errno111]接続が拒否されました。

90%の時間は機能しますが、それ以外のr10%は失敗します。失敗した直後にフェッチを再試行すると、成功します。なぜそうなのか理解できません。使用可能なポートがあるかどうかを確認しようとしましたが、使用可能です。デバッグのアイデアはありますか?

追加情報については、スタックトレースは次のとおりです。

File "/usr/lib/python2.6/urllib.py", line 203, in open 
    return getattr(self, name)(url)

File "/usr/lib/python2.6/urllib.py", line 342, in open_http
    h.endheaders()

File "/usr/lib/python2.6/httplib.py", line 868, in endheaders
    self._send_output()

File "/usr/lib/python2.6/httplib.py", line 740, in _send_output
    self.send(msg)

File "/usr/lib/python2.6/httplib.py", line 699, in send
    self.connect()

File "/usr/lib/python2.6/httplib.py", line 683, in connect
    self.timeout)

File "/usr/lib/python2.6/socket.py", line 512, in create_connection
    raise error, msg

編集-グーグル検索はあまり役に立ちません、私がそれから得たのは、私がフェッチしているサーバーが時々接続を拒否するということです、どうすればそれが私のコードのバグではないことを確認できますか?これは確かに事実ですか?

4

5 に答える 5

40

Wiresharkのようなパケットスニファを使用して、何が起こるかを確認します。SYNフラグが設定されたパケットの送信、SYN + ACKフラグが設定された着信、次にACKフラグが設定された送信を確認する必要があります。その後、ポートはローカル側で開いていると見なされます。

最初のパケットのみが表示され、数秒待ってからエラーメッセージが表示された場合、反対側はまったく応答せず(ケーブルが接続されていない、サーバーが過負荷になっている、誤ったパケットが破棄されたなど)、ローカルネットワークスタックは接続の試行を中止します。RSTパケットが表示された場合、ホストは実際に接続を拒否します。「ICMPポートに到達できません」またはホストに到達できないパケットが表示された場合、ファイアウォールまたはターゲットホストは、ポートが実際に閉じられていることを通知します。

もちろん、サービスが常に利用可能であるとは限りません(ユーザーとデータの間のすべての障害点を考慮してください)。そのため、後で再試行する必要があります。

于 2010-04-01T13:05:49.123 に答える
11

ECONNREFUSED errnoを取得するということはカーネルがもう一方の端で接続を拒否されたことを意味します。したがって、バグの場合は、カーネルまたはもう一方の端にあります。あなたができることは、これがうまくいくように見えるので、非常に特定の方法でエラーをトラップし、しばらくしてから再試行することです。

# This is Python > 2.5 code
import errno, time

for attempt in range(MAXIMUM_NUMBER_OF_ATTEMPTS):
    try:
        # your urllib call here
    except EnvironmentError as exc: # replace " as " with ", " for Python<2.6
        if exc.errno == errno.ECONNREFUSED:
            time.sleep(A_COUPLE_OF_SECONDS)
        else:
            raise # re-raise otherwise
    else: # we tried, and we had no failure, so
        break
else: # we never broke out of the for loop
    raise RuntimeError("maximum number of unsuccessful attempts reached")

2つのすべて大文字の定数をお気に入りの数値に置き換えます。

于 2010-04-01T13:00:58.043 に答える
3

以前、EC2インスタンスでこの問題が発生しました(リソースを提供するためにcouchdbを提供していました-将来的にAmazonのS3を検討しています)。

チェックすることの1つ(Ec2を想定)は、couchdbポートがセキュリティポリシー内で開いているポートに追加されていることです。

私は特に遭遇しました

「[Errno111]接続が拒否されました」

インスタンスが停止および開始されたときにEC2を介して。問題はpidfileの競合のようです。私にとっての解決策は、次の方法でcouchdbを(完全かつ適切に)強制終了することでした。

pkill -f couchdb

その後、次のコマンドで再起動します。

/etc/init.d/couchdb restart
于 2012-01-26T01:56:51.440 に答える
2

何が原因なのか正確にはわかりません。socket.pyを調べてみてください(私のバージョンは異なるため、トレースの行番号が一致しません。他の詳細も一致しない可能性があります)。

try: ... except: ... とにかく、URLフェッチコードをブロックに入れて、短い一時停止と再試行でこれを処理することは良い習慣のようです。フェッチしようとしているURLがダウンしているか、ロードされすぎている可能性があります。これは、とにかく再試行することでしか処理できないものです。

于 2010-04-01T07:54:40.807 に答える
1

サーバーが正常に動作していないようですので、

telnet ip port

telnet localhost 8069

localhostに接続された状態に戻るため、接続に問題がないことを示します。それ以外の場合は、接続が拒否 され、接続に問題があることを示します。

于 2017-06-22T06:31:34.250 に答える