fix(caddy): ретрай подключения к фронту МЕРЫ — остаток окна подмены (#3274, часть 2a/3) #3446

Merged
bot-backend merged 1 commit from fix/3274-part2a-caddy-retry into main 2026-09-11 20:37:58 +00:00
Collaborator

Часть 2a из 3 по #3274 (часть 1 — PR #3442, уже в main). Только caddy/sites/apps.caddy — по фильтру deploy.yml:152-154 это caddy_only=true → джоба deploy-caddy с caddy reload (~1 с), без полного деплоя ПТИЦЫ. Гейт и шаг ci.yml поедут частью 2b, которая не триггерит ни один деплой.

Зачем. Часть 1 свела окно подмены фронта с 30–90 с до ~0,5 с (вынос frontend из общей команды up -d). Остаток — эти самые полсекунды: снипет (tradein_frontend_retry) с lb_try_duration 2s + lb_try_interval 100ms во все 9 блоков reverse_proxy tradein-frontend:3000.

Разворот решения, записанного в теле #3274. Там сказано «чего делать НЕ надо: lb_try_duration» — и для окна 30–90 с это верно, ретрай превратил бы отказ в минутное ожидание. Возражение снято порядком: сначала окно сжато правкой деплоя, и только потом ретрай применим. Отдельный комментарий об этом написан в саму issue.

Проверено исполнением (deep-ревью, caddy validate + разбор JSON конфига на живом caddy:2):

  • покрытие ровно целевое: 9 × tradein-frontend:3000 с try_duration=2s try_interval=100ms; tradein-backend:8000 (2 блока), backend:8000 (3) и фронт ПТИЦЫ — без ретрая;
  • handle_errors 502 503 504 + deploy-window.caddy.snippet не конфликтуют: заглушка отдаётся, просто на 2 с позже;
  • потолок честный: при длительной аварии клиент получает 503 за 2.098 с (без ретрая — 0.008 с).

Неидемпотентный POST не дублируется — проверено отдельно, потому что среди путей есть платежи: при установленном соединении и умершем апстриме апстрим получил POST ровно один раз (клиенту 503 за 0.007 с); дефолтный lb_retry_match повторяет только GET, а при неудавшемся дозвоне запрос апстриму не доставлен вовсе. Плюс платёжные пути идут в tradein-backend, где ретрая нет.

Известный побочный эффект (назван, не спрятан): при lb_try_interval 100ms один GET посетителя может превратиться в до 20 попыток за 2 с — если фронт умрёт уже ПОСЛЕ приёма соединения (начав SSR), это до 20 рендеров и столько же пачек вызовов бэкенда. Дефолт Caddy — 250 мс (8 попыток). Оставляю 100 мс на первый цикл, чтобы покрыть измеренные 0,5 с с запасом; если в логах появится усиление — поднять до 200 мс (10 попыток, то же покрытие, вдвое меньше нагрузки).

Приёмка на проде: docker exec gendesign-caddy-1 grep -c tradein_frontend_retry /etc/caddy/caddy/sites/apps.caddy > 0 (в старой версии символа нет), и в окне следующего деплоя МЕРЫ непрерывная проба scripts/probe-deploy-window.sh по https://meraocenka.ru/ не даёт ни одного не-200 (после части 1 остаётся ~0,5 с, их и должен съесть ретрай).

Откат: caddy-only revert → тот же дешёвый caddy reload.

Часть 2a из 3 по #3274 (часть 1 — PR #3442, уже в main). **Только `caddy/sites/apps.caddy`** — по фильтру `deploy.yml:152-154` это `caddy_only=true` → джоба `deploy-caddy` с `caddy reload` (~1 с), без полного деплоя ПТИЦЫ. Гейт и шаг `ci.yml` поедут частью 2b, которая не триггерит ни один деплой. **Зачем.** Часть 1 свела окно подмены фронта с 30–90 с до ~0,5 с (вынос `frontend` из общей команды `up -d`). Остаток — эти самые полсекунды: снипет `(tradein_frontend_retry)` с `lb_try_duration 2s` + `lb_try_interval 100ms` во все 9 блоков `reverse_proxy tradein-frontend:3000`. **Разворот решения, записанного в теле #3274.** Там сказано «чего делать НЕ надо: `lb_try_duration`» — и для окна 30–90 с это верно, ретрай превратил бы отказ в минутное ожидание. Возражение снято **порядком**: сначала окно сжато правкой деплоя, и только потом ретрай применим. Отдельный комментарий об этом написан в саму issue. **Проверено исполнением** (deep-ревью, `caddy validate` + разбор JSON конфига на живом `caddy:2`): - покрытие ровно целевое: 9 × `tradein-frontend:3000` с `try_duration=2s try_interval=100ms`; `tradein-backend:8000` (2 блока), `backend:8000` (3) и фронт ПТИЦЫ — **без** ретрая; - `handle_errors 502 503 504` + `deploy-window.caddy.snippet` не конфликтуют: заглушка отдаётся, просто на 2 с позже; - потолок честный: при длительной аварии клиент получает 503 за 2.098 с (без ретрая — 0.008 с). **Неидемпотентный POST не дублируется** — проверено отдельно, потому что среди путей есть платежи: при установленном соединении и умершем апстриме апстрим получил POST **ровно один раз** (клиенту 503 за 0.007 с); дефолтный `lb_retry_match` повторяет только GET, а при неудавшемся дозвоне запрос апстриму не доставлен вовсе. Плюс платёжные пути идут в `tradein-backend`, где ретрая нет. **Известный побочный эффект (назван, не спрятан):** при `lb_try_interval 100ms` один GET посетителя может превратиться в до 20 попыток за 2 с — если фронт умрёт уже ПОСЛЕ приёма соединения (начав SSR), это до 20 рендеров и столько же пачек вызовов бэкенда. Дефолт Caddy — 250 мс (8 попыток). Оставляю 100 мс на первый цикл, чтобы покрыть измеренные 0,5 с с запасом; если в логах появится усиление — поднять до 200 мс (10 попыток, то же покрытие, вдвое меньше нагрузки). **Приёмка на проде:** `docker exec gendesign-caddy-1 grep -c tradein_frontend_retry /etc/caddy/caddy/sites/apps.caddy` > 0 (в старой версии символа нет), и в окне следующего деплоя МЕРЫ непрерывная проба `scripts/probe-deploy-window.sh` по `https://meraocenka.ru/` не даёт **ни одного** не-200 (после части 1 остаётся ~0,5 с, их и должен съесть ретрай). **Откат:** caddy-only revert → тот же дешёвый `caddy reload`.
bot-backend added 1 commit 2026-09-11 20:25:23 +00:00
fix(caddy): ретрай подключения к фронту МЕРЫ — остаток окна подмены (#3274, часть 2a/3)
All checks were successful
CI Trade-In / changes (pull_request) Successful in 9s
CI Trade-In / backend-tests (pull_request) Has been skipped
CI Trade-In / browser-tests (pull_request) Has been skipped
CI / changes (pull_request) Successful in 10s
CI Trade-In / frontend-checks (pull_request) Has been skipped
CI / backend-tests (pull_request) Has been skipped
CI / frontend-tests (pull_request) Has been skipped
CI / openapi-codegen-check (pull_request) Has been skipped
5f5bfa8a83
Только caddy/sites/apps.caddy: по фильтру deploy.yml это caddy_only=true →
джоба deploy-caddy с 'caddy reload' (~1 с), без полного деплоя ПТИЦЫ.
Гейт и шаг ci.yml едут отдельной частью 2b, которая не триггерит ничего.
bot-backend merged commit 84920e6cbd into main 2026-09-11 20:37:58 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: lekss361/gendesign#3446
No description provided.