我的堆栈是 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的问题。必须有办法...
谢谢......感谢任何帮助
答案 0 :(得分:1)
Apache不会为每个请求生成一个新进程。
您可能会被欺骗,因为在嵌入模式下它可能是一个多进程Web服务器,因此可以在单独的进程中处理不同的请求。
我建议你使用mod_wsgi守护进程模式并使用单个多线程进程,但不幸的是你的代码不是线程安全的,因为你不能同时保护多个线程创建全局套接字连接。但是,仅此一点无济于事,因为如果多个线程同时尝试使用该连接,则可能会导致问题。所以你真的需要每个线程都有一个连接对象。
我建议你阅读以下内容,了解Apache / mod_wsgi的不同进程/线程模型。