fix(tradein/imv): домовая оценка ходит в сайдкар через пул, а не через чужой env-прокси (#2698) #2708
No reviewers
Labels
No labels
Fable 5 ревью
GG-форсайт
admin
analytics
auth
automation
bug
business
chore
ci
compliance
data
data-moat
docs
duplicate
dx
enhancement
feedback/max
generative
needs-discussion
needs-human
observability
pause-bots
performance
priority/p0
priority/p1
priority/p2
priority/p3
scope/backend
scope/db
scope/devops
scope/frontend
scope/qa
scrapers
security
site-finder
stage/1
stage/2
status/blocked
status/done
status/needs-analysis
status/needs-fix
status/qa
status/ready
status/review
status/wip
tech-debt
tradein
ux
week ревью 1
wontfix
ИРД
вторичка
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference: lekss361/gendesign#2708
Loading…
Add table
Reference in a new issue
No description provided.
Delete branch "fix/2698-imv-outage"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Что чинит
Домовая оценка Авито (
house_imv_backfill) не сохранила ни одной записи с 03.07 — 34 дня, каждый прогон{"saved": 0, "errors": 35, "checked": 50}. Отказ приходил от нашего собственного сайдкара, при этом сайдкар был жив.Корневая причина (с контрольной группой)
backfill_house_imv— единственный avito-путь, который конструировалBrowserFetcherбезproxy_provider/use_pool/environment(house_imv_backfill.py:581; сравнить сorchestration/pipeline.py:519). Без них телоPOST /fetch-jsonуходит без поляproxy→ сайдкар берёт свойSCRAPER_PROXY_URL→ на проде это узел пулаid=1(asocks-residential-1,provider_affinity='domclick'), которыйproxy_pool.acquire('avito')не выдал бы никогда.Контрольная группа в те же сутки, через тот же сайдкар и тот же инстанс камуфокса:
Разница ровно одна — поле
proxyв теле запроса. Побочный эффект той же дыры: запрос безproxyроняет сайдкару желаемый прокси на env →_ensure_browserрелончит камуфокс на каждый дом, сбивая тёплый браузер sweep'ам.Механизм 500 подтверждён живым логом сайдкара (06.08 04:12, тот же env-прокси):
Page.goto: NS_ERROR_PROXY_BAD_GATEWAY→except Exception→ HTTP 500.Второй дефект: причина отказа выбрасывалась
Сайдкар кладёт причину в тело (
{"error": "browser unavailable (proxy may be down)"}), аresp.raise_for_status()печатает только код — ровно эта строка 34 дня лежала вhouses.imv_error_reasonу 1240 домов. Общий_raise_for_sidecar_status(оба эндпоинта,/fetchи/fetch-json) добавляет тело в текст ошибки. Тип исключения прежний (HTTPStatusError⊂HTTPError) → retry-политика не меняется.Test plan
tests/test_2698_imv_sidecar_wiring.py— проводка пула доезжает до фетчера; причина сайдкара доезжает до вызывающего на обоих эндпоинтахtest_search_cache_hit)Что НЕ чинится этим PR
403 от самой площадки (31 дом) и живость единственного исходящего IP — ротация пула ждёт
ASOCKS_API_TOKEN(#2638, пункт 5 в #2704).Часть «честность прогона» из #2698 уже на проде до этого PR — см. комментарий к issue.
Refs #2698
Домовая оценка Авито не сохранила ни одной записи с 03.07 — 34 дня, каждый прогон 35 отказов из 35 попыток. Отказ приходил от НАШЕГО сайдкара (tradein-browser:3000/fetch-json): 1240 домов «503 Service Unavailable» (до 02.08), затем 83 «500 Internal Server Error» и 31 «403 auth rejected» (05.08). При этом сам сайдкар был жив. 1. Проводка пула. backfill_house_imv конструировал BrowserFetcher(source="avito", endpoint=...) без proxy_provider/use_pool/ environment — единственный avito-путь без пула (avito_city_sweep его подключает, orchestration/pipeline.py:519). Без них тело POST /fetch-json уходит БЕЗ "proxy", и сайдкар берёт свой env-прокси SCRAPER_PROXY_URL. На проде это узел пула id=1 (asocks-residential-1, provider_affinity='domclick') — узел, который proxy_pool.acquire('avito') не выдал бы никогда: он отбирает affinity IN (provider,'any'), а последний узел выделенной affinity ещё и защищён от fallback (173_scrape_proxies_add_domclick_affinity.sql). Контрольная группа в тех же сутках: avito_city_sweep и avito_newbuilding_sweep тянули сотни объявлений через ТОТ ЖЕ сайдкар и тот же инстанс камуфокса (01.08: 78/69 и 484/447), пока house_imv_backfill получал 35 отказов из 35. Разница ровно одна — поле "proxy" в теле запроса. Второй эффект этой же дыры: запрос без "proxy" роняет сайдкару желаемый прокси на env → relaunch камуфокса на каждый дом (server.py::_ensure_browser), то есть путь IMV ещё и сбивал тёплый браузер sweep'ам. environment пробрасывается ради #2616 шаг 1: иначе прод-отказ «пул пуст» на этом пути мёртв и фетчер молча уходит на тот самый env-прокси. 2. Причина отказа больше не выбрасывается. Сайдкар кладёт её в тело ({"error": "browser unavailable (proxy may be down)"} / {"error": "Error: Page.goto: NS_ERROR_PROXY_BAD_GATEWAY"}), а resp.raise_for_status() печатает только код: ровно строка «Server error '503 Service Unavailable' for url 'http://tradein-browser:3000/fetch-json'» и лежала 34 дня в houses.imv_error_reason у 1240 домов. Общий _raise_for_sidecar_status в browser_fetcher (оба вызова, /fetch и /fetch-json) добавляет тело в текст ошибки; тип исключения прежний (HTTPStatusError ⊂ HTTPError), retry-политика не меняется. Тесты: проводка пула доезжает до фетчера; причина сайдкара доезжает до вызывающего на обоих эндпоинтах. Прежний parity-тест эндпоинта расширен новыми аргументами (не ослаблен). Не чинится кодом (в #2704): 403 от самой площадки и живость единственного исходящего IP — ротация пула ждёт ASOCKS_API_TOKEN (#2638). Refs #2698done#2698done#2698done#2698done#2698