无需停机即可更新Web应用程序


31

这是一个PHP应用程序。在更新整个代码库时,如何最大程度地减少停机时间?

Answers:


44

我们通常在工作中做的是:

  • 在更新之前,服务器的文档根目录为:
    • /www/app-2009-09-01
    • 但可通过符号链接(称为 /www/application
  • 我们把整个新的代码库 /www/app-2009-09-08
  • 一旦整个代码库都存在:
    • 我们删除了旧的符号链接
    • 我们创建了一个仍称为的新符号链接,/www/application但它指向新的源:/www/app-2009-09-08
  • 我们重新加载apache以强制考虑修改。

所有这些过程都是通过自动脚本完成的(唯一的非自动过程是我们在需要时启动它)。这意味着 :

  • 一切进展很快(尤其是符号链接的切换,这是重要的部分)
  • 没有犯错误的风险:脚本已经过充分的测试,并且可以工作数月/年


此符号链接程序的另一个优点是,如果只有在将新版本的源投入生产后才发现灾难性错误,才很容易“回滚”更新:我们只需要将符号链接切换回即可。

当然,这不会阻止您在登台服务器上投入生产之前测试新版本-但是,谁知道...有时候,有一个非常大的错误,没人能看到。测试:-(
例如,因为在登台计算机上没有定期进行负载测试。
(我已经看到“回滚”功能在3年中使用了4或5次,每次都保存了这一天-网站^^)


这是一个简单的例子:假设我的Apache配置中有这个VirtualHost:

<VirtualHost *>
        ServerName example.com
        DocumentRoot /www/application
        <Directory /www/application>
            # Whatever you might need here (this example is copy-pasted from a test server and test application ^^ )
            Options Indexes FollowSymLinks MultiViews +SymLinksIfOwnerMatch
            AllowOverride All
            php_value   error_reporting 6135
            php_value short_open_tag  on
        </Directory>
</VirtualHost>

相当“标准” ...唯一的/www/application不是真实目录:它只是源当前版本的符号链接。
这意味着当您将源放置到服务器上但尚未切换时,将出现以下内容:

root@shark:/www
# ll
total 8
drwxr-xr-x 2 root root 4096 2009-09-08 22:07 app-2009-09-01
drwxr-xr-x 2 root root 4096 2009-09-08 22:07 app-2009-09-08
lrwxrwxrwx 1 root root   19 2009-09-08 22:08 application -> /www/app-2009-09-01

请注意,symlinc指向“旧版本”

现在,新版本已完全上传到服务器,让我们切换:

root@shark:/www
# rm /www/application
root@shark:/www
# ln -s /www/app-2009-09-08 /www/application

现在,/www/application指向新版本的源代码要点:

root@shark:/www
# ll
total 8
drwxr-xr-x 2 root root 4096 2009-09-08 22:07 app-2009-09-01
drwxr-xr-x 2 root root 4096 2009-09-08 22:07 app-2009-09-08
lrwxrwxrwx 1 root root   19 2009-09-08 22:09 application -> /www/app-2009-09-08

而且我们只需要重启Apache即可:

root@shark:/www
# /etc/init.d/apache2 restart
 * Restarting web server apache2

应该迅速进行三个步骤:“ 删除链接;创建新链接;重新启动apache ”;然后执行以下步骤。即通过自动脚本而不是人。

使用此解决方案:

  • 您可以根据需要花费尽可能多的时间来上传新版本的源代码:只要未更改symlic,apache就不会使用它们
  • 一切正常后,只需切换符号链接即可:它甚至比更改1或2个文件快得多...这实际上意味着没有停机时间:-)

我想,如果使用stat选项为0的APC等操作码缓存,则意味着停机的风险更低。


当然,这是“简单”版本-例如,如果您有一些上传的文件,则必须在某个地方使用另一个符号链接,或另一个VirtualHost或其他任何东西。


希望这更清楚:-)


