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

Чтобы так получилось, нужно понимать, что именно запомнил её плеер. Оказывается, он помнит не один адрес, а три разные вещи, и при переезде каждая из них ведёт себя по-своему.

Три адреса, которые легко принять за один

Когда говорят «адрес подкаста», обычно имеют в виду что-то одно. На деле их три, и путаница между ними — главный источник дублей и «потерянных» подписчиков.

  • Адрес ленты — URL файла RSS. Именно его приложение Лены опрашивает по расписанию. Это и есть подписка: приложение хранит этот адрес и приходит по нему снова и снова.
  • Адрес аудиофайла — значение атрибута url в теге enclosure каждого выпуска. Это путь, по которому плеер скачивает или стримит звук. У каждого выпуска он свой.
  • Идентификатор выпуска — значение тега guid. Это не адрес, а «паспортный номер» эпизода. Он нужен приложению, чтобы отличить уже известный выпуск от нового.

Разница принципиальна. Адрес ленты — это дверь, в которую стучится плеер. Адрес файла — полка, на которой лежит звук. GUID — отметка в записной книжке плеера: «этот выпуск я уже видел». Дверь можно перенести, предупредив гостя. Полку можно переставить, если в ленте указан новый путь. А вот отметку в записной книжке трогать нельзя: если номер изменился, плеер решает, что перед ним незнакомый эпизод.

Apple в своей документации по смене адреса ленты прямо фиксирует это правило: GUID выпуска должен сохраняться, даже если меняются заголовок и URL в enclosure, иначе клиент может распознать существующий выпуск как новый (Apple Podcasts: перенос RSS). Это описание поведения Apple Podcasts; другие приложения вправе реализовывать сравнение выпусков по-своему, поэтому разумнее считать сохранение GUID общей хорошей практикой, а не гарантией для каждого клиента.

Что плеер на самом деле узнаёт из RSS

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

Теперь посмотрим на последствия. Допустим, вы переезжаете с чужого хостинга на собственный VPS. Меняются домен или путь, а значит, и адрес ленты, и адреса файлов. Что произойдёт в каждом случае:

  • Адрес ленты изменился, а перенаправления нет — приложение продолжает стучаться в старую дверь. Если старый хостинг вы отключили, оттуда ничего не приходит, и подписчик просто перестаёт получать выпуски. Ошибки он не увидит: лента тихо «замолчит».
  • Адрес файла изменился, GUID сохранён — приложение видит знакомые выпуски, помнит, что Лена прослушала третий наполовину, и просто запоминает новое место файла для будущих загрузок.
  • GUID изменился — выпуск выглядит новым. В худшем случае у слушателя в списке окажется вся архивная история заново, с уведомлениями и отметками «не прослушано».

Третий сценарий особенно неприятен тем, что случается не из-за переезда как такового, а из-за способа его выполнения. Многие платформы генерируют GUID автоматически, часто на основе адреса файла. Если вы собираете новую ленту в другом генераторе, он честно создаст свои идентификаторы, и они не совпадут со старыми. Поэтому первый шаг миграции — не копирование аудио, а переписывание «паспортных данных».

Инвентаризация: таблица, с которой начинается переезд

Прежде чем трогать сервер, выгрузите текущую ленту и разберите её в таблицу. Для каждого выпуска нужны три значения: GUID, текущий URL в enclosure и размер файла в байтах (атрибут length). Дополнительно полезны дата публикации и заголовок — по ним удобно сверять результат глазами.

Вот как может выглядеть одна строка для учебного выпуска. Данные условные, придуманы для примера:

Условный учебный выпуск до и после переезда
ПолеБыло (старый хостинг)Стало (свой VPS)
ЗаголовокВыпуск 12. Как мы выбирали микрофонВыпуск 12. Как мы выбирали микрофон
guidold-host-ep12-7f3aold-host-ep12-7f3a (без изменений)
enclosure urlhttps://cdn.oldhost.example/show/ep12.mp3https://media.example.org/podcast/ep12.mp3
Адрес лентыhttps://feeds.oldhost.example/show.xmlhttps://podcast.example.org/feed.xml

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

В тексте ленты это выглядит так:

<item>
  <title>Выпуск 12. Как мы выбирали микрофон</title>
  <guid isPermaLink="false">old-host-ep12-7f3a</guid>
  <enclosure url="https://media.example.org/podcast/ep12.mp3"
             length="28411904" type="audio/mpeg"/>
</item>

Атрибут isPermaLink="false" говорит, что содержимое GUID — не ссылка, а просто строка-идентификатор. Это удобно: даже если старый домен перестанет существовать, значение остаётся валидным ярлыком и никто не пытается его открыть.

