我的堆栈是 Django 1.3(Python 2.7) + Apache + mod_wsgi
Apache 为每个请求生成一个新进程...有时在这些请求中我必须发布一条关于一些繁重任务的消息到 RabbitMQ稍后完成(例如通知某人的关注者他们刚刚发布的猫照片)。
发布 涉及连接到 RabbitMQ,这很昂贵。 (请参阅此 SO 问题:RabbitMQ create connection is an expensive operation)
我也很遗憾地意识到 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 结合使用时都会遇到的问题。必须有办法......
谢谢...感谢任何帮助
最佳答案
Apache 不会为每个请求生成一个新进程。
您可能会误以为这是因为在嵌入式模式下它可以是一个多进程 Web 服务器,因此不同的请求可以在单独的进程中处理。
我会建议您使用 mod_wsgi 守护进程模式并使用单个多线程进程,但不幸的是您的代码不是线程安全的,因为您没有保护同时从多个线程创建全局套接字连接。但是,仅此一点也无济于事,因为如果多个线程同时尝试使用一个连接,很可能会导致问题。所以你真的需要每个线程有一个连接对象。
我建议您阅读以下内容以了解 Apache/mod_wsgi 的不同进程/线程模型的一些背景知识。
关于python - Django - 在 apache 每个请求创建的所有进程之间共享 RabbitMQ 连接?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13055718/