1

私はここで自分の快適ゾーンのかなり外側で何かをしているので、うまくいけば私はただ愚かなことをしているだけです。

特殊なデータベースを実行するために使用しているAmazonEC2インスタンスがあります。これは、RESTAPIを提供するTomcat内のWebアプリケーションを介して制御されます。同じサーバーで、Requestsライブラリを使用してデータベースに対して数十万の単純なクエリを実行するPythonスクリプトを実行しています(クエリを統合することはできないと思いますが、次に試してみます。 )。

問題:スクリプトを少し実行した後、SSH端末で突然パイプの破損エラーが発生します。SSHで再度ログインしようとすると、「操作がタイムアウトしました」というエラーが発生し続けます。そのため、ログインしてPythonプロセスを終了することすらできず、代わりにEC2インスタンスを再起動する必要があります(これは、特にエフェメラルストレージを使用しているため、非常に苦痛です)

私の理論では、リクエストがREST呼び出しを行うたびに、PythonとTomcatの間のポートのペアがアクティブになりますが、完了したときにポートが閉じられることはありません。そのため、Pythonはますます多くのポートを取得しようとし続け、最終的にはSSHポートを取得してロックする(私を起動する)か、すべてのポートを使用するだけで、ネットワークシステムが何らかの形で機能しなくなります(私が言ったように、私の深さから外れています。)

私も使ってみhttplib2ましたが、同様の問題が発生していました。

何か案は?私のポート理論が正しい場合、それが完了したときにポートを放棄するように要求を強制する方法はありますか?または、少なくともログインしてプロセスを終了できるように、SSHポートを立ち入り禁止にするようにUbuntuに指示する方法はありますか?

または、Pythonを使用して非常に単純なREST呼び出しをたくさん行うためのある種のベストプラクティスはありますか?

編集:

解決済み...実行:

s = requests.session()
s.config['keep_alive'] = False

要求を行う前に、要求が完了したときに接続を解放するように要求を強制します。

4

2 に答える 2

2

私の推測:

https://github.com/kennethreitz/requests/blob/develop/requests/models.py#L539は conn を connectionpool.connection_from_url(url) に設定します

それはhttps://github.com/kennethreitz/requests/blob/develop/requests/packages/urllib3/connectionpool.py#L562につながり、これはhttps://github.com/kennethreitz/requests/blob/develop/につながりますrequests/packages/urllib3/connectionpool.py#L167 .

これは最終的にhttps://github.com/kennethreitz/requests/blob/develop/requests/packages/urllib3/connectionpool.py#L185につながります:

def _new_conn(self):
    """
    Return a fresh :class:`httplib.HTTPConnection`.
    """
    self.num_connections += 1
    log.info("Starting new HTTP connection (%d): %s" %
             (self.num_connections, self.host))
    return HTTPConnection(host=self.host, port=self.port)

ハンドラーをそのロガーに接続し、それに一致する行をリッスンすることをお勧めします。これにより、作成されている接続の数を確認できます。

于 2012-08-07T21:58:13.653 に答える
0

理解した...リクエストには、接続に対してデフォルトの「キープアライブ」ポリシーがあり、これを実行して明示的にオーバーライドする必要があります

s = requests.session()
s.config['keep_alive'] = False

リクエストを行う前に。

ドキュメントから:

""" Keep-Alive 素晴らしいニュース — urllib3 のおかげで、keep-alive はセッション内で 100% 自動です! セッション内で行うリクエストは、適切な接続を自動的に再利用します!

すべての本体データが読み取られると、接続は再利用のためにプールに解放されるだけであることに注意してください。prefetch を True に設定するか、Response オブジェクトの content プロパティを読み取ってください。

キープアライブを無効にしたい場合は、keep_alive 設定を False に設定するだけです:

s = requests.session() s.config['keep_alive'] = False """

私は .text および .content プロパティを読んでいて、まだ接続を解放していないため、リクエストに微妙なバグがある可能性があります。しかし、「キープアライブ」をfalseとして明示的に渡すと、問題が修正されました。

于 2012-08-08T07:30:25.390 に答える