我已经在CentOS 6上使用Capistrano建立了PHP部署并遇到了一个有趣的问题。 capistrano工作的方式,它设置这样的文件夹:
当我看到"当前"符号链接,它指向最新版本。首先,在打开我的网络应用程序时,一切正常。部署新版本后,当前文件夹正确指向新版本,但Web应用程序尝试从旧版本(已在Capistrano清理过程中删除)中加载文件。此外,虚拟主机配置为指向 /var/www/myapp.com/current/Public 。
符号链接是否以任何方式缓存?
失败的特定PHP代码(初始化我的框架)是:
require_once dirname(dirname(__FILE__)) . '/App/App.php';
App\App::run();
目前位于 /var/www/app.com/current/Public/index.php 的 index.php 。
我的Apache错误日志显示:
PHP致命错误:require_once():无法打开所需' /var/www/myapp.com/releases/20130826172237/App/App.php' (include_path ='。:/ usr / share / pear:/ usr / share / php')/var/www/myapp.com/releases/20130826172237/Public/index.php
当前符号链接显示:
当前 - >的/ var / WWW / zverse /释放/ 20130826172641
显然是20130826172641!= 20130826172237,后者是以前的版本。
我能看到的任何想法或领域?
答案 0 :(得分:4)
我无法验证这一点,但似乎Apache在跟踪/缓存符号链接的旧位置时存在一些不可预测的行为:
唯一能完全解决这个问题的是循环Apache,我们不希望在每次部署时都这样做。 - Mike Brittain
他建议移动整个目录,而不是更新符号链接。
答案 1 :(得分:4)
你检查过realpath_cache_size和realpath_cache_ttl指令吗?默认情况下,php> 5.1缓存符号链接文件的真实路径120秒。这将导致capistrano部署出现问题。主要问题是缓存 - 即使你清除你的缓存,你的旧PHP文件将继续服务两分钟,用旧数据重新填充它 - 以及php和静态文件之间的交互。静态文件由Apache直接提供,因此将立即更新。在部署之后,php代码仍将来自之前的版本两分钟,因此它将期待任何已更改的静态文件的旧版本。如果您使用更改这些文件名称的缓存中断过程,这尤其成问题;在这种情况下,php代码无法找到它所期望的文件。
无论如何,有两种解决方案。第一种是在php.ini中将realpath_cache_size设置为0。 (注意:将realpath_cache_ttl设置为0会使不禁用缓存。)或者,如果要保持启用它,您应该能够使用clearstatcache函数立即清除实际路径缓存部署符号链接后,使用capistrano挂钩。但请注意,如果你使用mod_php,那么php cli和apache运行时是分开的,所以你需要使用apache调用的php脚本来调用该函数,类似于{{3 }}。我还没有测试过,因为我没有注意到仅通过禁用缓存会对性能产生重大影响。