1

ピラミッドを使用して Web サイトを構築しており、他の Web サイトからデータを取得したいと考えています。の呼び出しが 50 回以上ある可能性があるためurlopen、gevent を使用して速度を上げたいと考えました。

geventを使用してこれまでに得たものは次のとおりです。

import urllib2    
from gevent import monkey; monkey.patch_all()
from gevent import pool

gpool = gevent.pool.Pool()

def load_page(url):
    response = urllib2.urlopen(url)
    html = response.read()
    response.close()
    return html

def load_pages(urls):
    return gpool.map(load_page, urls)

実行すると次のようになりpserve development.ini --reloadます。

NotImplementedError: gevent is only usable from a single thread.

何よりも先にパッチを適用する必要があると読んだことがありますが、そのための適切な場所がどこにあるのかわかりません。また、これは保存固有の問題ですか? mod_wsgiに移行するときに、この問題を再度解決する必要がありますか? または、gevent なしでこのユースケース (単に urlopen) を処理する方法はありますか? リクエストの提案を見たことがありますが、ドキュメントで複数のページをフェッチする例を見つけることができませんでした。

更新 1:

私もこのSOの質問からイベントレットを試しました(このイベントレットのからほぼ直接コピーされました):

import eventlet
from eventlet.green import urllib2

def fetch(url):
    return urllib2.urlopen(url).read()

def fetch_multiple(urls):
    pool = eventlet.GreenPool()
    return pool.imap(fetch, urls)

しかし、私が電話するとfetch_multiple、私は得ていますTypeError: request() got an unexpected keyword argument 'return_response'

更新 2:

以前の更新のTypeError原因は、以前に gevent を使用してモンキーパッチを試み、pserve を適切に再起動しなかったことが原因である可能性があります。すべてを再起動すると、正常に動作します。学んだ教訓。

4

2 に答える 2

3

必要なことを行うには、複数の方法があります。

  • 専用geventスレッドを作成し、すべての URL を開くジョブをそのスレッドに明示的にディスパッチします。これにより、geventedurlopenリクエストが実行されます。
  • グリーンレットの代わりにスレッドを使用します。50 スレッドを実行しても、最新の OS に負担をかけることはありません。
  • スレッド プールとキューを使用します。通常、一度に 8 回のダウンロードを行うよりも、50 回のダウンロードを行ってもあまり利点はありません (お使いのブラウザーがそうであるように)。
  • の代わりに別の非同期フレームワークを使用してgeventください。これは、コードを魔法のようにグリーンレット化することによって機能しません。
  • など、独自の非魔法の非同期サポートを持つライブラリを使用しますpycurl
  • 互換性のないフレームワークを混在させて一致させる代わりに、サーバーgeventも構築するか、Web サービスと Web クライアントの両方のニーズに対応する他のフレームワークを見つけてください。

最初にロードすることでフレームワークを変更せずに最後のものをシミュレートし、geventスレッドにモンキーパッチを適用して、既存のスレッド化されたサーバー フレームワークを強制的にサーバーにすることがgeventできます。しかし、これは機能しないか、ほとんど機能するが時々失敗するか、または機能するが非常に遅くなる可能性があります...本当に、gevent-フレンドリー (または少なくとも greenlet フレンドリー) になるように設計されたフレームワークを使用することは、はるかに優れたアイデアです。トーゴ。

あなたは、他の人が を勧めたと言いましたrequests。ドキュメントが見つからない理由は、組み込みの非同期コードrequestsが削除されたためです。それがどのように使用されたかについては、古いバージョンを参照してください。別のライブラリとして利用できるようになりましたgrequests。ただし、暗黙的に でラップrequestsすることで機能geventするため、自分でラップするのとまったく同じ問題が発生します。

requests( の代わりに使用する理由は他にもあります。使用しurllib2たい場合は、自分で行うよりもgevent簡単に使用できgrequestsます。)

于 2013-01-11T20:46:44.060 に答える
2

Web アプリケーションをデプロイしようとしたときに、gevent で同様の問題が発生しました。最も手間のかからない方法は、gevent で実行される WSGI デプロイメントを使用することです。例には、gUnicorn、uWSGI、または gevent の組み込み WSGI サーバーのいずれかが含まれます。Pyramid には、代替デプロイメントを使用する方法が必要です。コードの大部分が gevent に依存している場合は、gevent で実行されるサーバーを使用する方が簡単です。

したがって、基本的には上記の回答の最後の箇条書きです。

于 2013-01-11T22:32:36.363 に答える