将 Django 无缝部署到单个服务器
Posted
技术标签:
【中文标题】将 Django 无缝部署到单个服务器【英文标题】:Seamless deployment of Django to single server 【发布时间】:2011-09-19 06:47:18 【问题描述】:我有一个基于 Django 和 Python 2.6 构建的新网站,我已将其部署到云端(符合流行语且 Amazon 微型 EC2 实例是免费的!)。 这是我的详细笔记:https://docs.google.com/document/d/1qcZ_SqxNcFlGKNyp-CXqcFxXXsKs26Avv3mytXGCedA/edit?hl=en_US
由于这是一个新网站(并且想使用最新最好的),我在 Supervisor 之上使用了 nginx 和 Gunicorn。 使用 YUM / easy_install 从主干安装的所有软件。 我的数据库是 Sqlite(目前 - 不确定下一步该去哪里,但这不是问题)。也在待办事项列表中:virtualenv + pip。 到目前为止一切顺利。 我在 SVN 中的代码。我写了一个简单的 fabfile 来部署 - 检查最新的代码并通过 Supervisor 重新启动 Gunicorn。我将我的 DNS 名称与弹性 IP 挂钩。它有效。
我的问题是,如何在不中断服务的情况下更新网站?当我运行我的小更新脚本时,该网站的用户会收到 404s / 500s。
有没有办法在不添加另一台服务器的情况下做到这一点(价格是关键)?
我希望有一个登台系统(在不同的端口上?),并在登台和生产之间无缝切换。在同一(免费)服务器上。通过织物。 我怎么做?运行两个站点的 Nginx 是否相同?我可以在不影响生产的情况下升级暂存吗? fabfile 会是什么样子?目录树会是什么样子?
谢谢!
塔尔。
相关:
Seamless deployment in Rails -【问题讨论】:
对于任何阅读“EC2 Micro 是免费的”的人:它不是真的(至少不再是)。前 750 小时免费,大约是 20 美元的报价。结帐其他ASW Free Offers.. 【参考方案1】:Nginx 允许您为反向代理设置故障转移,您可以将一个 gunicorn 实例作为主要实例,只要该版本正在运行,它就永远不会查看故障转移。
如果您将站点配置为使新版本位于故障转移实例中,您只需编写 fab 文件以使用站点的新版本更新故障实例,然后在准备好后关闭主实例。 Nginx 将无缝地故障转移到第二个实例,并且您在新版本上运行,无需停机。
然后您可以更新主要版本,然后重新打开它,您的主要版本现在已经上线。此时,您可以保持故障转移实例运行以防万一,或者将其关闭。
需要考虑的一些事情。您必须小心数据库,如果您使用的是 sqllite,请确保两个 gunicorn 实例都可以访问 sqllite 文件。
如果您有一个普通的数据库,这不是什么大问题,您只需确保在切换到新版本之前应用了新版本所需的任何数据库迁移。
如果它们是向后兼容的更改,那么这没什么大不了的。如果它们不向后兼容,请小心,您可以在切换到新版本之前破坏旧版本的网站。
为了让事情变得更简单,我会在不同的虚拟环境中运行这些版本。
如果您使用 supervisord 来控制 gunicorn,那么您可以使用 supervisorctl 命令重新加载/重新启动您要部署的任何实例,而不会影响另一个实例。
希望有帮助
这里是 nginx 配置的示例(不是完整的配置文件,删除了不重要的部分)
假设主 gunicorn 实例在端口 9005 上运行,另一个在端口 9006 上运行
upstream service-backend
server localhost:9005; # primary
server localhost:9006 backup; # only used when primary is down
server
listen 80;
root /opt/htdocs;
server_name localhost;
access_log /var/logs/nginx/access.log;
error_log /var/logs/nginx/error.log;
location /
proxy_pass http://service-backend;
【讨论】:
如何配置 Nginx 来做到这一点?这是我的 Nginx 配置:pastebin.com/xdYxPeS2 我可以让两个 Gunicorn 并行运行,监听不同的端口(暂存/生产),并且仍然按照您的描述进行切换吗? 添加了 nginx 示例配置。是的,您可以让它们同时在不同的端口上运行。最好的方法是使用 supervisord 或其他一些流程管理器。 这确实让我有 2 个 gunicorn,每个都有不同的 SW,并让 Nginx 管理切换,因为我用 Supervisorctl 杀死正在运行的 Gunicorn。但是如何测试运行新软件的备份服务器呢?它与外界无关。这个配置中 Nginx 监听的端口不是 80 吗? @Tal 你可以设置第二个服务器配置,它运行在不同的端口,或者相同的端口但不同的 url(子域?),并确保代理通过只使用备份服务器。 @Ken 但是切换将涉及更改 nginx 配置(并重新启动 ngnix)???除非我有 3 个 gunicorns - 1 个运行当前的 SW,1 个用新的 SW 支持它,1 个暂存监听不同的端口。我将测试登台服务器,如果没问题切换到备份服务器。这有意义吗?【参考方案2】:听起来你需要弄清楚如何将 gunicorn 告诉 gracefully restart。似乎您所要做的就是在通知重新加载应用程序时向 gunicorn 进程发出 HUP。如链接中所述,gunicorn docs 解释了如何做到这一点。
【讨论】:
Gunicorn 是否“优雅”地重新启动?所有网站用户都像什么都没发生一样继续吗?当 Nginx 将作业发送到 Gunicorn 端口并且没有人在听(片刻)时,它是如何工作的?此外,这并没有解决源代码升级问题——新的 Gunicorn 实例如何知道运行新代码? 通常,“优雅重启”是指重启时不丢失任何请求。我已经阅读了一些关于独角兽的材料,而 gunicon 是它的一个端口。我相信当您发出 SIGHUP 时正在处理的请求将在您的新代码启动时完成处理。此外,独角兽被设计为只有在工作人员“准备好”时才让工作进程从请求队列中拉出。这篇博文提到了它:github.com/blog/517-unicorn ... 这个链接也描述了优雅重启功能:tomash.wrug.eu/2010/01/30/the-awesomeness-of-unicorn.html 我想补充的另一件事与 Ken 的响应有点相关......我会在所有上游 gunicorn 服务器上执行滚动重启,这样你的 gunicorn 服务器就不会因挂起的请求和加载而过载新工人。以上是关于将 Django 无缝部署到单个服务器的主要内容,如果未能解决你的问题,请参考以下文章
Linux MacBook单机部署Pulsar并开启认证功能
使用 Windows 机器将 Django 部署到 Heroku(生产服务器而不是开发服务器)