SilverStripe за балансировщиком нагрузки

У меня есть экземпляр SilverStripe, работающий на двух серверах за балансиром нагрузки AWS. Чтобы поделиться информацией о сеансе, я запускаю сервер Elasticache Redis. Я устанавливаю информацию своего магазина php как таковую:

ini_set('session.save_handler', 'redis'); ini_set('session.save_path', 'tcp://127.0.0.1:6379'); 

После того, как я вошел в раздел администрирования CMS, я могу перепрыгнуть между серверами, и он помнит меня, однако при переключении между разделами в CMS основной раздел не отображает (вызов AJAX). Из того, что я могу сказать, что другой сервер не понимает (который когда-либо запрашивался со второго), у вас уже есть администратор CMS, и в заголовках ответов говорится, что загружает новую версию зависимостей JS, которая затем выворачивает администратор, и это не загружается.

Чтение в документах SilverStripe использует Zend_Cache для получения дополнительной информации. Я полагаю, что если я загружу интерфейс администратора, а затем удалю каталог кэша, он будет реплицировать проблему. Это не так.

Затем я попытался использовать этот модуль для изменения механизма хранения, используемого 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 и это хранит некоторую информацию cms в redis, как для ключа CMSMain_SiteTreeHints9b258b19199db9f9ed8264009b6c351b , однако это все еще не устраняет проблему смены серверов в сбалансированной нагрузке среде.

Где еще SilverStripe может хранить данные кеша? Правильно ли я реализовал модуль?

    Интерфейс администратора по умолчанию (при условии, что вы используете 3.x) использует библиотеку javascript, называемую jquery.ondemand – это файлы треков, которые уже были включены (довольно древний вид предшественника подобных « require.js » – только без AMD и поддержка CSS).

    С этой целью вероятность того, что это имеет какое-либо отношение к самой CMS, минимальна – учитывая, что веб по своей природе является апатридом и что метод, который вы используете для сохранения состояния, используется на всех серверах (как базы данных, так и данные сеанса) ,

    То, что не разделяется между отдельными экземплярами вашего кластера HA, – это физические файлы. Причина здесь, скорее всего, (но не обязательно) – быть mtime в конце URI, предоставленной в ondemand – изначально предполагалось избежать проблем с кешированием браузера в отношении изменений темы (разработчик был сделан или иным образом автоматизирован).

    Заголовки, в которые вы не сомневаетесь, включают ( всегда , независимо от конечной точки, выбранной 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 может проверять и видеть, что уже включено, и что нужно добавить.

    (Кстати, размер этих заголовков является причиной проблем с буфером заголовков nginx вызывающим 502 в настройке по умолчанию.)

    Итак, что делать?

    Статические файлы должны поддерживать одно и то же время между сбалансированными экземплярами, если вы развертываете статический код, но это то, что нужно проверить. Сгенерированные файлы с другой стороны (например, с Requirements::combine_files ) должны быть синхронизированы при генерации (повторного) между всеми экземплярами, как и все /assets для вашего сайта, и в этом случае mtime должен сохраняться. Zend_cache вряд ли будет иметь какое-либо влияние здесь, хотя APC может быть фактором. Конечно, первое, что нужно проверить в любом случае, заключается в том, действительно ли моя предпосылка верна – например, для запуска ответов заголовков с обоих сторон через инструмент diff.

    Чтобы помочь тем, кто может столкнуться с этим, и нужно решение, которое подключается к 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 (мой – отдельное расширение, но mysite тоже будет работать).

    Проблема с этим решением заключается в том, что если в Core Requirements_Backend вы будете использовать более старую версию кода, но вряд ли что-то сломает, вы только что внедрили свой собственный бэкэнд требований, который использует тот же код. Вы могли бы просто вызвать родителя вместо того, чтобы все это делать самостоятельно, но я не мог найти способ запуска синхронизации только при записи файла, он будет запускаться каждый раз, когда будет запрошен комбинированный файл.