Django - 在apache根据请求创建的所有进程之间共享RabbitMQ连接?

时间:2012-10-24 18:47:12

标签: python django apache rabbitmq pika

我的堆栈是 Django 1.3(Python 2.7) + Apache + mod_wsgi

Apache 为每个请求生成一个新进程...有时在这些请求中,我必须发布一条消息给 RabbitMQ 关于一些繁重的任务稍后要做(比如通知某人的粉丝他们刚发布的猫照片)。

发布涉及与 RabbitMQ 的连接,这很昂贵。 (见这个问题:RabbitMQ create connection is an expensive operation

我也很遗憾地意识到Python无法跨进程共享内存......叹息:(

在这种情况下,如何防止每个apache请求创建和关闭RabbitMQ连接的开销?

对于Clarity,在这里使用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的问题。必须有办法...

谢谢......感谢任何帮助

1 个答案:

答案 0 :(得分:1)

Apache不会为每个请求生成一个新进程。

您可能会被欺骗,因为在嵌入模式下它可能是一个多进程Web服务器,因此可以在单独的进程中处理不同的请求。

我建议你使用mod_wsgi守护进程模式并使用单个多线程进程,但不幸的是你的代码不是线程安全的,因为你不能同时保护多个线程创建全局套接字连接。但是,仅此一点无济于事,因为如果多个线程同时尝试使用该连接,则可能会导致问题。所以你真的需要每个线程都有一个连接对象。

我建议你阅读以下内容,了解Apache / mod_wsgi的不同进程/线程模型。