在Gunicorn工作人员之间共享一个对象,或者在工作者中持久存在一个对象

时间:2013-04-18 20:00:27

标签: python bottle gunicorn

我正在编写一个使用Nginx / Gunicorn / Bottle堆栈的WSGI应用程序,它接受GET请求,返回一个简单的响应,然后将消息写入RabbitMQ。如果我通过直接的瓶子运行应用程序,每次应用程序收到GET时我都会重用RabbitMQ连接。但是,在Gunicorn中,工作人员似乎每次都在破坏并重新创建MQ连接。我想知道是否有一种重用该连接的好方法。

更详细的信息:

##This is my bottle app
from bottle import blahblahblah
import bottle
from mqconnector import MQConnector

mqc = MQConnector(ip, exchange)

@route('/')
def index():
  try:
    mqc
  except NameError:
    mqc = MQConnector(ip, exchange)

  mqc.publish('whatever message')
  return 'ok'

if __name__ == '__main__':
  run(host='blah', port=808)
app = bottle.default_app()

1 个答案:

答案 0 :(得分:6)

好的,这需要我一点时间来解决。发生的事情是,每当有新的请求通过时,Gunicorn都在运行我的index()方法,并因此创建MQConnector的新实例。

解决方法是重构MQConnector,使得它不仅仅是一个类,而只是一堆方法和变量。这样,每个工作者每次都会引用相同的 MQConnector,而不是创建MQConnector的新实例。最后,我传递了MQConnector的publish()函数。

#Bottle app
from blah import blahblah
import MQConnector

@route('/')
def index():
  blahblah(foo, bar, baz, MQConnector.publish)

#MQConnector
import pika
mq_ip = "blah"
exhange_name="blahblah"

connection=pika.BlockingConnection(....
...

def publish(message, r_key):
  ...

结果:过去需要800毫秒的呼叫现在需要4毫秒。我曾经在90名Gunicorn工作人员中以每秒80次呼叫最多,现在我在5名Gunicorn工作人员中最多可以发出约700次呼叫/秒。