【问题标题】:some uwsgi processes do not reload django application (ansible, nginx, supervisor, uwsgi, django)一些 uwsgi 进程不会重新加载 django 应用程序(ansible、nginx、supervisor、uwsgi、django)
【发布时间】:2018-02-16 12:35:02
【问题描述】:

情况:我想将我们 Django 项目的代码更改部署到舞台或生产服务器。为此,我们有一个 ansible 部署脚本,它从 gitlab 中提取 django 项目的代码、迁移数据库、收集静态文件、重新启动不同的服务器等。

问题:当我通过 ansible 脚本部署时,一些 uwsgi 进程(平均 10 个中的 1 个)不会重新加载我的 django 应用程序。例如,在代码更新后静态资产更改并且静态资产包的文件名散列更改后,我可以重现这一点。然后服务器抛出 500 错误,因为 uwsgi 仍然尝试使用旧哈希加载捆绑包(通过https://github.com/ezhome/django-webpack-loader)。当我在静态资产发生更改的部署后在浏览器中刷新网站时,服务器在大约 10-20% 的请求中返回 500 错误,因为它找不到旧的静态资产包(例如:bundle.9290aAFKASE234. js)。

当我在服务器上运行/etc/init.d/supervisor restart 时,问题立即消失,所有 uwsgi 进程似乎都已正确重新加载。

相关的nginx配置

location / {
    {% if nginx_site_basic_auth %}
    auth_basic "Test Server what.digital";
    auth_basic_user_file "{{ project_root}}/nginx_passwdfile";
    {% endif %}

    uwsgi_pass {{ project_name }}_server;
    uwsgi_read_timeout 1800s;
    include /etc/nginx/uwsgi_params;
}

uwsgi 配置(app.ini)

# uwsgi.ini file
[uwsgi]
# Django-related settings
# the base directory (full path)
chdir = {{ project_root }}
# Django's wsgi file
module = {{ project_django_wsgi }}
plugins = python
# the virtualenv (full path)
home = {{ project_venv }}
# process-related settings
# prevents some pretty crazy erratic behaviour
lazy-apps = true
# master
master = true
# maximum number of worker processes
processes = 10
pidfile = {{ wsgi_pid_file }}
#touch-reload = {{ project_root }}/config/wsgi.py
#daemonize = {{ project_root }}/{{ project_name }}-uwsgi-daemon.log
logto = {{ project_root }}/{{ project_name }}-uwsgi-error.log
log-5xx = true
disable-logging = true
harakiri = 120
no-orphans = true
max-requests = 50
# give appropriate permissions to socket file
chmod-socket = 666
# the socket (use the full path to be safe)
socket = {{ project_root }}/{{ project_name }}.sock
# http-socket = :8000
# clear environment on exit
vacuum = true
buffer-size = 32768
# https://stackoverflow.com/questions/32452529/uwsgi-emperor-unicodeencodeerror-ascii-codec-cant-encode-character
env = LANG=en_US.UTF-8

主管模板(由ansible填充):

[program:uwsgi]
user = {{ user_name }}
command={{ project_venv }}/bin/uwsgi --ini {{ project_root }}/{{ uwsgi_conf_file }}
environment={% for name, value in env_vars.iteritems() -%}
    {{ name }}="{{ value|replace('%', '%%') }}";
{%- endfor %}
autostart=true
autorestart=true
stderr_logfile = {{ project_logs }}/supervisor_uwsgi_err.log
stdout_logfile = {{ project_logs }}/supervisor_uwsgi_stdout.log
stopsignal=INT

相关的ansible配置

- name: upload supervisor configuration
  template: src=supervisor.j2 dest=/etc/supervisor/conf.d/{{ project_name }}.conf
  become_user: root

#- name: make sure supervisord runs
#  service: name=supervisor state=started
#  become_user: root

#- name: reread supervisorctl config files
#  command: supervisorctl reread
#  become_user: root

- name: restart supervisor
  # ansible's supervisorctl module doesnt really restart and some weird caching problems emerge
  # shell: supervisorctl restart uwsgi
  shell: /etc/init.d/supervisor restart
  become_user: root

- name: make sure nginx is restarted
  service: name=nginx state=restarted
  become_user: root

【问题讨论】:

  • 你运行supervisorctl restart uwsgi吗?它已在您的 ansible 文件中注释掉。
  • json 文件不像 python 文件那样工作。一旦文件被修改,更改就会生效。重启uwsgi没关系。如果您想要不同的行为,您可能必须以某种方式更改 django-webpack-loader。例如,应该可以将 json 文件转换为公开字典的 python 脚本。然后,这将由 uwsgi 工人兑现。
  • 也可以更改 django-webpack-loader 配置以获得相同的结果。你启用缓存了吗? github.com/ezhome/django-webpack-loader#cache
  • 如果在运行 Ansible 后直接在服务器上调用 /etc/init.d/supervisor restart 可以解决问题,则问题可能是您的 Ansible 配置的一部分。你所展示的 Ansible 配置是否 100% 与 Supervisor 相关?
  • @HåkenLid 谢谢,/etc/init.d/supervisor restart 也会重新启动所有子进程 AFAIK。关于 json 文件,这是预期的行为。但是一旦主管重新启动了 uwsgi 进程,它也应该捕获 json 文件中的新路径。问题恰恰相反,uwsgi 仍然从 json 文件中“读取”旧路径。它还从 db.sqlite3 数据库文件中“读取”旧值!它似乎以某种方式缓存进程有权访问的文件。

标签: django ansible uwsgi


【解决方案1】:

我们终于找到了原因:django 默认使用本地缓存,当有多个 uwsgi 进程时使用不安全。解决方案是设置一个memcached服务并为其配置django的CACHES,如下所述:https://docs.djangoproject.com/en/4.0/topics/cache/#memcached

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-12-05
    • 2014-05-31
    • 2015-12-25
    • 1970-01-01
    • 1970-01-01
    • 2015-03-04
    • 2013-09-15
    相关资源
    最近更新 更多