Urllibを使用して定期的にURLを取得するプログラムがあり、次のような断続的なエラーが表示されます。
I/Oエラー(ソケットエラー):[Errno 111]接続が拒否されました。
それは時間の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
編集-Google検索はあまり役に立たない、私が得たのは、私がフェッチしているサーバーが時々接続を拒否することです、どうすればコードのバグではないことを確認できますか?
Wireshark のようなパケットスニファーを使用して、何が起こるかを見てください。 SYNフラグ付きパケットの発信、SYN + ACKフラグ付きの着信、そしてACKフラグ付きの発信を確認する必要があります。その後、ポートはローカル側で開いていると見なされます。
最初のパケットのみが表示され、数秒待ってからエラーメッセージが表示される場合、反対側はまったく応答していない(例:ケーブルの抜き差し、サーバーの過負荷、誤ったパケットの破棄)、ローカルネットワークスタックは接続試行を中止します。 RSTパケットが表示される場合、ホストは実際に接続を拒否しています。 「ICMP Port unreachable」またはHost unreachableパケットが表示された場合、ファイアウォールまたはターゲットホストは、ポートが実際に閉じられていることを通知します。
もちろん、サービスが常に利用可能であることを期待することはできません(ユーザーとデータの間のすべての障害点を考慮してください)。後でもう一度試す必要があります。
ECONNREFUSED errnoを取得するということは、yourカーネルがもう一方の端で接続を拒否したことを意味します。できることは、非常に具体的な方法でエラーをトラップし、しばらくしてからもう一度試すことです。
# 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つのすべて大文字の定数をお気に入りの数字に置き換えます。
以前、EC2インスタンスでこの問題が発生しました(リソースを提供するためにcouchdbを提供していました-将来的にAmazonのS3を検討しています)。
確認する1つのこと(Ec2を想定)は、セキュリティポリシー内でcouchdbポートが開いているポートに追加されることです。
具体的に出会った
「[Errno 111]接続が拒否されました」
インスタンスが停止および開始されたときにEC2経由で。問題はpidfileの競合のようです。私にとっての解決策は、次の方法でcouchdbを(完全かつ適切に)削除することでした。
pkill -f couchdb
その後、再起動します:
/etc/init.d/couchdb restart
何がこれを引き起こしているのか正確にはわかりません。 socket.pyを確認してみてください(私のバージョンは異なるため、トレースの行番号は一致しません。他の詳細も一致しない場合があります)。
とにかく、URLフェッチコードをtry: ... except: ...
ブロックし、短い休止と再試行でこれを処理します。取得しようとしているURLがダウンしているか、ロードが多すぎる可能性があります。それは、とにかく再試行することでしか処理できないものです。
サーバーが正常に動作していないようですので、端末で
telnet ip port
例
telnet localhost 8069
localhostに接続を返すので、接続に問題がないことを示します。そうでない場合はConnection refused接続に問題があることを示します。