"[Errno 12] Cannot allocate memory" 在 Django 中的 Geoip2() 上使用 uWSGI



以下代码在manage.py shell中成功运行:

from django.contrib.gis.geoip2 import GeoIP2
g = GeoIP2()

如果我用manage.py runserver手动启动服务器并将代码放在我的django视图中,也可以运行良好。

我的Django应用程序由uWSGINginx作为反向代理托管。uWSGINginx都使用www-data用户运行。

这是我在uWSGI上运行时得到的例外:

...
File "/home/myuser/Env/virtenv/myproject/index/views.py" in index
  28.     g = GeoIP2()
File "/home/myuser/Env/virtenv/local/lib/python2.7/site-packages/django/contrib/gis/geoip2/base.py" in __init__
  95.                 self._city = geoip2.database.Reader(city_db, mode=cache)
File "/home/myuser/Env/virtenv/local/lib/python2.7/site-packages/geoip2/database.py" in __init__
  82.         self._db_reader = maxminddb.open_database(filename, mode)
File "/home/myuser/Env/virtenv/local/lib/python2.7/site-packages/maxminddb/__init__.py" in open_database
  37.         return maxminddb.reader.Reader(database, mode)
File "/home/myuser/Env/virtenv/local/lib/python2.7/site-packages/maxminddb/reader.py" in __init__
  52.                     db_file.fileno(), 0, access=mmap.ACCESS_READ)
Exception Type: error at /
Exception Value: [Errno 12] Cannot allocate memory

本地变量为:

Variable    Value
database    '/home/myuser/Env/virtenv/myproject/geoip/GeoLite2-City.mmdb'
db_file     <closed file '/home/myuser/Env/virtenv/myproject/geoip/GeoLite2-City.mmdb',     mode 'rb' at 0x7f8c5cf5d390>
mode        0
self        <maxminddb.reader.Reader object at 0x7f8c5cf5f550>

我使用VirtualBox,我的访客OS是Ubuntu 16.04。我那里有4GB交换文件。如果我释放一些RAM,问题仍然存在。但是,这不应该是OS级别的内存问题因为我可以在外壳中创建geoip2对象,也可以手动运行服务器。

我检查的接下来是我项目中的geoip目录归www-data所有,具有775。www-data也所有(GeoLite2-City.mmdbGeoLite2-Country.mmdb)内部的两个文件也拥有774。

/etc/systemd/system/uwsgi.service包含:

[Unit]
Description=uWSGI Emperor service
[Service]
ExecStartPre=/bin/bash -c 'mkdir -p /run/uwsgi; chown www-data:www-data /run/uwsgi'
ExecStart=/usr/local/bin/uwsgi --emperor /etc/uwsgi/sites
Restart=always
KillSignal=SIGQUIT
Type=notify
NotifyAccess=all
[Install]
WantedBy=multi-user.target

/etc/uwsgi/sites/my_site.ini包含:

[uwsgi]
project = myproject
base = /home/myuser
home = %(base)/Env/virtenv/%(project)
binary-path = /usr/local/bin/uwsgi
chdir = %(home)
chmod-socket = 660
chown-socket = www-data:www-data
#emperor = true
#enable-threads = true
gid = www-data
limit-as = 1024
logto = /tmp/uwsgi.log
master = true
module = myproject.wsgi:application
pidfile = /opt/logs/uwsgi/master.pid
# number of cores on machine
processes = 2
python-path = %(home)
py-autoreload = 2
socket = /run/uwsgi/%(project).sock
uid = www-data
vacuum = true
virtualenv = %(base)/Env/virtenv
vhost = true
workers = 4
env = AWS_KEY=***************
env = AWS_SECRET=***************
env = DJANGO_SETTINGS_MODULE=myproject.settings.local
env = GMAIL_PASS=***************
env = PSQL_PASS=***************
env = SECRET_KEY=*********************************************

我想知道uWSGI的限制在哪里?

limit-as = 512是罪魁祸首。将其加倍到1024 MB解决问题。

从官方UWSGI 2文档中获取:

limit-as

参数:数字

限制过程地址空间(VSZ)(在Megabytes中)。

使用每个UWSGI(Worker)进程的地址空间使用 posix/unix setrlimit()。例如,极限-AS 256将禁止UWSGI 生长超过256MB的地址空间的过程。地址空间是 虚拟内存一个过程可以访问。它与 物理内存。在启用此页面之前,请阅读并理解此页面 选项:http://en.wikipedia.org/wiki/virtual_memory

最新更新