Разделы документации

Восстановление после потери PHP-сессий

Как новое поколение PHP начинается после утраты временного состояния — автоматически после перезагрузки сервера или вручную — и как проверить итог без повтора старых форм.

Временное состояние PHP может исчезнуть при перезапуске VPS, Docker или PHP-контейнера. Micator закрывает небезопасное исполнение. После подтверждённой перезагрузки сервера новое поколение PHP-сессий начинается автоматически, в остальных случаях владелец начинает его вручную. Потерянное содержимое сессий этот порядок не восстанавливает.

Внимание.

Ручной порядок относится к контракту PHP format2. Автовосстановление доступно с выпуска 20261101.1, контроллер 20261101, и требует обновления установки. Наличие статьи не обновляет сервер; ручной recovery требует явного согласия владельца на потерю сессий.

Что происходит при потере состояния

Новое приложение проверяет поколение PHP и служебные метки до обработчика. При потере, повреждении или неготовности состояния обработчик не вызывается и POST автоматически не повторяется. Ошибка проверки пула в PHP даёт 503; запрос со старым или недействительным защищённым доступом может получить 404. В прежнем контракте новое поколение запускается вручную. В выпуске 20261101.1 подтверждённая перезагрузка ОС обрабатывается по правилам автоматического восстановления; перезапуск отдельной службы или повтор обновления не запускают автоматическое восстановление. Если PHP-состояние потеряно, нужны ручная проверка и recovery.

При первом закреплении работающих legacy-пулов служба сначала сохраняет устойчивый барьер входящего трафика, затем меняет их runtime restart policy на no без остановки и пересоздания и только потом записывает состояние сохранения PHP. Барьер переживает прерывание или перезапуск ОС между этими шагами: старое приложение не должно получить пустой legacy-пул. Если обновление отклонено или прервано уже после записи состояния, но до начала резервной копии, служба сама снимает барьер (при прерывании — при следующем запуске), пока оба пула ограждены и совпадают с записью: прежнее приложение продолжает обслуживать те же закреплённые пулы. Иначе барьер остаётся, а php-status показывает lost. Если снять барьер при запуске не удалось (например, Docker не ответил), служба не повторяет попытку: барьер остаётся, пока обновление не продолжено командой из раздела ниже, а php-status показывает requires_compatible_release. Не возвращайте прежнюю restart policy и не удаляйте барьер вручную; продолжайте исходную операцию после проверки причины.

Это отказ выполнения PHP с неизвестным состоянием. Он не является причиной самостоятельно выключать приём постбеков или обычные внешние редиректы. Во время самого recovery служба может оградить и перезапустить процессы приложения, чтобы завершить запросы и проверить совместимый код; непрерывность всего трафика этим порядком не обещается.

Пока восстановление держит приложения остановленными, трекер ставит трафик на паузу так же, как при создании копии: ссылки кампаний, локальные лендинги и офферы, приём постбеков и лидов отвечают кодом 503 с текстом Tracker maintenance in progress. Клики и постбеки, пришедшие за это время, не сохраняются. Исходящие постбеки не отправляются и ждут в очереди, разделы панели не загружают данные. Пауза снимается сама, когда совместимые приложения снова запущены, а при старом приложении — когда завершено обновление до совместимого выпуска. PHP остаётся закрытым до завершения восстановления.

Автоматическое восстановление после перезагрузки

С выпуска 20261101.1, контроллер 20261101. Новый контракт автоматически начинает новое поколение PHP после подтверждённой перезагрузки самого сервера. Потерянные сессии и заполненные формы не возвращаются. Старый POST не повторяется; посетитель должен заново открыть ссылку кампании и новую форму. На часть восстановления приложения останавливаются: до их повторного запуска трафик получает ответ 503 об обслуживании, как описано выше.

