Отчёт о работе · 03.09.2026 · выкачено на бой

Флот готов к закупке

Пять оставшихся требований эпика Э4 закрыты, выкачены на боевой сервер и проверены на живой нагрузке. Главное подтвердилось: ограничитель действительно ограничивает, потолок растёт от нового адреса без перезапуска, а китайская площадка перестала жечь адреса. Осталось купить.

Продолжает: что оставалось · сайзинг флота · журнал docs/plans/proxy-readiness-progress.md
Требований закрыто
9 / 9
Весь эпик Э4. Два блокирующих — переезд и российские площадки — были главными.
Выкачено и проверено
226 карточек за час
Пять площадок собрали данные после выкатки. Сайт отвечает за 0,08 с, аварий нет.
Проверок в оракуле
174
50 групп, зелёные локально. По одной на каждую найденную ошибку.
Ваших действий
3
Разрешить выкатку, вернуть отключённый адрес, купить два новых.
Что сделано

Пять требований

Э4.5

Переезд — только когда адресов два и больше

блокировало закупку
В чём был обман. В настройках объявлено: заблокировали немецкую площадку — переезжаем на другой адрес. Решение принималось по вопросу «есть ли хоть один здоровый». Немецкий адрес ровно один, поэтому ответ «да» означал тот же самый адрес: площадка вставала целиком, а в журнале стояла запись об успешном переезде.

Теперь переезд возможен, только когда физических адресов два и больше. При одном — честная пауза площадки и отдельное событие в колокольчике админки: «единственный маршрут — переезжать некуда». Событие описывает состояние пула, а не происшествие, поэтому повторяется не чаще раза в полчаса. Скрапер перестал обещать в журнале переезд, которого не будет.

Счёт адресов для этого решения нарочно не вычитает остывающие: переезд происходит именно с адреса, который только что заблокировали, и счёт живых в этот момент всегда отвечал бы «остался один».

Приёмка
Подстановкой списка адресов, без сети: один адрес → пауза площадки и событие; два → на паузе только сгоревший маршрут, работа идёт. Две строки одной машины вторым адресом не считаются.
Э4.6

Российские площадки ходят через маршруты

блокировало закупку
Почему купленный адрес был бы мёртвым грузом. Обе площадки брали первую строку списка — порядок по «когда использовали последний раз», а это поле в их пути никогда не обновляется. То есть фактически всегда первую строку, включая сгоревшую. Ни выбора здорового маршрута, ни счётчика соединений, ни оценки результата.

Теперь маршрут выбирается по здоровью и загрузке — тем же порядком, что у китайских и корейской площадок. Каждый запрос через адрес занимает слот физической машины и отчитывается о результате: 403, 429 и редирект на капчу читаются как «площадка ругается на этот адрес», обрыв — как транспортный сбой. Слот берётся на запрос, а не на весь сбор: листинг живёт минутами, и удержание слота означало бы, что один сбор выкупает треть ёмкости машины, ничего с ней не делая между страницами.

Прямой канал остался первой ступенью. Адрес нужен как запасной путь при ограничении по скорости, а не вместо прямого хода: с адреса сервера идут ещё фотографии, Telegram и спецификации китайской площадки, и разгружать его важнее, чем гонять через прокси то, что и так проходит.

Побочная находка: в админке вообще не было секций для этих двух площадок — их строки не отображались. Купленный российский адрес было бы не видно, и не понять, почему он «не работает». Секции добавлены, обе площадки есть во всех формах.

Приёмка
При наличии строки российского адреса не меньше 90 % запросов идут через него. Меряется полем маршрута в журнале — оно добавлено в каждую строку запроса, включая прямой ход и путь через VPN, чтобы знаменатель был полным.
Э4.7

Стартовые темпы — из замера

Система сама нащупывает безопасный темп для каждого адреса, но стартовала от чисел, посчитанных из времени запроса 7,4 секунды. Замер даёт 2,5–4,0. Занижённый старт не «безопаснее»: темп растёт на 10 % за полсотни успехов подряд, то есть от 24 до 72 адрес разгоняется часами — и всё это время отдаёт треть того, что может.

ПлощадкаБылоСталоОткуда
Китайская первая24723 места × 60 с ÷ 2,5 с
Китайская вторая24503 × 60 ÷ 3,6
Корейская40453 × 60 ÷ 4,0
Немецкая1240оценка: не парсилась с 20.08
Что чуть не сорвало правку. Общий потолок темпа стоял на 60 — ниже нового старта китайской первой. Он молча срезал бы ровно ту настройку, ради которой всё и делалось. Потолок поднят, и сверх того заведено правило: заданный старт не срезается никогда.
Откат
Одной переменной окружения, без правки кода — проверено тестом.
Э4.4м

