重新加载Django网站没有500服务器错误?

时间:2017-04-17 16:38:05

标签: python django ansible gunicorn

我有一个Django / Gunicorn / Nginx网站,我使用Ansible playbook构建。我目前正在我的playbook中标记那些需要在我添加新功能或修复bug并想重新加载我的Django代码时运行的任务。我的目标是,只要我在登台服务器上测试它们,就可以将任何此类更改推送到生产中,而无需关闭我的生产服务器。

我的Playbook目前已设置好,每当我想将更改推送到生产时,它将删除整个网站目录并重建Pip虚拟环境,以便没有剩余的“残缺”。问题是,当我运行Ansible playbook时,我在删除网站目录时会出现一个短暂的500服务器错误。然后,只要从Github检出代码的下一个任务运行,错误就会消失。显然,每当我重新加载我的代码库时,如果任何用户在该任务运行的时刻访问我的网站,他们也会得到这500个错误。我一直在想,一旦Gunicorn启动并且我的Django代码被加载到内存中,我可以删除并重新加载我的代码并重新启动Gunicorn而不会中断服务。其他Stackover question似乎应该是这种情况。但是,我的测试表明不是这样。

当客户端浏览器向Django发送请求时,Django会将所有.pyc文件重新加载到内存中吗?这是什么导致了这个问题?当我重新加载我的Django代码而不删除删除旧代码的任务时,有没有办法防止这种短暂的中断?

以下是我的Ansible剧本的摘录:

- name: configure web server
  hosts: webservers
  gather_facts: True
  tasks:
     # This task causes momentary 500 server error
     - name: delete any existing project repo
       file: >
         path={{ repo_path }}
         state=absent
       tags: reload

    - name: check out {{ repo_version }} of Github repo
      git: >
        repo={{ repo_url }}
        version={{ repo_version }}
        dest={{ repo_path }}
        accept_hostkey=yes
      register: checkout
      until: checkout|success
      retries: 5
      delay: 10
      become: true
      become_user: "{{ me }}"
      tags: reload

    # ... more tasks

    - name: install python packages into virtual environment
      pip: >
        requirements={{ repo_path }}/requirements/{{ server_tier }}.txt
        state=present
        virtualenv={{ venvs_path }}/{{ commit_hash }}
      tags: reload

    # ... more tasks

    - name: reload gunicorn
      command: pkill -HUP gunicorn
  become: true
  become_user: root
  tags: reload

1 个答案:

答案 0 :(得分:0)

解决方案:将django根目录设为symb链接。

让我详细解释一下我的解决方案。确保您的代码根是指向为流量提供服务的实际代码版本的符号链接。在部署期间,您的ansible脚本将基本上创建一个新的virtualenv,并安装需求。并在新目录中提取代码,该目录应在名称中包含当前时间戳。而你做任何你需要做的事情都可以为交通服务做好准备。然后在最后一步中,您将开始将django根目录链接指向新位置。

/home/ubuntu/project/current -> /home/ubuntu/project/releases/145678/
/home/ubuntu/project/releases/123456/
/home/ubuntu/project/releases/134567/
/home/ubuntu/project/releases/145678/

在上面的目录结构中,您可以将当前点指向其中一个版本。对于每个新部署,您都可以创建新版本,然后将当前指向新版本目录。

在此之后,您可以重新启动gunicorn以刷新新代码库中的设置。

您可以使用cron作业从计算机中删除非常旧的版本。

如果您需要更多说明,请与我们联系。