Миграция с Sonatype Nexus: как мы переписали код, сломали API и всё равно достигли цели


Обычное рабочее утро, вы — администратор инсталляции Nexus — открываете ноутбук, чтобы проверить состояние артефактов и убедиться, что сборки проходят штатно. Но вместо привычного списка артефактов видите красный баннер:

Всё, Nexus заблокировал запись. Разработчики не могут загрузить новую сборку, конвейеры падают один за другим, а коллеги смотрят недобрым взглядом.
Если представить, что такое происходит не на тестовом стенде, а в реальном проде — это кошмар. Особенно в большой компании, где таких экземпляров могут быть десятки, и каждый из них — критический элемент процесса разработки.
Меня зовут Кирилл Быков, я владелец продукта Platform V Works::Artifactory — менеджера репозиториев артефактов и контейнеров. В Сбере он уже заменил собой иностранный Sonatype Nexus во всех инстансах. Банк — это ключевой заказчик и среда, в которой мы выполняли миграцию, о которой я расскажу.
При проектировании продукта нашей команде пришлось решить целый набор «задач со звездочкой». Нужно было сделать так, чтобы миграция проходила бесшовно: без переучивания разработчиков, без перестройки CI/CD, и чтобы в случае проблем всегда оставалась возможность откатиться на старый Nexus, от которого мы сделали форк.
Ниже расскажу, что у нас получилось и на какие грабли мы наступили.
Как Sonatype Nexus закрутил гайки
Всё началось с версии 3.66.0 — именно тогда Sonatype впервые добавил в Nexus OSS индикаторы для отслеживания количества компонентов и запросов. Мы могли видеть приближение к неким порогам, но это были лишь «лампочки» на приборной панели.
До версии 3.76.1 включительно Nexus OSS показывал лимиты только как намёк. Превысил 100 000 компонентов или 200 000 запросов? Получал жёлтое предупреждение, но продолжал работать, поэтому мы почти не задумывались об этих числах.
Всё изменилось с выходом 3.77.0. Лимиты стали жёсткими: 100 000 компонентов и 200 000 запросов в день. Превысил — запись блокируется.
Форумы взорвались. Люди писали, что пытались купить лицензию, но Sonatype предлагал только дорогой enterprise без реальной поддержки, а значит приобретение лицензии не имело смысла.
А потом правила ужесточили снова. На момент написания этой статьи официальный Usage Center Sonatype фиксирует 40 000 компонентов и 100 000 запросов в сутки. Такие значения — смертельный приговор для любого enterprise‑проекта. У нас на одном инстансе было больше 10 миллионов компонентов. Мы просто не могли обновиться до 3.77+ — это гарантированно убило бы разработку.
Но и сидеть на старой версии без патчей было рискованно.
Подготовка первого прототипа: от форка к рыночному продукту
У нас был рабочий форк Nexus public. Но форк — это ещё не продукт.
Первое, что мы сделали — привели фронтальную часть в соответствие с корпоративным стилем Сбера. Интерфейс не должен был выглядеть чужеродным, это важное условие приёмки продукта в банке.
Потом определили список доработок, необходимых для запуска первого прототипа, определили облик и стратегию продукта. Мы смотрели в первую очередь на текущие потребности и рабочие процессы заказчика:
какие типы репозиториев и форматов артефактов нужны;
как встроить продукт во внутренние DevOps‑процессы (без переписывания пайплайнов);
какие дополнительные фичи (например, ГОСТ‑подписи) сделать, чтобы пилот закрывал реальные задачи.
Только реализовав все пункты из списка, мы получили согласие на развёртывание пилотного инстанса. Началось самое сложное: как провести миграцию так, чтобы в любой момент можно было откатиться на старый Nexus и чтобы разработчики ничего не заметили.
Наше решение: бесшовная миграция
Нельзя просто взять и попросить Сбер на денёк приостановить работу, пока мы тут мигрируем. Поэтому пошли не по пути «вырезать и заменить», а по пути эволюции.
Вот три правила, на которые мы ориентировались в процессе:
Никаких изменений для разработчиков: те же URL, команды, плагины CI/CD.
Миграция без копирования: не копируем терабайты артефактов. Останавливаем Nexus, поднимаем Artifactory на той же базе данных и дисках.
Откат всегда возможен как на старый Nexus, от которого был сделан форк, так и между нашими версиями.
На практике разработчик продолжает работать как обычно, с привычными скриптами и командами. DevOps не копирует терабайты артефактов и не покупает новое железо. Всё, что нужно, — остановить Nexus, запустить Artifactory. Никаких дополнительных расходов на инфраструктуру. Просто переключили — и поехало.
Откат — не магия, а инженерия
Мы подготовили, протестировали и предоставили SQL‑скрипты отката с подробным описанием для каждой версии продукта. Особое внимание уделили возможности отката на базовую версию Nexus 3.76 — ту, с которой банк начинал.
Каждый скрипт решает три задачи:
Откат схемы БД: удаление новых индексов, колонок и ограничений, которые появились в новой версии.
Восстановление прежней структуры: создание индексов и таблиц в том виде, в котором их ожидает старый Nexus.
Очистка служебных таблиц: удаление записей о миграциях из
flyway_schema_history, чтобы система при следующем запуске не пыталась применить их снова.
Мы тестировали эти скрипты многократно: останавливаем Artifactory, выполняем скрипт отката, ставим старый Nexus 3.76 — он подхватывает базу и работает.
Как мы откатываемся между своими версиями
Возьмём реальный пример: обновились до версии 2.13.0, а через несколько часов обнаружили критическую проблему. Нужно вернуться на предыдущую версию (например, 2.12.0).
Важно: перед откатом удаляем SAML и OAuth2-возможности, если они существуют. Затем выполняем шаги:
Останавливаем Artifactory.
Удаляем новый индекс, созданный в миграции:
DROP INDEX IF EXISTS uk_capability_storage_item_type_properties;Восстанавливаем старый индекс:
CREATE UNIQUE INDEX IF NOT EXISTS uk_capability_storage_item_type_props ON capability_storage_item(type, property);Удаляем колонки из
saml_user:ALTER TABLE saml_user DROP COLUMN IF EXISTS link_session, DROP COLUMN IF EXISTS end_session_on;Для отката внесенных изменений потребуется удалить записи миграций из таблицы flyway_schema_history. Это позволит системе повторно применить изменения, если возникнет необходимость вернуться к предыдущей версии. Можно использовать следующий SQL‑код для удаления соответствующих записей:
DELETE FROM flyway_schema_history WHERE description = 'SamUserDatabaseMigrationStep';Заменяем бинарники на предыдущую версию, запускаем снова.
Инцидент: как мы сломали API из‑за стандарта и вернули как было