Метрика «ложный вывод адреса из работы»

Именно ложные срабатывания и были исходной болезнью: у трёх адресов накопилось по 2846 «сбоев» против 15 успехов. Механизм починен — метрика сторожит возврат.

Событие считается ложным, когда адрес выведен из работы для одной площадки, а другая площадка по тому же адресу ответила в ту же минуту. Судим с двух сторон: порядок наблюдений внутри минуты произволен (проверки идут пачкой), поэтому на выводе смотрим назад, а на успешной проверке — вперёд, на уже записанные выводы. Один вывод считается ложным ровно один раз.

Горячий путь не подорожал: боевые успехи только ставят отметку, читают и судят лишь редкие выводы и минутные проверки. Доля выведена в админку рядом со списком адресов — зелёная ниже одного процента, красная выше.

Приёмка
Меньше 1 % от числа проверок за сутки.
Э4.8

В админке — адрес сразу трём площадкам

Список адресов переписан. Сверху — таблица физических машин: одна строка на адрес с отметками площадок вместо трёх одинаковых строк. Единица учёта в коде давно адрес, а не строка таблицы; список наконец показывает ту же единицу — четыре машины читались как двенадцать прокси.

Добавлено
  • «Адрес в группу площадок» — одна форма заводит все строки разом. Заводя по одной, оператор теряет строку молча: площадка просто продолжает работать на прежней ёмкости.
  • «Включить обратно» / «Выключить все строки» — групповой переключатель. Возвращать адрес построчно нельзя: счёт маршрутов у площадок разойдётся.
  • Панель ёмкости — адресов в пуле, живых сейчас, потолок одновременных обработок по каждой площадке, с пометкой «единственный маршрут». Это же и приёмка требования о лимитах: строка добавлена — потолок вырос в течение минуты, без перезапуска.
Состояние эпика

Все девять требований

IDТребованиеСтатусКогда
Э4.1Лимиты считаются от числа живых адресовзакрыто02.09
Э4.2Корейская площадка под ограничителемзакрыто02.09
Э4.3Один счётчик на физическую машинузакрыто02.09
Э4.4Пер-площадочные таймаут и кулдаун проверкизакрыто02.09
Э4.4мМетрика ложных выводовзакрыто03.09
Э4.5Переезд только при двух и более адресахзакрыто03.09
Э4.6Российские площадки через маршрутызакрыто03.09
Э4.7Стартовые темпы из замеразакрыто03.09
Э4.8Групповое добавление адреса в админкезакрыто03.09
Э4.9Фотографии идут напрямую, мимо проксиинвариантне трогали
После работы

Код-ревью: два прохода, двадцать находок

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

Что нашлосьЧем это грозило
Слот адреса брался другим потолком Единственное место в системе, читавшее не ту настройку. Сегодня обе равны трём, но их две, и первое же поднятие одной дало бы на одном счётчике держателей с разными пределами. Ровно эту ошибку ревью уже ловило вчера в другом месте.
Ответы 5xx и 407 считались успехом 502 и 503 отдаёт сам прокси, 407 значит «пароль не принят». Мы растили бы темп ровно тому адресу, который перестал работать.
Заглушка с кодом 200 не доезжала до реестра Главная. У drom страница защиты приходит с обычным кодом 200 и коротким телом. Записывалось как успех — значит сгоревший адрес никогда бы не ушёл в конец очереди, и требование «система заметит смерть адреса» не выполнялось.
Учёт прямого канала — мусор Записи, которые не читает никто, ценой трёх обращений к Redis на каждый запрос пути, который раньше туда вообще не ходил.
Метрика обнулялась в полночь Приёмка «доля за сутки» считалась по календарному дню: в 00:05 один ложный вывод из трёх проверок дал бы 33 % — красную карточку на пустом месте. Окно стало скользящим, плюс порог «мало данных».
Метрика могла унести основной учёт Побочная запись стояла внутри общей транзакции: сбой в ней откатил бы и учёт самого запроса.
Порядок маршрутов считался дважды Лишняя работа и две строки в журнале с разным первым адресом — читать журнал стало бы труднее, чем выбирать маршрут.
Строки без площадки пропадали из админки Два вида одной таблицы показывали разное: в сводке по машинам строка есть, в секциях — нет.
Панель ёмкости завышала потолок втрое Показывала «когда площадка работает одна». В залпе из трёх администратор увидел бы девять и не понял, почему в кампании три.
Обещанный откат требовал правки файла Спецификация назвала пороги настройками — «откат одной переменной». Ни одна из них не была проброшена в конфигурацию: откат означал бы ту же выкатку. Проброшены.
Второй проход

