如何将多个Flask开发服务器连接到一个MongoDB实例?

时间:2015-04-28 10:44:48

标签: python mongodb flask database-connection mongoengine

我正在Python Flask framework中构建一个网站,我使用MongoEngine ORM连接到MongoDB。我有一个简单的(Ubuntu 14.04)开发服务器,我尝试在不同的端口上运行该网站的多个实例(端口5000上的dev-version和端口5010上的beta版本)。问题是MongoDB似乎不允许多个Flask实例连接到MongoDB。当我启动一个烧瓶开发服务器时,它工作正常。当我再启动另一个并尝试在浏览器中加载一个从MongoDB实例获取图像的页面时,我首先得到以下错误(如果只启动了一个Flask开发服务器,它可以正常工作):

File "/usr/local/lib/python2.7/dist-packages/PIL/Image.py", line 2290, in open
    % (filename if filename else fp))
IOError: cannot identify image file <_io.BytesIO object at 0x7f09a50f2dd0>

在其中几个之后我得到了很多这些:

  File "/usr/local/lib/python2.7/dist-packages/mongoengine/queryset/base.py", line 309, in first
    result = queryset[0]
  File "/usr/local/lib/python2.7/dist-packages/mongoengine/queryset/base.py", line 160, in __getitem__
    return queryset._document._from_son(queryset._cursor[key],
  File "/usr/local/lib/python2.7/dist-packages/pymongo/cursor.py", line 595, in __getitem__
    for doc in clone:
  File "/usr/local/lib/python2.7/dist-packages/pymongo/cursor.py", line 1076, in next
    if len(self.__data) or self._refresh():
  File "/usr/local/lib/python2.7/dist-packages/pymongo/cursor.py", line 1020, in _refresh
    self.__uuid_subtype))
  File "/usr/local/lib/python2.7/dist-packages/pymongo/cursor.py", line 933, in __send_message
    res = client._send_message_with_response(message, **kwargs)
  File "/usr/local/lib/python2.7/dist-packages/pymongo/mongo_client.py", line 1198, in _send_message_with_response
    member = self.__ensure_member()
  File "/usr/local/lib/python2.7/dist-packages/pymongo/mongo_client.py", line 798, in __ensure_member
    return future.result()
  File "/usr/local/lib/python2.7/dist-packages/pymongo/thread_util.py", line 214, in result
    raise self._exception
AutoReconnect: [Errno 111] Connection refused

/var/log/mongodb/mongodb.log的MongoDB日志只是说:

Tue Apr 28 12:06:12.976 [initandlisten] connection accepted from 127.0.0.1:52035 #1 (1 connection now open)
Tue Apr 28 12:06:13.471 [initandlisten] connection accepted from 127.0.0.1:52042 #2 (2 connections now open)
Tue Apr 28 12:06:29.643 [initandlisten] connection accepted from 127.0.0.1:52347 #3 (3 connections now open)
Tue Apr 28 12:06:30.237 [initandlisten] connection accepted from 127.0.0.1:52361 #4 (4 connections now open)
Tue Apr 28 12:06:30.238 [initandlisten] connection accepted from 127.0.0.1:52362 #5 (5 connections now open)
Tue Apr 28 12:06:30.238 [initandlisten] connection accepted from 127.0.0.1:52363 #6 (6 connections now open)
Tue Apr 28 12:06:30.274 [initandlisten] connection accepted from 127.0.0.1:52425 #7 (7 connections now open)
Tue Apr 28 12:06:37.861 [initandlisten] connection accepted from 127.0.0.1:52625 #8 (8 connections now open)
Tue Apr 28 12:06:38.465 [initandlisten] connection accepted from 127.0.0.1:52642 #9 (9 connections now open)
Tue Apr 28 12:06:52.198 [initandlisten] connection accepted from 127.0.0.1:52910 #10 (10 connections now open)
Tue Apr 28 12:06:52.200 [initandlisten] connection accepted from 127.0.0.1:52911 #11 (11 connections now open)
Tue Apr 28 12:06:52.201 [initandlisten] connection accepted from 127.0.0.1:52912 #12 (12 connections now open)
Tue Apr 28 12:06:52.201 [initandlisten] connection accepted from 127.0.0.1:52913 #13 (13 connections now open)
Tue Apr 28 12:06:52.201 [initandlisten] connection accepted from 127.0.0.1:52914 #14 (14 connections now open)

虽然我不明白为什么它只为两个flask dev服务器建立了这么多连接,但它确实似乎允许多个连接。

那么有人知道为什么两个Flask开发服务器太多了吗?这是MongoDB,MongoEngine,flask_mongoengine还是Flask开发服务器的问题?有谁知道这里发生了什么以及如何解决它?欢迎所有提示!

[编辑]

好吧,我终于发现问题在于使用crop functionality我用来裁剪图像的Python Pillow library。我已经简化了下面的代码来解决问题。如果我注释掉im = im.crop((1, 1, 100, 100))行,那就没问题了;我可以反复运行此代码并刷新页面,完全没有问题。但是,当我使用下面的代码时,我仍然可以刷新并运行此代码几次,但是当我启动两个Flask开发服务器时,我开始从pymongo获取Connection refused错误,我需要重新启动MongoDB才能再次运行它。

有没有人知道为什么在同一台机器上使用两台开发服务器时,使用Pillow裁剪功能会导致MongoDB崩溃?

@app.route('/doc/<docId>')
def getDoc(docId):
    userDoc = UserDocument.objects(id=docId).first()
    im = Image.open(userDoc.file_)
    imageFormat = im.format
    im = im.crop((1, 1, 100, 100))  # <== THIS IS THE PROBLEM
    thumbFilename = '/tmp/' + str(userDoc.id) + '.' + imageFormat  # Create a filename with the id of the image.
    im.save(thumbFilename, im.format)  # Cache the resized image in /tmp
    thumbFile = open(thumbFilename, 'r')  # Open the file from cache
    return Response(thumbFile, mimetype=mimetypes.guess_type(thumbFilename)[0])

0 个答案:

没有答案