现场部署新的代码

在现场(电子商务)网站上部署新代码的最佳做法是什么?

现在,当重新命名public_html_newpublic_html ,旧的为public_html_old时,我已经停止了apache的+/- 10秒。 这会造成一个短暂的停机时间,然后再次启动Apache。

如果使用Git来将新的repo拉到实时目录中,也会出现同样的问题。 在网站活跃的时候,我可以拉回购回吗? 那么如果我需要复制一个数据库呢?

在活动站点的tar(备份目的)压缩过程中,我注意到媒体目录中发生了变化。 这表明文件不断变化。 如果这些更改可能会干扰,如果部署期间没有停止Apache。

使用负载平衡器是一个好主意。 如果网站重要性足以担心几秒钟的停机时间,重要的是要担心容错。

除此之外,如果这是在UNIX系统上,则可以在重命名(或符号链接更新等)期间暂挂Apache:

 killall -STOP httpd # Pause all httpd processes mv public_html public_html_orig mv public_html_new public_html killall -CONT httpd # Resume all httpd processes 

这将使Apache在重命名期间不接受新的请求。 如果你喜欢符号链接或其他方法,可以使用相同的想法:

 killall -STOP httpd # Pause all httpd processes rm /var/www/html ln -s /var/www/version/03 /var/www/html killall -CONT httpd # Resume all httpd processes 

请注意,任何挂起的连接或数据包将在操作系统中排队。 对于一个非常繁忙的站点,考虑调整ListenBacklog(如果适合您的httpd工作types),并检查与TCP listen backlog相关的操作系统设置。

您也可以在httpd.conf中更改DocumentRoot并进行平稳重启( apachectl graceful )。 这个缺点是增加了错误的风险,因为你必须更新任何Directoryconfiguration。

最快最简单的就是使用一个版本目录如

 /var/www/version/01 /var/www/version/02 

并使用当前的符号链接作为您的html_root:

 /var/www/html -> /var/www/version/02 

这个技术可以很好地集成到一个版本控制系统 (svn,git,mercurial,…)中,你可以签出分支和标签,改变符号链接并重新加载Apache。 使用这种技术的停机时间是最小的 ,它允许非常容易的回滚

它还可以与更复杂的部署系统(如RPM软件包或configuration更改pipe理(厨师,木偶等)基础架构)良好集成。

重命名目录而不closuresApache应该也可以。 这将显着缩短窗口。 mv public_html public_html_old && mv public_html_new public_html应该在几分之一秒内完成。

有两个缺点,就是这种方法会给出404窗口期间仍然会发生的任何请求。 如果你运行上面的命令而没有public_html_new目录,它将会失败,并给你一个网站给每个请求404

与目录做primefaces是不支持的。 但是你可以用符号链接来完成。 有一个名为public_html的目录,而不是一个名为public_html.version-number的目录和一个名为public_html指向该目录的符号链接。 现在你可以创build一个名为public_html.new-version-number的目录和一个名为public_html.new的新的符号链接。

然后,您可以将public_html.new重命名为public_html以自动切换。 请注意, mv是“太聪明”来执行重命名,但可以使用python os.rename或其他任何将调用rename系统调用而不尝试变得聪明的任何其他。

如何处理数据库取决于您使用的数据库以及您使用的数据库。 你需要提供更多关于数据库的详细信息,然后才能给你一个很好的答案。

符号链接和MV是你的朋友,但是,如果你真的需要避免最终用户在部署新版本的时候得到一个错误页面,那么你应该在至less2个后端服务器(apache)前面有一个反向代理或负载平衡器在你的情况)。

在部署期间,您只需要一次停止一个后端,部署新代码,重新启动它,然后遍历剩余的后端。

代理将始终将最终用户指向好的后端。

如果您定期在生产系统上应用更改,我会照顾一个结构化的生命周期。 一个很好的做法是Capistrano http://capistranorb.com/ 。 这是在多个平台和configuration上的一台或多台服务器上部署软件的开源解决scheme。

对于Magento甚至有一个插件: https : //github.com/augustash/capistrano-ash/wiki/Magento-Example

对于单服务器和几乎无缝的转换,我build议使用符号链接。

我这样做的方式是将我的本地开发环境中的更改提交到在线Git存储库(如Github)。 我的生产环境运行远程存储库,所以我需要做的就是ssh到服务器,并运行git pull下来最新的变化。 无需停止您的networking服务器。

如果项目中的设置和/或内容与本地版本不同(例如configuration文件和媒体上载)的文件可以使用环境variables和/或将这些文件/目录添加到.gitignore文件,以防止与库。

我的第一个想法是:

 # deploy into public_html_new, and then: rsync -vaH --delete public_html_new/ public_html/ 

一个好的解决scheme是使用rsync。 它只改变了真正改变的文件。 要小心,最后的斜线在这里很重要。

通常apache不需要重启,它不是java世界。 它会根据请求检查每个php文件的更改,并自动重新读取(并重新标记)更改。

Git pull类似的效率,虽然脚本有点困难。 当然,它使各种不同的合并/变化检测成为可能。

只有在没有真正的重大变化的情况下,这个解决scheme才能无缝连接 – 如果部署有很大的变化,一点危险就不能被closures,因为有一个不可忽视的时间间隔,并且不是。

如果有很大的变化,我的build议是你最初的解决scheme(两个重命名)。


这是一个硬核,但100%的primefaces解决scheme:

(1)在你的magento发生的地方做一个备用的mount文件系统:

 mount /dev/sdXY /mnt/tmp 

(2)将public_html_new的装载绑定到public_html:

 mount --bind /path/to/public_html_new /path/to/public_html 

从这一点来说,Apache将会看到你的新部署。 404的任何改变都是不可能的。

(3)使用rsync进行同步, 在备用挂载点上):

 rsync -vaH --delete /mnt/tmp/path/to/public_html_new/ /mnt/tmp/path/to/public_html/ 

(4)删除绑定安装

 umount /path/to/public_html 

移动/replacehttp_public文件夹可以使用简单的mvln -s命令或同等的http服务器运行。 您可以执行一些脚本来显着减less停机时间,但是如果您自动执行该过程,请仔细检查脚本中的命令返回代码。

也就是说,如果你不想停机,你的应用程序也必须支持它。 大多数应用程序使用数据库进行持久性。 如果您的应用程序的版本N与您的数据模型的版本N + 1(或相反)混淆,如果开发团队没有预见,则可能会破坏事物。

从经验来看,通过升级保持这种一致性并不是大多数应用程序所给出的。 尽pipe停机,正确的关机是避免一致性问题的好方法。