负载均衡器后面的 SilverStripe
SilverStripe behind load balancer
我在 AWS 负载均衡器后面的两台服务器上有一个 SilverStripe 运行 实例。为了分享 session 信息,我是 运行 Elasticache Redis 服务器。我正在设置我的 php session 商店信息:
ini_set('session.save_handler', 'redis');
ini_set('session.save_path', 'tcp://127.0.0.1:6379');
登录 CMS 的管理部分后,我可以在服务器之间跳转,它会记住我,但是在 CMS 的部分之间切换时,主要部分不会呈现(AJAX 调用).据我所知,另一台服务器没有意识到(你从第二个请求的任何一个)你已经加载了 CMS 管理员并且在响应中 headers 说加载一个新版本的 JS 依赖项然后假发管理员,它没有加载。
读入 the docs SilverStripe 正在使用 Zend_Cache 获取一些额外信息。我想如果我加载管理界面,然后删除它会复制问题的缓存目录。它没有。
然后我尝试使用 this module 来更改 Zend_Cache 正在使用的存储引擎。我补充说:
SS_Cache::add_backend(
'primary_redis',
'Redis',
array(
'servers' => array(
'host' => 'localhost',
'port' => 6379,
'persistent' => true,
'weight' => 1,
'timeout' => 5,
'retry_interval' => 15,
'status' => true,
'failure_callback' => null
)
)
);
SS_Cache::pick_backend('primary_redis', 'any', 10);
我的 mysite/_config.php 并且这在 redis 中存储了一些 cms 信息,例如密钥 CMSMain_SiteTreeHints9b258b19199db9f9ed8264009b6c351b
,但这仍然不能解决问题在负载平衡环境中的服务器之间切换。
SilverStripe 还能在哪里存储缓存数据?我是否正确实施了模块?
默认管理界面(假设您使用的是 3.x)使用一个名为 jquery.ondemand
的 javascript 库 - 它跟踪已经包含的文件(一种相当古老的'require.js
'之类的前身 - 仅在没有 AMD 的情况下,并且有 CSS 支持)。
为此,这与 CMS 本身有任何关系的可能性很小 - 考虑到网络本质上是无状态的,并且您用来保存状态的方法在您的服务器之间共享(两者数据库和 session 数据)。
不 在 HA 集群中的各个实例之间共享的是物理文件。这里的原因很可能(但不一定)是提供给 ondemand
的 URI 末尾的 mtime
标记 - 最初旨在避免浏览器缓存在主题更改方面的问题(开发人员制作或以其他方式自动化)。
你肯定检查过的 headers 包括(总是,无论 HAProxy、nginx、ELB 或其他选择的端点如何)X-Include-CSS
和 X-Include-JS
- 其中一个示例如下所示:
X-Include-JS:/framework/thirdparty/jquery/jquery.js?m=1481487203,/framework/javascript/jquery-ondemand/jquery.ondemand.js?m=1481487186,/framework/admin/javascript/lib.js?m=1481487181
[...]
这是在每个请求上,ondemand
可以检查并查看已经包含的内容以及需要添加的内容。
(顺便说一下,这些 header 的大小是导致 nginx
header 缓冲区问题导致 'default' 设置中的 502
的原因。)
那么,怎么办?
如果您正在部署静态代码,静态文件应该在平衡实例之间保持相同的 mtime - 但这是需要检查的。另一方面,生成的文件(例如 Requirements::combine_files
)将需要在所有实例之间(重新)生成同步,就像您站点的所有 /assets
一样,在这种情况下,mtime 应该持续存在。 Zend_cache
不太可能在这里产生任何影响,尽管 APC
可能是一个因素。当然,在任何情况下首先要检查的是我的前提是否成立——例如运行 header 通过差异工具 back-ends 的响应。
为了帮助那些可能遇到这个问题并需要一个挂钩到 CMS 的解决方案的人,我做了以下工作:
class SyncRequirements_Backend extends Requirements_Backend implements Flushable {
protected static $flush = false;
public static function flush() {
static::$flush = true;
}
public function process_combined_files() {
// You can write your own or copy from framework/view/Requirements.php
// Do the required syncing like rsync at the appropriate spot like on successfulWrite
}
}
将 Requirements::set_backend(new SyncRequirements_Backend());
添加到您的 _config.php(我的是一个单独的扩展,但我的网站也可以)。
此解决方案的问题是,如果核心 Requirements_Backend 更新,您将 运行 使用旧版本的代码,但它不太可能破坏任何东西,您刚刚实施了您的代码拥有使用相同代码的需求后端。您可以只调用父级而不是自己完成所有操作,但是我找不到 运行 仅在文件写入时同步的方法,每次请求组合文件时它都会 运行。
我在 AWS 负载均衡器后面的两台服务器上有一个 SilverStripe 运行 实例。为了分享 session 信息,我是 运行 Elasticache Redis 服务器。我正在设置我的 php session 商店信息:
ini_set('session.save_handler', 'redis');
ini_set('session.save_path', 'tcp://127.0.0.1:6379');
登录 CMS 的管理部分后,我可以在服务器之间跳转,它会记住我,但是在 CMS 的部分之间切换时,主要部分不会呈现(AJAX 调用).据我所知,另一台服务器没有意识到(你从第二个请求的任何一个)你已经加载了 CMS 管理员并且在响应中 headers 说加载一个新版本的 JS 依赖项然后假发管理员,它没有加载。
读入 the docs SilverStripe 正在使用 Zend_Cache 获取一些额外信息。我想如果我加载管理界面,然后删除它会复制问题的缓存目录。它没有。
然后我尝试使用 this module 来更改 Zend_Cache 正在使用的存储引擎。我补充说:
SS_Cache::add_backend(
'primary_redis',
'Redis',
array(
'servers' => array(
'host' => 'localhost',
'port' => 6379,
'persistent' => true,
'weight' => 1,
'timeout' => 5,
'retry_interval' => 15,
'status' => true,
'failure_callback' => null
)
)
);
SS_Cache::pick_backend('primary_redis', 'any', 10);
我的 mysite/_config.php 并且这在 redis 中存储了一些 cms 信息,例如密钥 CMSMain_SiteTreeHints9b258b19199db9f9ed8264009b6c351b
,但这仍然不能解决问题在负载平衡环境中的服务器之间切换。
SilverStripe 还能在哪里存储缓存数据?我是否正确实施了模块?
默认管理界面(假设您使用的是 3.x)使用一个名为 jquery.ondemand
的 javascript 库 - 它跟踪已经包含的文件(一种相当古老的'require.js
'之类的前身 - 仅在没有 AMD 的情况下,并且有 CSS 支持)。
为此,这与 CMS 本身有任何关系的可能性很小 - 考虑到网络本质上是无状态的,并且您用来保存状态的方法在您的服务器之间共享(两者数据库和 session 数据)。
不 在 HA 集群中的各个实例之间共享的是物理文件。这里的原因很可能(但不一定)是提供给 ondemand
的 URI 末尾的 mtime
标记 - 最初旨在避免浏览器缓存在主题更改方面的问题(开发人员制作或以其他方式自动化)。
你肯定检查过的 headers 包括(总是,无论 HAProxy、nginx、ELB 或其他选择的端点如何)X-Include-CSS
和 X-Include-JS
- 其中一个示例如下所示:
X-Include-JS:/framework/thirdparty/jquery/jquery.js?m=1481487203,/framework/javascript/jquery-ondemand/jquery.ondemand.js?m=1481487186,/framework/admin/javascript/lib.js?m=1481487181
[...]
这是在每个请求上,ondemand
可以检查并查看已经包含的内容以及需要添加的内容。
(顺便说一下,这些 header 的大小是导致 nginx
header 缓冲区问题导致 'default' 设置中的 502
的原因。)
那么,怎么办?
如果您正在部署静态代码,静态文件应该在平衡实例之间保持相同的 mtime - 但这是需要检查的。另一方面,生成的文件(例如 Requirements::combine_files
)将需要在所有实例之间(重新)生成同步,就像您站点的所有 /assets
一样,在这种情况下,mtime 应该持续存在。 Zend_cache
不太可能在这里产生任何影响,尽管 APC
可能是一个因素。当然,在任何情况下首先要检查的是我的前提是否成立——例如运行 header 通过差异工具 back-ends 的响应。
为了帮助那些可能遇到这个问题并需要一个挂钩到 CMS 的解决方案的人,我做了以下工作:
class SyncRequirements_Backend extends Requirements_Backend implements Flushable {
protected static $flush = false;
public static function flush() {
static::$flush = true;
}
public function process_combined_files() {
// You can write your own or copy from framework/view/Requirements.php
// Do the required syncing like rsync at the appropriate spot like on successfulWrite
}
}
将 Requirements::set_backend(new SyncRequirements_Backend());
添加到您的 _config.php(我的是一个单独的扩展,但我的网站也可以)。
此解决方案的问题是,如果核心 Requirements_Backend 更新,您将 运行 使用旧版本的代码,但它不太可能破坏任何东西,您刚刚实施了您的代码拥有使用相同代码的需求后端。您可以只调用父级而不是自己完成所有操作,但是我找不到 运行 仅在文件写入时同步的方法,每次请求组合文件时它都会 运行。