Служба ждёт запуска приложений и проверяет прежнее состояние, текущий выпуск, PHP-пулы и настройки. Она не вмешивается в установку, обновление, восстановление копии или перенос истории. Изменение файлов, подмена контейнера либо потеря служебной записи требуют проверки администратора. Один перезапуск службы обновлений или отдельного PHP-контейнера сам по себе не разрешает сброс сессий.

Если при перезагрузке Redis остановился раньше сервера обработки, в Redis остаётся запись прежнего процесса. Следующий запуск того же контейнера удаляет её, как только с последнего отклика проходит больше 30 секунд, поэтому такая запись не мешает ни автоматическому, ни ручному восстановлению. Запись пересозданного контейнера так не удаляется, а запись другого сервера обработки удаляет следующий запуск его собственного контейнера. Пока такая запись есть, восстановление отклоняется; она исчезает сама через 24 часа после последнего отклика. Если этот сервер выведен из работы, убедитесь, что он действительно остановлен и не принимает трафик.

Прерванное автоматическое восстановление продолжается с тем же поколением; повторный запуск контроллера не создаёт ещё одно. После успешной проверки служба прекращает повторные обращения к Docker до изменения состояния. Успех или устойчивый отказ появляется в уведомлениях владельца, ход операции сохраняется в журнале службы обновлений.

Проверьте sudo micatorctl php-status: команда печатает одну строку JSON, успешный результат содержит "state":"ready" и "ready":true. Если автоматическое восстановление не завершилось, сохраните журналы и выполните проверки ниже. Ручной php-recover с прежними пятью подтверждениями остаётся доступен; он также позволяет продолжить незавершённую операцию после потери локального ключа. Копия с другого сервера не даёт разрешения автоматически сбросить сессии на этой установке.

Что проверить владельцу

Команду выполняет владелец установки с правами root на сервере управляемой клиентской установки. Перед ней:

  1. Проверьте фактические процессы, слоты, PHP-пулы, ноды и балансировщик. Старый процесс не должен обойти закрытый PHP-контур.
  2. Проверьте HTTPS, CDN и обход кеша для кампаний, hosted-путей и переходов; уберите старые кешированные ответы.
  3. Подтвердите границу отката и восстановления. После recovery нельзя возвращать старое приложение или снимок состояния, который снимает этот барьер.
  4. Проверьте PHP-обработчики и внешнего получателя на тестовой форме.
  5. Примите потерю всех текущих PHP-сессий, а не только одного сломанного пула. Заявки, уже принятые внешним получателем, не нужно повторять.

Старые sess_* не копируются между страницами или поколениями. Cookie PHPSESSID не служит источником восстановления или доказательством владельца файла.

Проверить состояние

До любых действий выполните на сервере:

bash
sudo micatorctl php-status

Это проверка через локальный root-контроллер. Команда печатает одну строку JSON с полями format, state, ready, private_ready, legacy_preserved, legacy_retired, php_epoch, controller_min_version, witness_sha256, а при наличии плана — plan_sha256, start, legacy_until и arm_plan. Она показывает текущее поколение и готовность PHP, в том числе потерю состояния или незавершённую операцию; не создаёт новый epoch и не запускает или продолжает recovery.

  • "state":"ready" и "ready":true — PHP подтверждён; новое восстановление не требуется.
  • lost — прежнее временное состояние больше не подтверждается: пул перезапущен, метка или ограждение потеряны.
  • recovering — готовность ещё не подтверждена. Причиной может быть незавершённый recovery или промежуточная публикация root-плана после arm. Если прерван arm при здоровых пулах, используйте подтверждённый повтор того же arm, а не сброс сессий.
  • requires_compatible_release — для продолжения нужен совместимый подписанный выпуск. Так же отображается прерванное или отклонённое первое обновление с сохранением PHP: работающие legacy-пулы те же, что были закреплены, сессии не потеряны. Подтверждённый php-recover в этом состоянии не создаёт новое поколение и не сбрасывает сессии; с --target-version этого выпуска он продолжает то же обновление (см. ниже).
  • php_epoch и legacy_retired — поколение сессий и выведены ли legacy-пулы из обслуживания. Если присутствует arm_plan, это исходный закреплённый план с ID и датами start/legacy_until. Сверяйте их без продления или создания новых дат.

