测试、部署和更新 PHP 网站。

4
很快我就要发布我的网站项目,在它正式发布之前,我想准备一种"更新模型"。我使用的是Debian系统,带有Apache、PHP 5.3和MySQL(我认为是最新版本),但它们并不是作为一个软件包安装的,而是分别安装的。
我想到了一个简单的方案,请看一下并指出其中的问题:
- 测试 - 我在某个地方找到了这样一个普遍做法:将测试版本的网站部署到beta.mysite.com子域名中,并从那里进行测试。测试将使用与生产环境相同的数据库。在首次发布后,每个新的测试候选版本都将成为一个单独的分支(在部署时合并,我还不知道如何进行分支)。 - 部署 - 如果在beta阶段一切正常,复制并覆盖旧版网页即可。
我能立即发现的问题有:
- 只要数据库保持不变,测试就没问题。但如果最终数据库被更改了怎么办? - 我希望更新尽可能透明,没有任何维护模式或其他东西,但我担心复制文件会在这方面导致问题。
还有其他可能会成为问题的地方吗?或者,有没有更好的方法来完成这件事呢?
3个回答

5

1. 测试

通常情况下,你不会在生产环境,尤其是生产数据库中进行测试,原因如下:

  • 性能:测试可能会占用大量CPU资源和服务器的其他宝贵资源。由于你不希望在测试期间降低生产环境的性能,所以不能使用生产环境进行测试。

  • 数据保护:你不想在测试期间更改生产数据库中的数据。这意味着不仅你的测试范围可能受到限制(即你可能会三思而后行地测试可能破坏实际用户相关数据的某些错误,使该错误稍后被黑客利用),而且你可能会意外更改数据通过在生产数据库上运行未经测试的代码。

  • 安全性:如果你在公司中并有一个团队,则可能将与测试相关的工作分配给专门的测试人员。出于安全原因,让此测试人员访问生产环境不是一个好主意。

1.1 测试环境

测试环境必须尽可能与生产环境相似。例如,如果你为Windows XP提供了使用.NET Framework 3.5的应用程序,则不应该在Windows 7上使用.NET Framework 4进行测试,因为这样会导致测试时一切正常,而当你的客户开始使用该应用程序时失败。

例如:曾经我在一个使用NTFS备用数据流的应用程序上工作。在开发和测试期间,一切都完美无缺,没人想到在2009年,FAT32仍然存在。当然,一旦在生产中,客户将应用程序安装在格式化为FAT32的闪存驱动器上,它就崩溃了。

请注意,这并不意味着你应该在开发过程中使用相同的环境。

在数据库的情况下,情况有所不同。数据库引擎和版本必须相同,并且模式(相同的表,相同的约束等)必须相同,但大多数情况下数据应该不同,测试数据库填充了一些随机的数据,与你在生产中拥有的数据无关。

1.2 数据库:测试瓶颈

例如,如果一个网站最近发布,你没有大量数据。如果数据库包含注册用户列表,则一开始只有很少的用户。另一方面,你可能不仅需要测试你的应用程序是否正常工作,还需要测试性能是否正确以及瓶颈在哪里。在这种情况下,你将需要使用大量的数据进行测试:这样,你可以在生产环境中拥有数千个用户,在测试环境中拥有数十亿个随机生成的用户帐户。

1.3 数据库:测试输出的正确性

当您希望测试数据与生产数据不同以避免HTML注入并验证输出是否正确时,另一种情况是。如果您拥有一个电子商务网站,您会有一个SQL表Products,每个产品都有一个标题将显示在网站上。在测试环境中,您应该有像以下这样的产品名称:

1. A very long name of a product goes here. Oh, this name is really huge!
2. javascript:alert('<a>&\é<%щ你好')
3. 
4. '; delete * from Users

这些名称将确保:
  1. 长名称正确显示,
  2. 名称被正确转义,支持Unicode并且编码正确,
  3. 空名称不会破坏布局,
  4. 避免SQL注入但在输出时不进行转义(如果可以通过网站更改标题)。
如果您开始用这种方式填充生产数据库,则您的用户可能会认为您的网站已经损坏或被黑客攻击了。

2. 部署

一切都取决于每秒实际请求的数量。 2.1 小型网站 如果您的网站很小并且不经常使用,则您真的不需要关心更新工作流程。复制更改的源文件可能少于一秒钟,因为这些文件很小。如果这真的让您困扰,您可以在访问者较少的时间安排文件复制。对于大多数小型网站,在半夜更新源代码应该没问题此外,在显示消息时没有任何问题,即在凌晨4点至5点之间服务器可能会离线。有时在夜间工作,我经常在我的银行网站上看到这些消息,他们可能需要出于安全原因在维护或其他计划任务期间完全离线一次每周。 2.2 服务器群 如果您的网站很大并且每秒有数千个请求,则可能拥有服务器群。在这种情况下,更新过程不应该是一个问题,因为服务器将一个接一个地离线,更新自己,然后返回到群中

听起来很合理。那么我认为最好先下载数据库并在本地进行一些测试,然后立即将更新推送到服务器上? - Maurycy
1
@Maurycy Zarzycki:我编辑了我的答案来回答你的评论。所以是的,在测试环境中应该有相同的模式,但这并不意味着你必须使用相同的数据。 - Arseni Mourzenko
我个人怀疑性能很快会成为一个问题,更不用说我对进行这样的测试没有真正的知识。就测试而言,我更关心在我的开发环境(Windows + WAMP)和生产环境(Debian)上工作不同的事情。 - Maurycy
1
@Maurycy Zarzycki:如果您在生产环境中使用LAMP,则测试环境中也应该使用LAMP。此外,开发环境与测试无关;您可以为测试安装一个LAMP虚拟机。 - Arseni Mourzenko
非常感谢,列表非常全面。 - Maurycy

1
使用同一个数据库是有风险的,因为你可能会意外删除、修改或者输入错误信息到数据库中,然后这些错误信息会出现在你的生产网站上。

那么,我最好克隆数据库并将其用于测试?还是其他什么? - Maurycy
一个“强大”可靠的设置应该包括4个环境:开发、集成、预发布和生产。预发布和生产环境几乎完全相同,甚至可能使用同一个数据库。集成环境是真正的测试环境,它使用自己的数据库副本,定期从生产环境更新。 - Brent Baisley

1
你说得对,复制文件可能需要时间,并且在复制过程中可能会导致网站崩溃。更好的选择是使用rsync只复制已更改的文件,这样会更快。
更好的方法是使用符号链接。将Web服务器指向一个指向“生产”目录的符号链接。对于测试/预发布目录也是同样操作。当测试完成后,将生产符号链接指向测试目录,这样测试目录就变成了生产目录。
您可以按日期和/或版本来命名生产目录。如果出现问题,您只需重新指向符号链接即可回退。您可以保存多个以前的版本。切换版本几乎是瞬间完成的。
请注意,在重新指向符号链接时仍然有可能出现问题。解决此问题的唯一方法是在负载平衡设置中使用多个Web服务器。

简单而惊人,作为Windows用户,我从未想过可以这样使用符号链接! - Maurycy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接