Answers:
使用负载平衡器是一个好主意。如果站点足够重要,可以担心几秒钟的停机时间,那么它足够重要,可以考虑容错能力。
除此之外,如果这是在UNIX系统上,则可以在重命名(或symlink更新等)期间将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
请注意,所有未决的连接或数据包都将在操作系统中排队。对于非常繁忙的站点,请考虑根据您的httpd工作程序类型调整ListenBacklog,并检查与TCP侦听积压相关的OS设置。
您还可以在httpd.conf中更改DocumentRoot并进行正常重启(apachectl graceful
)。这样做的缺点是增加了出错的风险,因为您还必须更新任何Directory
配置。
最快,最简单的方法是使用版本目录,例如
/var/www/version/01
/var/www/version/02
并使用当前的符号链接作为html_root:
/var/www/html -> /var/www/version/02
该技术可以完美地集成到修订控制系统(svn,git,mercurial等)中,因为您可以签出分支和标签,更改符号链接并重新加载Apache。该停机时间最小使用这种技术,它可以很容易的回滚。
它还可以与更复杂的部署系统(例如RPM软件包)或配置更改管理(首席,木偶等)基础架构很好地集成。
ln -snf
破坏原始符号链接之类的方法,底层操作也是unlink
and symlink
。用户在更新期间可能会收到404。这不仅仅只是重命名原始目录并重命名一个新目录(假设您没有跨越文件系统),这也没有什么好。请参阅上面的答案,并在其旁边打勾,以解决此问题。
重命名目录而不关闭Apache也应该起作用。这将大大缩短窗口。mv public_html public_html_old && mv public_html_new public_html
应该在不到一秒钟的时间内完成。
有两个缺点,即该方法将给404
仍然在窗口期间发生的任何请求提供一个。而且,如果您在没有public_html_new
目录的情况下运行上述命令,它将失败,并为您提供一个404
针对每个请求的站点。
不支持对目录执行原子操作。但是您可以使用符号链接来实现。与其拥有一个名为public_html
的目录public_html.version-number
,不如拥有一个名为的目录和一个public_html
指向该目录的符号链接。现在,您可以创建一个名为的目录public_html.new-version-number
和一个名为的新符号链接public_html.new
。
然后,您可以重命名public_html.new
为public_html
自动切换。请注意,mv
执行该重命名“太聪明了”,但是可以使用os.rename
python或其他任何会调用rename
系统调用而又不会变得聪明的方法来完成。
如何处理数据库取决于您使用的数据库以及数据库的用途。您需要提供有关数据库的更多详细信息,然后我们才能为您提供对这一部分问题的良好答案。
mv
有一个-T
选项可以阻止它遵循符号链接。假设两者都是软链接,这将使您原子重命名public_html.new
over public_html
。
Symlinks和mv是您的朋友,但是,如果您确实需要避免最终用户在部署新版本时出现错误页面,则应该在至少2台后端服务器(Apache)前面安装反向代理或负载均衡器(Apache在您的情况下)。
在部署过程中,您只需要一次停止一个后端,部署新代码,重新启动它,然后在其余后端上进行迭代。
最终用户将始终通过代理定向到良好的后端。
如果您要定期在生产系统上应用更改,那么我将处理结构化的生命周期。好的做法是Capistrano http://capistranorb.com/。这是一个开源解决方案,用于在多个平台和配置的一个或多个服务器上部署软件。
对于Magento来说,甚至还有一个插件:https : //github.com/augustash/capistrano-ash/wiki/Magento-Example
对于单服务器和几乎无缝的过渡,我建议使用符号链接。
我的第一个想法是:
# deploy into public_html_new, and then:
rsync -vaH --delete public_html_new/ public_html/
一个好的解决方案是使用rsync。它仅更改了真正更改的文件。当心,路径结尾处的斜线在这里很重要。
通常apache不需要重启,这不是Java世界。它根据请求检查每个php文件的更改,并根据更改自动重新读取(并重新标记)。
Git pull具有相似的效率,尽管编写起来有些困难。当然,它实现了多种不同的合并/更改检测可能性。
仅当没有真正的重大更改时,此解决方案才能无缝运行-如果部署中有较大更改,则无法消除一点危险,因为存在不可忽略的时间间隔,此时将部分更改代码部分不是。
如果有很大的变化,我的建议是您最初的解决方案(两个重命名)。
这有点硬,但是100%是原子解决方案:
(1)在您的magento发生的地方做一些文件系统的替代挂载:
mount /dev/sdXY /mnt/tmp
(2)--bind
将您的public_html_new装载到public_html:
mount --bind /path/to/public_html_new /path/to/public_html
至此,apache将看到您的新部署。404的任何更改都是不可能的。
(3)使用rsync进行synhcronistation,但是在备用安装点上):
rsync -vaH --delete /mnt/tmp/path/to/public_html_new/ /mnt/tmp/path/to/public_html/
(4)拆下装订架
umount /path/to/public_html
public_html
所做的更改,您可能会在很短的时间内,其中的代码处于不一致状态,并且您不希望借此机会。