Новое место для файлов: что требуется от вашего VPS

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

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

Что при этом считать от ресурсов. Объём диска определяется арифметикой, и её стоит сделать самому. Возьмём условный подкаст: 150 выпусков по 30 МБ — это около 4,5 ГБ архива. Даже с запасом на несколько лет публикации это комфортно умещается на небольшом диске. Тариф Ba у MAATRIX — 1 vCPU, 2 ГБ RAM и 40 ГБ NVMe — для такой задачи служит разумной отправной точкой, но не обещанием ёмкости: сколько одновременных скачиваний выдержит конкретная конфигурация, покажет только ваш собственный тест. Если же у шоу большая аудитория, архив с видеоверсиями или несколько проектов на одной машине, логично смотреть в сторону Uab (2 vCPU, 4 ГБ, 80 ГБ) и выше. Корневой доступ на VPS даёт свободу настроить веб-сервер так, как нужно именно ленте и файлам; сведения о тарифах и локациях — на странице аренды VPS MAATRIX.

Отдельно о трафике. Узким местом у подкаста обычно оказывается не процессор, а исходящий канал в момент выхода нового выпуска: многие подписчики скачивают его почти одновременно. Стоит заранее прикинуть пиковую нагрузку: размер файла умножить на ожидаемое число скачиваний в первый час. Это только оценка, но она быстро показывает, нужен ли вам запас или хватит и скромной машины.

Файлы переехали, но лента ещё старая

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

Правильная последовательность выглядит так:

  1. Скопируйте на новый сервер все аудиофайлы и обложки, сохранив имена, под которые вы будете формировать ссылки.
  2. Проверьте каждый файл: открывается ли по прямой ссылке, совпадает ли размер с атрибутом length, правильный ли тип содержимого отдаёт сервер.
  3. Соберите новую ленту с прежними GUID и новыми URL в enclosure.
  4. Только после этого настройте перенаправление со старого адреса ленты на новый.

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

Одну из частых ловушек стоит назвать отдельно: длина файла. Если в length осталось значение от прежнего хостинга, а вы при переносе пересжали аудио или перезаписали теги, размер изменился, и некоторые клиенты начинают жаловаться на несоответствие. Проще всего пересчитать длину для каждого файла на новом месте и записать в ленту фактическое значение.

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации Россия, США, Франция и Великобритания. Оплата картой РФ и по СБП.

АРЕНДОВАТЬ СЕРВЕР

Перенаправление: как сказать плееру, что дверь переехала

Теперь сама дверь. Старый адрес ленты нужно превратить в указатель на новый. Для этого есть два взаимодополняющих механизма, и Apple рекомендует использовать их вместе: постоянное перенаправление HTTP 301 со старого адреса RSS и тег itunes:new-feed-url в самой ленте. Тот же источник советует сохранять и перенаправление, и тег не менее четырёх недель (документация Apple Podcasts).

Смысл двух механизмов в том, что они работают на разных уровнях. 301 — это ответ веб-сервера: «этот адрес переехал навсегда, идите сюда». Его понимают HTTP-клиенты, и приложение может обновить сохранённый адрес подписки. Тег new-feed-url — это сообщение внутри самой ленты, которое читают приложения и каталоги, умеющие его интерпретировать. Если один способ по какой-то причине не сработает у конкретного клиента, второй даёт шанс.

Как распределены роли на практике. Старый адрес ленты — на прежнем хостинге, и именно там нужно включить 301, если хостинг такую возможность предоставляет. Это принципиальный момент: перенаправление настраивается на старом месте, а не на новом. Если вы уже полностью отказались от прежней площадки и домен ленты принадлежит вам, то перенаправление настраивается на вашем сервере, где этот домен теперь указывает.

Здесь возможны три ситуации:

  • Старая лента на домене, которым вы управляете. Лучший случай. Вы направляете домен на VPS и на нём же настраиваете 301 со старого пути на новый. Подписчикам не нужно ничего знать.
  • Лента на домене хостинга, который позволяет задать перенаправление. Следуйте его инструкции, по возможности включив и тег с новым адресом. Старый хостинг нужно оплачивать, пока перенаправление должно работать.
  • Хостинг не даёт управлять перенаправлением. Тогда остаётся полагаться на тег в ленте, пока она доступна, и честно предупредить слушателей отдельным выпуском. Гарантий в этом случае меньше, и это стоит учитывать при решении о переезде.