这也是一种服务器交换。:-)
Wim 10 Brink

mod_rewrite管理符号链接?

@gAMBOOKa:否:仅与Apache的DocumentRoot(或VirtualHost DocumentRoot)有关,该文件为/ www / application; 即符号链接-无论该链接指向何处。

2
很棒的答案。不过,还有一个提示:您可以使符号链接发生而无需取消链接。引述如下:“这三个步骤……应迅速完成;即,通过自动脚本而不是人。” mv命令是一个原子操作,因此您可以创建一个符号链接,例如“ ln -s / www / app-2011-01-28 / www / application-temp”,然后执行“ mv -T / www / application-temp” / www / application”。

1
symlink方法未涵盖某些内容。您的方式适用于Apache + mod_php,但在lighttpd + fastcgi上可能会失败。在一个高流量的网站中,请求将在交换链接的过程中得到满足,即php代码依赖关系将因混合版本而失败。
丹尼斯C,

2

您不能采用现有代码并将项目迁移到单独的测试php文件中,并在进行更新时使用它吗?我的意思是,您应该拥有一个测试服务器和一个生产服务器,以便在必须进行更新时不会造成任何停机。


1

使用更新的代码库设置第二台服务器,并尽快切换它们。:-)

如果不可能,请确保将代码库分为数十个较小的部分。这样一来,停机时间将仅限于一个子部分。较小的代码块更易于替换,并且大多数代码块将继续运行而不会出现问题。不过,只需先在测试环境上尝试一下即可!


由于尚未对应用程序进行零碎模块测试,因此可能会导致意外情况。

这意味着在此更新之后,这将在您的“待办事项”列表中。:-)使它更具模块化,您可以每个模块进行更新。
Wim 10 Brink

1
那是在待办事项清单上,但这是一个长期目标。我们是一家年轻的初创公司,因此开发团队中的组织自然会花费一段时间。= D

1

首先,我经常使用和喜欢类似于Pascal MARTIN的响应的方法。

我还喜欢的另一种方法是使用SCM推送新代码。确切的过程取决于您的SCM类型(git vs svn vs ...)。如果您使用的是svn,我想创建一个“在线”或“生产”分支,并将其作为服务器上的文档根目录签出。然后,每当我想从另一个分支/标签/主干推送新代码时,我只需将新代码提交到“在线”分支中,然后在文档根目录中运行svn update即可。这提供了非常简单的回滚,因为有完整的修订日志,记录了服务器上/下发生的事情以及谁做的以及何时做的。您还可以轻松地在测试框上运行该“在线”分支,从而允许您审核要推送的应用程序。

git和其他样式的SCM的过程相似,只是对其工作流程的样式进行了修改以使其更加自然。

想要拉/轮询而不是推送更新?只需执行cron作业或其他更智能的机制即可自动运行svn update。

附加:您还可以使用此过程将应用程序写入磁盘的文件备份。只需执行cron作业或运行svn commit的其他机制即可。现在,已将应用程序创建的文件备份到SCM中,记录了修订版本等(例如,如果用户更新了磁盘上的文件,但要您还原该文件,则只需推送旧修订版本即可)。


0

我也使用类似Pascal MARTIN的方法。但是,我没有将我的应用程序的多个版本上传到生产服务器,而是将“版本”保留在防火墙后,每个版本都包含在单独的目录中,其中包含版本号和日期。当我想上传新版本时,我使用了一个简单的脚本,其中包括“ rsync -avh --delay-updates”。“ delay = updates”标志会将所有内容(不同)上传到一个临时文件夹,直到所有更新都存在为止,然后在传输结束时立即将所有内容移到它们的正确路径,因此该应用程序永远不会位于半新状态。它与上面的方法具有相同的效果,除了我只在生产站点上保留一个版本的应用程序(最好在生产服务器IMO上仅保留裸露的基本文件)。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.