使用 uWSGI 在 Django 中的 Geoip2() 上出现“[Errno 12] 无法分配内存”
"[Errno 12] Cannot allocate memory" on Geoip2() in Django with uWSGI
以下代码 运行s 在 manage.py shell
中成功:
from django.contrib.gis.geoip2 import GeoIP2
g = GeoIP2()
如果我用 manage.py runserver
手动启动服务器
并将代码放在我的 Django 视图中,它也 运行 没问题。
我的 Django 应用程序由 uWSGI
和 Nginx
作为反向代理托管。
uWSGI
和 Nginx
运行 与 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 级别的内存问题,
因为我可以在 shell 中创建 GeoIP2 对象,而且如果我 运行 手动创建服务器。
接下来我检查的是我项目中的 geoip
目录归 www-data
所有并且有 775 个。
里面的两个文件(GeoLite2-City.mmdb
和 GeoLite2-Country.mmdb
)也属于 www-data
并且有 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
的限制在哪里?
uWSGI 的 ini
文件中的 limit-as = 512
是罪魁祸首。将它加倍到 1024
mb 可以解决问题。
来自官方 uWSGI 2 文档here:
limit-as
Argument: number
Limit process address space (vsz) (in megabytes).
Limits the address space usage of each uWSGI (worker) process using
POSIX/UNIX setrlimit(). For example, limit-as 256 will disallow uWSGI
processes to grow over 256MB of address space. Address space is the
virtual memory a process has access to. It does not correspond to
physical memory. Read and understand this page before enabling this
option: http://en.wikipedia.org/wiki/Virtual_memory
以下代码 运行s 在 manage.py shell
中成功:
from django.contrib.gis.geoip2 import GeoIP2
g = GeoIP2()
如果我用 manage.py runserver
手动启动服务器
并将代码放在我的 Django 视图中,它也 运行 没问题。
我的 Django 应用程序由 uWSGI
和 Nginx
作为反向代理托管。
uWSGI
和 Nginx
运行 与 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 级别的内存问题,
因为我可以在 shell 中创建 GeoIP2 对象,而且如果我 运行 手动创建服务器。
接下来我检查的是我项目中的 geoip
目录归 www-data
所有并且有 775 个。
里面的两个文件(GeoLite2-City.mmdb
和 GeoLite2-Country.mmdb
)也属于 www-data
并且有 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
的限制在哪里?
ini
文件中的 limit-as = 512
是罪魁祸首。将它加倍到 1024
mb 可以解决问题。
来自官方 uWSGI 2 文档here:
limit-as
Argument: number
Limit process address space (vsz) (in megabytes).
Limits the address space usage of each uWSGI (worker) process using POSIX/UNIX setrlimit(). For example, limit-as 256 will disallow uWSGI processes to grow over 256MB of address space. Address space is the virtual memory a process has access to. It does not correspond to physical memory. Read and understand this page before enabling this option: http://en.wikipedia.org/wiki/Virtual_memory