在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()

好吧,这花了我一点时间来整理。发生的事情是,每当一个新的请求通过,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):
  ...

结果:以前需要800ms的调用现在需要4ms。我曾经在90个Gunicorn工作人员中最多可以达到每秒80个呼叫,现在我在5个Gunicorn工作人员中最多可以达到每秒700个呼叫。

最新更新