3

私のスタックはDjango 1.3(Python 2.7) + Apache + mod_wsgiです

Apacheはリクエストごとに新しいプロセスを生成します... 時々、それらのリクエストで、後で行うべき重いタスクについて、 RabbitMQにメッセージを公開する必要があります (投稿したばかりの猫の写真について誰かのフォロワーに通知するなど)。

パブリッシュには、高価なRabbitMQへの接続が含まれます。(この SO の質問を参照してください: RabbitMQ の作成接続は高価な操作です)

残念なことに、Python がプロセス間でメモリを共有できないことも認識しています...ため息 :(

この場合、Apache リクエストごとに RabbitMQ 接続を作成して閉じるオーバーヘッドをどのように回避できますか?

明確にするために、ここでRabbitMQ + pikaを使用して、プロセス間の接続を共有しようとして失敗しました:

def test_view(request):
    """a django view publishing to RabbitMQ"""
    connection = Connection.get_shared_connection()
    channel = connection.channel() 
    channel.queue_declare(queue='test_queue', auto_delete=False, durable=True)
    channel.basic_publish(exchange='', routing_key='test_queue', body='Hello Rabbit!', 
                                properties=pika.BasicProperties(delivery_mode=2))
    print 'SENT:', body

    return HttpResponse("published")


class Connection(object):
    """failed attempt to create a singleton"""
    _connection = None

    @staticmethod
    def get_shared_connection(): # return a pika connection
        if not Connection._connection:
            print 'NEW CONNECTION'  # prints NEW CONNECTION with every request
            Connection._connection = pika.BlockingConnection(pika.ConnectionParameters(
                                                                           host='localhost'))
        return Connection._connection

サーバー設定(Django + Apache + mod_wsgi)'NEW CONNECTION'では、要求が行われるたびに出力されますtest_view

Django を RabbitMQ で使用すると、誰もが遭遇する問題のように思えます。方法があるはずです...

ありがとう...どんな助けでも大歓迎です

4

1 に答える 1

1

Apache は、リクエストごとに新しいプロセスを生成しません。

組み込みモードではマルチプロセス Web サーバーになる可能性があるため、さまざまな要求が別のプロセスで処理される可能性があるため、だまされている可能性があります。

mod_wsgi デーモン モードを使用し、単一のマルチスレッド プロセスを使用することをお勧めしますが、残念ながら、複数のスレッドからのグローバル ソケット接続の作成を同時に保護しないため、コードはそのままではスレッド セーフではありません。しかし、それだけでは役に立ちません。複数のスレッドがその 1 つの接続を同時に使用しようとすると、問題が発生する可能性が高いからです。したがって、スレッドごとに接続オブジェクトが必要です。

以下を読んで、Apache/mod_wsgi のさまざまなプロセス/スレッド モデルの背景を理解することをお勧めします。

于 2012-10-25T09:41:50.730 に答える