render-service: умное ожидание вместо фикс-пауз. 2ГИС карточка 7.2 -> 1.6с, поиск 17 -> 5с, Яндекс-карточка 6.5 -> 2.8с. Качество проверено вживую. шаг 2: таймаут открытия сайта 45 -> 15с, убран лишний повтор, карточки 2ГИС пачкой htmlBatch. Полнота сохранена, скорость выросла. доки: ранбук выката рендер-виртуалки, фаза 8. Ветка worktree-avtopodbor, не прод. Тесты 459/459, Pint чист. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Рендер-сервис 2ГИС/Яндекс (замена xf4)
Маленький Node+Playwright сервис для выделенной виртуалки. Портал (Лидерра) зовёт его по HTTP как xf4 — он рисует страницу с маскировкой через прокси и отдаёт данные. Ни базы, ни Redis, ни денег — только рендер (топология Б, см. docs/superpowers/specs/2026-07-05-self-render-2gis-yandex-channel-design.md).
Что делает
- Постоянный браузер, на каждую страницу — свой контекст (куки + прокси).
- Маскировка под живой Chrome + museum double-tap для поиска 2ГИС (иначе запрос уходит в мусор — см. findings-спайк).
- Отсечка картинок/шрифтов/медиа (экономит трафик прокси и время).
- Для 2ГИС отдаёт
window.initialState(портал разбираетTwoGisJsonReader), для Яндекса/сайтов — HTML.
Контракт
POST /render заголовок X-Render-Key: <секрет>, тело { "url": "...", "type": "initialState"|"html" } → { "data": "<initialState|html>" }. Ошибка → { "data": "" } (портал не роняем).
GET /health → { ok, active, max, proxies }.
Переменные окружения (только в .env виртуалки, не в гит)
| Env | Смысл | Дефолт |
|---|---|---|
PORT |
порт сервиса | 8790 |
RENDER_KEY |
секрет портал↔виртуалка (совпадает с SELF_RENDER_KEY портала) |
— (пусто = 401) |
MAX_CONCURRENCY |
сколько браузер-контекстов разом (по памяти, ~350 МБ/контекст) | 4 |
PROXIES |
пул прокси через запятую: http://user:pass@host:port,host:port |
пусто (без прокси) |
Прокси — Proxy.Market (mobile-static)
После оплаты в дашборде берём для порта: host, port, login, password.
🔴 Только HTTP-эндпоинт, НЕ SOCKS5. Playwright умеет авторизацию прокси (user:pass) лишь для HTTP/HTTPS — у SOCKS5 авторизация не поддерживается (тихо не подключится). У Proxy.Market для порта обычно есть оба протокола — берём HTTP.
Формат в .env виртуалки:
PROXIES=http://login:password@host:port
Несколько портов — через запятую (тогда round-robin по ним). Один мобильный порт = один IP за раз; для нашего объёма (5–6 прогонов/день) этого хватает — мобильный IP высокодоверенный. Смена IP у мобильных — по ссылке-ротатору из дашборда (опционально, на будущее; сейчас не требуется).
Запуск
npm install # ставит playwright
npx playwright install chromium
RENDER_KEY=... MAX_CONCURRENCY=16 PROXIES=... npm start
npm run smoke # проверка на живом 2ГИС (без прокси)
На стороне портала
.env: SELF_RENDER_ENDPOINT=https://<виртуалка>/render, SELF_RENDER_KEY=<тот же секрет>, флаг AUTOPODBOR_SELF_RENDER=true. Откат — флаг в false (мгновенно назад на xf4).