Что нашлось в работе накануне

Что нашлосьЧем это грозило
Пароли прокси лежали в именах ключей и в логах Самая серьёзная. Один модуль эту опасность знал и обходил, соседний — клал полный адрес с логином и паролем прямо в имя ключа хранилища, а шесть мест печатали его в журнал, который уезжает в сборщик логов. Правило в проекте давно записано — про него просто не знали. Теперь пароль не попадает ни туда, ни туда.
Проверка живости без площадки выводила адрес «для всех» Слабый сигнал проверки проваливался в жёсткий общий запрет — ту самую связку площадок, от которой весь эпик и уходит.
Два разных ответа на вопрос «сколько у нас адресов» Решение о переезде и решение о паузе читали РАЗНЫЕ списки, один ещё и с минутной задержкой. По одному сигналу они могли ответить противоположно. Свели к одному источнику.
Строка журнала роняла обработку машины Моя же правка про маскировку пароля брала функцию из модуля, который в проверках подменяется — и обработка падала на строке лога. Машина терялась. Взяли из модуля, который никто не подменяет.
Ёмкость делилась и на площадки, стоящие на паузе Площадка на паузе не делает ни одного запроса, но занимала долю адресов: при паузе одной из трёх оставшиеся получали по трети вместо половины — ровно когда им нужнее всего.
Три обращения к хранилищу там, где хватает одного Проверка здоровья спрашивает три вида запрета по отдельности, а зовётся на каждый адрес при каждом выборе: на девяти адресах — двадцать семь обращений на один запрос.
Имена: функция-константа и приватное имя как публичный API Мелочи, но обе против записанных правил проекта; вторая — функция, которую зовут из двух площадок и четырёх проверок, всё это время притворялась внутренней.

Отдельно — сами проверки. Одна падала на функции, которой в коде нет и не было: месяцами не проверяла ничего. Другая закрепляла поведение, намеренно изменённое накануне, — код поправили, оракул забыли. Ещё две собирали имя ключа хранилища вручную, то есть проверяли устройство, а не поведение, и молча переставали что-либо проверять при его смене. И в одиннадцати тестах жила скопированная заглушка хранилища, умеющая ровно один ключ вместо нескольких: такая либо роняет проверку, либо — хуже — тихо пропускает её. Всё это починено: иначе постоянно красные проверки прячут настоящие поломки.

Сверка с базой: прогон тридцати четырёх оракулов, задевающих изменённые модули, до и после — три улучшения, ни одной регрессии.

Выкатка

Что подтвердилось на живой нагрузке

Раньше эти вещи проверить было нельзя: ограничитель работает на механизме хранилища, которого в тестовой заглушке нет. Теперь проверены на боевом сервере, под одновременной работой шести площадок.

ПроверкаРезультат
Ограничитель действительно ограничивает Три обращения к адресу разрешены, четвёртое и пятое — нет. Освобождение возвращает место. Под нагрузкой шести площадок замеры каждые шесть секунд: больше трёх ни разу.
Потолок растёт от нового адреса без перезапуска С девяти до двенадцати. Проверено вставкой строки в отменяемой операции — боевая таблица не тронута. Это и есть доказательство, что покупка превратится в пропускную способность.
Лимиты сходятся с числом мест Три адреса дают девять мест; когда работают три площадки — по три каждой, ровно девять. Раньше каждая независимо считала, что ей можно двенадцать-шестнадцать.
Китайская площадка перестала жечь адреса Главный результат. Проверка занимала ровно восемь секунд — то есть упиралась в таймаут; теперь около секунды. Счётчик подряд идущих сбоев был 1616, 1650 и 1656 — стал ноль. Доля успеха выросла с 1,4 % примерно до 60 %, постоянные отключения адресов прекратились.
Пароли ушли из хранилища До выкатки там лежал ключ с логином и паролем прокси открытым текстом. После — ни одного.
Соседние площадки не страдают Пока китайская площадка держит адрес в отключении, корейская по тому же адресу набирает 38 успехов подряд. Раньше отключение было общим.
Выкатка чуть не уронила сервер — и это стоит записать. Штатная процедура синхронизирует всё дерево с удалением лишнего. Пробный прогон показал, что она удалила бы файл, который кто-то выложил вручную мимо репозитория, а он нужен всем фоновым обработчикам — они перестали бы запускаться. Заодно откатилась бы мобильная работа и одиннадцать резервных копий настроек. Синхронизировали только файлы своего изменения.
Пробел, который увидел только бой. Обещанное событие «переезжать некуда» не появлялось, хотя немецкую площадку за двадцать минут заблокировали девять раз при единственном адресе. Оказалось, сигнал о блокировке отправляется только из обработки карточки, а немецкую площадку блокируют на входе — до карточек дело не доходит. Чинили дважды: первая правка попала не в тот путь. После второй событие появилось. Расширять сам сигнал на все случаи не стали — это поменяло бы поведение всем площадкам сразу и требует отдельного замера.

