Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/342.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 重新加载Django网站而不出现500服务器错误?_Python_Django_Ansible_Gunicorn - Fatal编程技术网

Python 重新加载Django网站而不出现500服务器错误?

Python 重新加载Django网站而不出现500服务器错误?,python,django,ansible,gunicorn,Python,Django,Ansible,Gunicorn,我有一个Django/Gunicorn/Nginx网站,我用Ansible剧本建立了这个网站。我目前正在为我的剧本中的那些任务添加标签,每当我添加新功能或修复bug并想重新加载Django代码时,这些任务都需要运行。我的目标是,一旦我在登台服务器上测试了这些更改,就能够将它们推送到生产环境中,而不必关闭生产服务器 我的playbook目前已经设置好了,这样每当我想要将更改推送到生产时,它都会删除整个网站目录,并重建Pip虚拟环境,这样就不会有遗留的“积垢”。问题是,当我运行Ansible pla

我有一个Django/Gunicorn/Nginx网站,我用Ansible剧本建立了这个网站。我目前正在为我的剧本中的那些任务添加标签,每当我添加新功能或修复bug并想重新加载Django代码时,这些任务都需要运行。我的目标是,一旦我在登台服务器上测试了这些更改,就能够将它们推送到生产环境中,而不必关闭生产服务器

我的playbook目前已经设置好了,这样每当我想要将更改推送到生产时,它都会删除整个网站目录,并重建Pip虚拟环境,这样就不会有遗留的“积垢”。问题是,当我运行Ansible playbook时,在它删除网站目录时,会出现一个瞬间的500服务器错误。然后,只要下一个从Github检出代码的任务运行,错误就会消失。显然,每当我重新加载代码库时,如果有任何用户在任务运行时访问我的网站,他们也会得到这个500错误。我一直在想,一旦启动Gunicorn并将Django代码加载到内存中,我就可以删除并重新加载代码,并在不中断服务的情况下重新启动Gunicorn。另一个似乎应该是这样的。然而,我的测试表明并非如此

当客户端浏览器向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

解决方案:将django根目录设置为符号链接。

让我详细解释一下我的解决方案。确保您的代码根是指向服务于流量的实际代码版本的符号链接。在部署过程中,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/
在上面的目录结构中,您可以将current指向其中一个版本。对于每个新部署,您都可以创建一个新版本,然后将当前版本指向新版本目录

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

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


如果需要更多说明,请告诉我。

为什么要删除存储库?Git应该处理过时文件的删除。剩下什么?过时的pip包?我认为最好删除顶级网站目录中的所有内容,以确保我从一个新的代码库开始。我当时正试图遵循Lincoln Loop在YouTube上发表的“Django部署做得对”的建议。我没有停下来考虑Git可能会删除我的目录中的所有文件,当它检查新目录时都不存在。但是,为什么要这样做呢?不是所有的东西都在记忆里吗?在我重新加载Gunicorn之前,为什么网站一直在查看磁盘?在负载平衡器处处理这个问题。我还不够大,还没有一个LB。只有三台服务器:web、db、file。导致500的实际错误是什么?可能是因为删除了模板。