В СберТехе действуют внутренние стандарты на форматы HTTP‑ответов. Один из них гласит: неасинхронный метод «создать» должен возвращать статус 201 Created, но не 200 OK.
Мы взяли метод POST /v1/security/roles “Create role” — создание роли. Раньше он честно возвращал 200 и тело с созданной ролью. Мы переписали его на 201 без тела. Красиво, по стандарту.
Катим пилот.
Через несколько часов получаем жалобу: внутренняя система управления доступом перестала создавать роли. Смотрим логи: клиентский код парсит ответ, ожидая тело с ролью, а получает пустой 201 и падает с NullPointerException.
Мы откатили изменение и вернули 200.
Намотали на ус: даже «правильный» стандарт не стоит того, чтобы ломать обратную совместимость. И теперь проверяем API на обратную совместимость перед выпуском каждого релиза, а также создаём v2 API для некоторых методов, чтобы добавлять, изменять, улучшать и соответствовать стандартам. При этом оставляем версию v1 для полной обратной совместимости со старыми клиентами.
Стратегия: поддерживать апстрим или отходить?
Любой форк рано или поздно сталкивается с вопросом: идти в ногу с новыми версиями оригинального продукта или окончательно откалываться? У нас нет универсального ответа, но есть свои критерии для ориентира.
Когда есть смысл синхронизироваться с апстримом:
Используются только незначительные кастомные доработки.
Лицензия апстрима позволяет вливать изменения обратно.
Есть ресурс на постоянный backport патчей безопасности.
Когда проще и дешевле отойти:
Апстрим резко меняет архитектуру (например, переход с OrientDB на PostgreSQL) и ломает обратную совместимость.
Вендор вводит жёсткие лимиты или меняет лицензию на проприетарную.
Собственные фичи становятся настолько глубокими, что каждый ребейс превращается в ад.
Мы совместили подходы: ядро осталось совместимым с Nexus 3.76, чтобы сохранить откат, а новые функции (бесшовная миграция, работа с blob‑хранилищами) развиваем сами. Крупные обновления апстрима пока не берём — слишком велик риск сломать банковские интеграции.
Но думаем, что в отсутствие жёстких ограничений можно периодически оценивать стоимость синхронизации. Иногда просто остаться на стабильном форке и забыть про бесконечную гонку версий — самое прагматичное решение, особенно когда речь идет об обработке и закрытии уязвимостей, которые в форке можно контролировать самостоятельно.
Итоги: бесшовная миграция состоялась
Мы перевели все инстансы в банке на Platform V Works::Artifactory. Но самый волнительный момент — первый пилот на первом инстансе. Выполнив все необходимые действия по развёртыванию, мы получили такие графики из нашей Grafana (апрель‑май 2025). На всех остальных инстансах картина повторилась без сюрпризов. Память Java (использование Heap):