Вернёмся к сроку. Четыре недели — это минимум из рекомендации Apple, а не волшебная граница, после которой все клиенты уже переехали. Приложения опрашивают ленты с разной частотой, а у части слушателей телефон неделями лежит без интернета или приложение не открывалось. Практичная стратегия — держать перенаправление значительно дольше, а если возможно, то бессрочно: поддерживать один 301 почти ничего не стоит, а выгода — каждый «отставший» подписчик, который всё-таки доберётся до новой ленты.

Каталоги — не мгновенное обновление

Отдельно об ожиданиях. Каталоги подкастов хранят у себя копию вашей ленты и перечитывают её по своему расписанию. Принять новый адрес они могут не сразу: на это уходит время, и сроки у каждого каталога свои. Поэтому не стоит ждать, что в момент включения 301 все подписчики и все справочники мгновенно переключатся. Часть приложений заметит переезд в течение суток, часть — позже, а какая-то часть будет приходить на старый адрес и через несколько недель.

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

Что происходит в период перехода
ЭтапСостояние старого адресаСостояние нового адресаЧто наблюдать
До переключенияОсновная лентаТестовая, без подписчиковНет ли дублей в тестовом приложении
Первые дни301 на новый адресОсновная лентаОбращения на новый адрес в журнале веб-сервера
Первые недели301 и тег сохраняютсяОсновная лента, выходят новые выпускиОбращения на старый адрес должны постепенно убывать
ДальшеРешение за вами, лучше держать дольшеОсновная лентаОстаточный трафик на старый адрес

Журнал веб-сервера здесь работает как барометр. Пока на старый адрес приходят запросы, у вас есть подписчики, которые ещё не переехали. Это не повод для паники, а повод не торопиться с отключением.

Проверяем выход нового выпуска в разных клиентах

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

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

На что смотреть в каждом клиенте:

  • Не появились ли старые выпуски как новые — признак того, что GUID разошёлся.
  • Сохранились ли отметки прослушивания и позиция воспроизведения у знакомых эпизодов.
  • Появился ли новый выпуск и открывается ли его аудио с перемоткой.
  • Совпадает ли заявленная длительность и размер с реальными.

Если в одном клиенте что-то пошло не так, а в остальных всё в порядке, это не обязательно ваша ошибка. Клиенты кэшируют ленты и обновляют их по собственному расписанию, поэтому прежде чем менять что-либо, подождите и перепроверьте. А вот если несоответствие видно во всех приложениях сразу, ищите причину в самой ленте: почти наверняка там изменился GUID или сломан URL файла.

Критерии возврата: когда стоит откатиться

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

Если подкаст — не только файлы

Иногда на собственном сервере вместе с подкастом хочется держать и другие вещи: сайт шоу, страницу выпуска с расшифровкой, закрытый раздел для спонсоров. Обычный подкаст в формате RSS при этом остаётся набором статичных файлов, которые клиент скачивает целиком. Это отличает его от потокового вещания: у живых трансляций по протоколу HLS другая механика, где клиент последовательно получает небольшие сегменты по плейлисту, а плейлист обновляется по мере появления новых частей, как описано в RFC 8216. Этот документ опубликован в 2017 году и не относится к Internet Standards Track, так что считать его строгим стандартом не стоит. Для подкаста с обычными выпусками HLS не нужен: достаточно отдавать файл целиком, а плееру — позволить запрашивать диапазоны байтов при перемотке. Но если вы планируете вести ещё и прямые эфиры, это уже другая задача с другой нагрузкой, и тестировать её нужно отдельно.

Если рядом с подкастом поселится ещё и рассылка для слушателей, полезно прикинуть, чем собственная инфраструктура отличается от платного сервиса. Об этом, на примере другого проекта, рассказывает материал про собственную рассылку вместо сервиса по подписке.

Что в итоге увидит Лена

Вернёмся к нашей слушательнице. Она ничего не знает ни о GUID, ни о 301, ни о том, как называется ваш новый сервер. В понедельник утром её приложение по привычке обращается к адресу, который запомнило полгода назад. Получает ответ, что адрес переехал навсегда, переходит на новый и находит там ленту, в которой выпуск 12 всё так же подписан старым идентификатором. Приложение узнаёт знакомый эпизод и не создаёт дубль: отметка «прослушано» на месте, а позиция воспроизведения сохранилась. Рядом в списке появляется новый выпуск, звук которого лежит уже на вашем VPS.

Лена нажимает «играть». Ей не пришлось искать подкаст заново, подписываться ещё раз или гадать, почему лента вдруг опустела. Для неё ничего не произошло — и именно этот результат и был целью всей работы.