При здоровом PHP повтор php-recover не создаёт ещё одно поколение и не теряет здоровые сессии. Без незавершённого задания обычный вызов или --target-version с уже установленной версией только возвращает статус. Явный другой target может запустить установку ранее принятого и закреплённого совместимого кандидата, сохранив текущий epoch; этот узкий случай описан ниже. Если уже есть незавершённое recovery-обновление в фазе переключения или фиксации, исходное задание имеет приоритет: повторяйте его target, другое значение не подменяет pending job. Команду нельзя добавлять в автоматику. ready не означает завершённое обновление или открытый трафик.

Ручная команда

Для установки с действующим совместимым приложением:

bash
sudo micatorctl php-recover \
  --inventory-confirmed \
  --cache-confirmed \
  --restore-confirmed \
  --php-confirmed \
  --accept-session-loss

Все пять флагов обязательны. Последний явно принимает потерю сессий. Их нельзя добавлять в автоматический boot-скрипт, cron или обычную команду обновления. Первое фактическое восстановление после потери состояния создаёт durable intent; что делать, если команда прервалась, описано ниже.

Если при запуске восстановления идёт другая операция с паузой трафика — обновление, создание или восстановление копии либо перенос из Keitaro, — php-recover отказывает, ничего не останавливая, и печатает «Local controller refused the operation; the PHP recovery journal is preserved.» Завершите эту операцию и повторите ту же команду.

Служба проверяет приложение и подписанный PHP-runtime, закрывает прежнее исполнение, ждёт завершения обработчиков и создаёт новые private-пулы. Новый PHP epoch относится к сессиям и доступу, а не к версии HTML/PHP-файлов страницы.

Если работает старое приложение

После разрешённого до активации отката могут остаться несовместимые Go-процессы. Recovery в этом случае остаётся закрытым и сообщает requires_compatible_release. Если php-recover уже остановил старое приложение, оно остаётся остановленным до установки совместимого выпуска: служба его снова не запускает, а трафик получает ответ 503 об обслуживании. Нужен проверенный совместимый подписанный выпуск через штатный контроллер:

То же состояние и та же команда применимы, если первое обновление с сохранением PHP было отклонено или прервано до переключения приложения. Подтверждения команды обязательны, но здесь сессии не сбрасываются: обновление продолжается по ранее принятому подписанному комплекту.

bash
sudo micatorctl php-recover \
  --inventory-confirmed \
  --cache-confirmed \
  --restore-confirmed \
  --php-confirmed \
  --accept-session-loss \
  --target-version 0.1.0-beta.20261101.1

Тот же явный вызов с --target-version применим и после отката к старому приложению, когда php-status уже показывает здоровый PHP. Если target отличается от установленной версии, контроллер может запустить только ранее принятый и закреплённый точный подписанный комплект. В этой ветке новое recovery не запускается, epoch и здоровые сессии не сбрасываются, публичный latest-каталог не используется как запасной вариант. Если такого сохранённого кандидата нет, команда отказывает без перехода на другую версию. Это обычное обновление с остановкой: на время переключения возможна пауза трафика приложения, даже если PHP-сессии сохранены. Это не произвольный выбор версии или обход нижней границы отката. compatible_update_job означает запущенное или продолженное задание, а не его завершение.

После первоначального принятия подписанного комплекта контроллер сохраняет и закрепляет его точные байты: архив, подписанный каталог и манифест. Повтор с тем же --target-version может продолжить работу по этому ранее принятому комплекту, даже если в публичном каталоге уже другая версия или прежний каталог истёк. Подписи, хеши и совместимость проверяются снова. Это узкое исключение для тех же закреплённых байтов, а не разрешение использовать любой старый каталог, одноимённый архив или другой источник.