Использование Old Gen:

Потоки JVM (состояния runnable, blocked, waiting и др.):

Потоки Jetty (обработка HTTP‑запросов):

Все графики подтвердили: даже самый первый, самый рискованный шаг прошёл без ущерба для производительности и доступности. Значит, и остальные инстансы можно было переводить спокойно.
Кстати о производительности. Мы не только сохранили её на уровне до миграции, но и продолжаем улучшать. О том, как мы перешли на Java 17 и Z Garbage Collector и сэкономили ресурсы, можно почитать в отдельной статье: «Как переход на Z Garbage Collector в Java 17 сэкономил нам ресурсы: на примере хранилища артефактов».
Итоговые масштабы миграции:
проектов — 15 тыс.;
артефактов — 56 млн;
объём данных — 2,3 Пб;
пользователей и сервисных учетных записей — около 500 тыс.
Разработчики ничего не заметили, CI/CD не перестраивали, скрипты не правили. Аналогичные сценарии мы успешно отработали и за пределами Сбера. Ряд внешних заказчиков, включая крупные страховые и финансовые компании, подтвердили, что подход с бесшовной заменой Nexus работает в их инфраструктурах без потери производительности и безболезненно для команд разработки.
Вместо заключения
Вcё началось с нашей интуиции: мы заранее видели риски зависимости от вендора. Красный баннер в Nexus лишь ускорил решение, которое уже назревало.
Главный урок этой миграции прост: если заранее продумать откат и не ломать API без крайней необходимости, то замена центрального элемента инфраструктуры может пройти незаметно для разработчиков.
Сегодня Platform V Works::Artifactory работает во всех экземплярах в СберЕ и уже доступен на внешнем рынке. Например, «АльфаСтрахование» успешно внедрило продукт, подтвердив, что бесшовная миграция возможна в крупной компании без остановки разработки. Мы знаем, что в любой момент можем вернуться на старый Nexus, но возвращаться не приходится.
KioskNews shows a cleaned-up reading view extracted from the publisher’s page — the original always lives on their site, not ours.