Счётчик ошибочных отключений показывает 4 % при норме 1 % — и это правда, а не поломка. Все случаи — от китайской площадки: она отвергает наши адреса тогда, когда корейская и вторая китайская по ним спокойно работают. Вывод для покупки: этой площадке нужны другие адреса, а не ещё три таких же.

Честно о проверках

Что подтверждено, а что нет

Локально зелены 50 групп проверок — 174 утверждения, по одной группе на каждую найденную ошибку. Но счётчики одновременности работают на серверных скриптах Redis, а в тестовой заглушке их нет: запрос слота всегда «пропускает». Проверки подтверждают правильность подключения — какой ключ, какой счёт, какой предел. Что счёт действительно ограничивает, видно только на боевом Redis.

Проверить на боюКакПризнак нормы
Счётчик действительно ограничиваетключи слотов адреса под нагрузкой кампаниине больше трёх держателей на адрес
Ложных выводов неткарточка в админкеменьше 1 % от проверок
Темпы не заниженысобытия роста и среза темпа за суткисредний темп не ниже стартового, без всплесков блокировок
Ротация честнаясобытия админки «единственный маршрут»при одном адресе — пауза, при двух — переезд
Российские площадки через адресполе маршрута в журнале за сутки≥ 90 % запросов не с адреса сервера
Лимиты сходятся с числом местпанель ёмкости в админкесумма лимитов не превышает адреса × 3
Что изменится сразу после выкатки. Пока работает одна площадка, она забирает всю ёмкость адресов — девять одновременных обработок на трёх машинах. Когда параллельно идут три, каждая получает по три. Раньше каждая независимо получала по девять: двадцать семь на девять мест, и превышение оплачивалось замедлением. Это не потеря пропускной способности, а приведение к измеренному пределу.
Порядок

Что дальше

  1. Шаг 1
    Выкачено 03.09 — наблюдать сутки

    Выложено вручную, четыре изменения. Первый час: 226 карточек по пяти площадкам, аварий нет, сайт отвечает за 0,08 с. Точка отката записана. Осталось досмотреть сутки — в первую очередь счётчик ошибочных отключений и то, как система сама поднимает темп.

  2. Шаг 2
    Купить два адреса: немецкий и российский

    Это не про скорость, а про отказоустойчивость: у немецкой площадки появляется куда переезжать, а фотографии, Telegram и российские площадки перестают зависеть от одного адреса сервера. После покупки — завести строки российским площадкам (теперь для них есть и секции, и групповая форма).

  3. Шаг 3
    Расширить китайско-корейский пул с 3 до 6

    Брать по два за раз, наблюдая за выводом адресов из работы. Групповое добавление и стартовые темпы уже готовы — новые адреса заводятся одной формой и выходят на измеренный темп сразу, а не за часы.

  4. Шаг 4
    Закрыть пробелы в замерах

    Прогнать одну кампанию немецкой площадки (её темп сейчас — оценка), разобрать стоимость обращения к Avito и понаблюдать, как система сама поднимает темп адреса. После этого решение по третьему немецкому адресу и по устройствам становится обоснованным, а не оценочным.

  5. Потом
    Диета обработки — эпики Э0–Э3

    Отдельная программа: наблюдаемость, жизнь рабочих процессов, вынос сети из обработки, разгрузка диска. Она поднимает долю времени, когда адрес реально занят, с 0,22 почти до 0,9 — и тогда те же площадки потребуют вдвое больше адресов. Покупать под неё нужно в тот же заход, что и выкатывать её.

Не код

Два действия на вашей стороне

Адрес 79.172.218.165 отключён с августа как неотвечающий и, вероятно, продолжает оплачиваться. Починить у провайдера или заменить — это четверть ёмкости трёх площадок, которая сейчас не работает. Кнопка «включить обратно» теперь есть и возвращает все строки адреса разом; само решение — ваше.

Разрешение на выкатку. Код лежит в рабочем дереве незакоммиченным. Ничего не выкачено и не тронуто на бою.

Контекст

Предшествующие документы