Если сохранённые файлы отсутствуют, изменены или не соответствуют закреплённому кандидату, продолжение закрывается. Не удаляйте кеш, журнал или root-запись и не подменяйте версию ради обхода: сохраните состояние и обратитесь в поддержку.

Какие формы больше не работают

Потеря одного пула требует смены общего PHP epoch. После фактического создания нового поколения из-за потери состояния все прежние защищённые посещения и формы теряют доступ. Установка только сохранённого кандидата при здоровом PHP сама по себе не меняет epoch и не инвалидирует формы этим механизмом. После восстановления из-за потери состояния старые legacy-пулы выведены из обслуживания навсегда; raw POST к прежнему пути, в том числе к ссылке кампании или /clk, не превращается в новый POST и не получает пустую новую сессию.

Чтобы начать новую работу, откройте заново ссылку кампании обычным GET. Она выдаёт новое ограниченное посещение и использует private-сессии, даже если отдельный переход защиты ещё находится в compat. Это явное recovery-исключение к прежнему режиму. Прямой GET на старый PHP-путь не обновляет доступ автоматически.

Сохранённые даты start и legacy_until плана защиты остаются прежними. Recovery не начинает новое 48-часовое окно и не продлевает открытые формы. Ограничение старого отката и in-place restore после нового epoch сохраняется независимо от часов.

Сбой во время recovery

При прерывании повторите ту же подтверждённую команду после проверки причины. Продолжение использует исходный intent, epoch и nonce; новый срок защиты не создаётся. Пока приложение или PHP не готовы, исполнение остаётся закрытым. Не удаляйте журналы операции, метки и файлы состояния и не пересоздавайте контейнеры вручную.

Ручной php-recover, прерванный перезапуском контроллера или перезагрузкой сервера, сам не продолжается: повторите ту же команду. До этого трекер может отвечать 503 (обслуживание), а PHP остаётся закрытым. Исключение — обновление до совместимого выпуска, которое уже дошло до этапа «Создание резервной копии»: его служба обновлений продолжает сама; итог проверяйте в истории операций обновления.

Состояния recovering, lost и requires_compatible_release не означают завершения. ready означает готовность поколения PHP, но не завершение recovery-обновления: оно ещё может переключать приложение или фиксировать итог. Повторяйте ту же подтверждённую команду, чтобы продолжить то же задание и поколение PHP. Значение compatible_update_job — ID запущенного или продолжаемого задания; проверяйте его итог в истории операций обновления. При непонятном состоянии обратитесь в поддержку.

Проверка результата

  1. Дождитесь успешного итога исходного задания обновления, готовности совместимого приложения и private-пулов. Один compatible_update_job или ready этого не подтверждает.
  2. Повторите sudo micatorctl php-status: нужны "state":"ready" и "ready":true. После восстановления из-за потери состояния нужны "legacy_retired":true и новый php_epoch; при установке сохранённого кандидата со здоровым PHP поколение и значение legacy_retired должны остаться прежними. Старое сообщение терминала не является свежей проверкой.
  3. В отдельном браузерном профиле откройте ссылку тестовой кампании, загрузите ресурсы и отправьте новую тестовую форму. Проверьте внешнего получателя.
  4. После смены поколения старое защищённое посещение и старый raw POST должны получить отказ без повторного вызова обработчика. При обновлении со здоровым PHP проверьте сохранение открытой тестовой формы без повторной отправки реальной заявки.
  5. Сверьте исходные даты плана защиты, открытый трафик, статусы редиректов и приёма событий. Не отправляйте реальные заявки повторно ради проверки.

Восстановление после фактической потери состояния возобновляет работу с новыми сессиями. Оно не возвращает содержимое старых форм, корзин, CSRF-состояния или уже утраченных временных файлов.

Обновлено Нужна помощь? ↗