«Один баг на миллион случается триста раз в день»: инженер о том, как была изнутри устроена разработка Skype
5 мая 2025 года Microsoft окончательно выключил Skype — сервис, с которого для многих начался сам феномен видеозвонков. Компания перевела пользователей в Teams и закрыла страницу, которую открыла еще в 2003-м. На пике Skype пользовались около 300 миллионов человек; к своему закрытию он подошел, растеряв аудиторию в битве с Zoom и тем же Teams. Я поговорила с Антоном Букаревым — инженером, который работал над Skype в Microsoft, а сегодня занимает позицию Director of Engineering в Scalio, — о том, как выглядит разработка продукта такого масштаба с той стороны экрана: где ломается интуиция, почему «просто выкатить фикс» здесь невозможно, и что из тех практик он до сих пор считает эталоном.
Как вы попали в Microsoft и оказались в команде Skype? Каким было первое впечатление от работы над продуктом, которым пользовались сотни миллионов людей по всему миру?
На самом деле в Skype я попал не «с улицы», а вместе со стартапом, в котором работал инженером. Это был американский QIK, где мы занимались мобильным стримингом — по сути сделали Periscope за несколько лет до появления самого Periscope. Позже мы разработали кроссплатформенные мобильные видеозвонки, которые работали между разными устройствами и по сотовой сети, а не только по Wi-Fi. Это был 2010 год — тогда Apple только представила FaceTime, который умел звонить лишь между iPhone и только через Wi-Fi. Мы могли больше. Насколько я могу судить, именно эта технология стала одной из причин, по которым Skype в итоге купил компанию. Так я и оказался внутри. Начинал с кроссплатформенной разработки, а потом сосредоточился на мобильной — на клиенте Skype под iOS.
Первое впечатление оказалось совсем не таким, как я ожидал. Когда приходишь в продукт с сотнями миллионов пользователей, очень быстро понимаешь цену любой ошибки. В небольшом сервисе баг увидят несколько десятков или сотен человек: извинился, исправил — и жизнь продолжается. Здесь любое твое изменение — это множитель. Любая цифра после запятой в проценте отказов — это конкретные живые люди, которые не смогли дозвониться. Кто-то не услышал внука. Кто-то не попал на собеседование. Ты начинаешь физически ощущать вес каждой строчки, которую коммитишь. Это отрезвляет и, честно говоря, немного пугает первые пару месяцев.
Что больше всего удивило вас в том, как в Microsoft организована разработка продукта такого масштаба? Какие процессы оказались совсем не такими, как вы ожидали?
Больше всего удивило, насколько мало разработка на таком масштабе похожа на «программирование» в наивном смысле и насколько много — на управление рисками.
Первое открытие: культура данных вместо культуры мнений. Я привык к спорам в духе «мне кажется, пользователю будет удобнее так». В большой команде это почти не работает как аргумент. Есть телеметрия, есть A/B-эксперимент, есть цифры. Твое «мне кажется» стоит ровно ноль, пока ты не показал график. Поначалу это раздражает — кажется, что убивают интуицию инженера. Потом понимаешь, что на масштабе сотен миллионов твоя интуиция систематически врет, потому что ты не репрезентативный пользователь. Ты сидишь на топовом ноутбуке со скоростным интернетом, а медианный пользователь Skype — это человек на слабом Android и мобильной сети 3G где-то, где до вышки далеко.
Второе, что перевернуло мои ожидания, — это то, что «зарелизить» не значит «нажать кнопку». Со стороны кажется, что выкатка — это финал, а на деле именно после нее все только начинается: это отдельная инженерная дисциплина, часто сложнее самой фичи. Никакого «большого взрыва», когда новая версия одномоментно уезжает всем. Вместо этого — кольцевые выкатки (ring deployment): сначала фича включается для внутренних сотрудников, потом для крошечного процента реальных пользователей, потом шире, шире, и на каждом кольце система смотрит на метрики и готова автоматически откатиться. Идея еще и в том, чтобы новая функция по возможности жила за «рубильником» (feature flag), который можно выключить, не выкатывая новый билд.
И третье, чисто культурное: примерно в те годы Microsoft ломал старую модель, где были отдельно разработчики и отдельно тестировщики (SDET). Их объединили в единую роль инженера, который сам и пишет, и отвечает за качество, и дежурит по своему коду. Это было болезненно и спорно, но идея простая и, на мой взгляд, правильная: тот, кто написал код, не должен иметь возможности «перебросить» ответственность за его качество через забор кому-то другому. Ты написал — ты и разгребаешь в три часа ночи, если оно упало.
Какие инженерные задачи в Skype были самыми сложными? С какими техническими проблемами невозможно столкнуться, пока не работаешь над продуктом для сотен миллионов пользователей?
Самое сложное в реалтайм-коммуникациях — то, что ты воюешь не с кодом, а с непредсказуемым интернетом и огромным разнообразием устройств. Особенно Android того времени: практически каждый производитель имел свои особенности, а продукт должен был одинаково хорошо работать везде.
Начнем с базового, но недооцененного: соединить двух людей — это уже нетривиально. Оба сидят за домашними роутерами, за NAT, за корпоративными файрволами. У них нет «прямого адреса» друг друга. Чтобы пробить это соединение, работает целый механизм (ICE/STUN/TURN): клиенты как будто перебирают все возможные способы дотянуться друг до друга и выбирают тот, что сработал. И вот на масштабе ты внезапно узнаешь, что интернет-провайдеров с их безумными настройками NAT в мире тысячи, и каждый пятый — со своими причудами. То, что идеально работает у тебя в офисе, разваливается у пользователя за каким-нибудь мобильным оператором в стране, о существовании которой ты смутно помнил из школьной географии.
Дальше — качество звука и картинки на плохой сети. Пакеты теряются, приходят не по порядку, с разной задержкой (это называется джиттер). Нельзя просто «подождать» — это же реальное время, задержка в разговоре убивает все. Поэтому под капотом крутятся вещи, которые обычный пользователь никогда не увидит: буфер джиттера, который балансирует между задержкой и плавностью; сокрытие потерь пакетов (алгоритм буквально «додумывает» кусочек звука, который не дошел, чтобы ты не услышал щелчок); эхоподавление; адаптивный битрейт, который на лету роняет качество картинки, чтобы звонок не оборвался. Отдельная гордость той эпохи — аудиокодек SILK, наработки которого потом легли в основу Opus, ставшего индустриальным стандартом (тот самый, что сегодня работает почти везде, где есть голос в интернете).
Но, пожалуй, самая интересная особенность больших сервисов — существование багов, которых просто не бывает на маленьком масштабе. Один баг на миллион случается триста раз в день. Гонка потоков, которая теоретически возможна раз в пятилетие, у тебя стреляет каждый час, потому что ты крутишь этот код миллиарды раз в сутки. Ты перестаешь мыслить категориями «этого почти не бывает» — на таком масштабе «почти не бывает» означает «бывает постоянно, просто у конкретного человека редко». Плюс — «длинный хвост»: огромная доля пользователей сидит на древних версиях ОS, на телефонах, которым по семь лет, на клиентах, которые ты не можешь заставить обновиться. И все это должно продолжать работать.
Из того, чем занимался лично, в этот вопрос хорошо ложится офлайн-шаринг документов. Звучит буднично, но задача ровно из той самой категории «не встретишь на малом масштабе». Раньше в Skype передать файл, картинку или документ можно было, только когда оба собеседника одновременно в сети — иначе передача просто не начиналась. А в реальной жизни люди в разных часовых поясах: у одного ночь, у другого день, третий вообще ушёл в метро посреди отправки. Чтобы файл долетел «когда-нибудь потом», нужно было по сути строить надёжное облачное хранение с досылкой: принять файл, сохранить, дождаться, пока получатель появится онлайн хоть на одном из своих устройств, и доставить — ничего не потеряв, не продублировав, переживая обрывы связи. На бумаге фича звучит как «ну просто сохраните файл на сервер». На практике это целый пласт распределённых проблем, которые вылезают именно тогда, когда пользователей миллионы, а сеть у них ненадежная.
В массовом сервисе даже небольшой баг может затронуть огромное количество людей. Как в Microsoft проверяли изменения перед релизом и какие механизмы помогали избежать критических ошибок?
Здесь работает многослойная оборона, и ни один слой сам по себе не считается достаточным.
Первый слой — до продакшена: код-ревью как обязательный ритуал (ничего не уезжает без второй пары глаз), большие наборы автоматических тестов, прогоны на «плохих» сетевых условиях, которые эмулируют потери и задержки. Это гигиена, но ее мало.
Второй слой — контролируемая выкатка, о которой я уже говорил. Ключевая идея: ты никогда не показываешь изменение всем сразу. Сначала — «нулевое кольцо», это сами сотрудники, которые живут на этих сборках каждый день (то, что называют dogfooding — «есть свой корм»). Если фича ломает звонки, первыми страдают инженеры Microsoft, а не бабушка в Волгограде. Потом — процент реальных пользователей, потом рост. И на каждом шаге ключевые метрики (процент успешных звонков, качество, падения) под непрерывным наблюдением.
Третий слой, и он важнейший: по возможности рискованная функциональность пряталась за «рубильником». Это значит, что если что-то пошло не так, тебе не нужно собирать новую версию, гнать ее через сторы и ждать сутки. Ты просто дистанционно гасишь фичу — и все возвращается как было, за минуты. Возможность мгновенно откатить без нового релиза — это, пожалуй, самая недооцененная суперсила больших сервисов. Не «как не допустить ни одной ошибки» (это невозможно), а «как сделать так, чтобы любая ошибка чинилась одним переключателем и за секунды».
И поверх всего — телеметрия как система раннего оповещения. Ты не ждешь, пока пользователи начнут жаловаться в твиттере. Графики сами показывают аномалию через минуты после выкатки на новое кольцо. Философия примерно такая: мы исходим из того, что баги в продакшен все равно попадут, и вкладываемся не только в то, чтобы их не было, но и в то, чтобы обнаружить и потушить их раньше, чем заметит ощутимая доля людей.
Были ли случаи, когда небольшое изменение в коде приводило к неожиданным последствиям или выявляло проблемы, которые невозможно было предсказать заранее? Чему такие ситуации научили вас как инженера?
Один из самых показательных для меня случаев был, казалось бы, про пустяк — про смайлики. Звучит несерьезно, но именно он отлично показывает, как «мелочь» вскрывает то, о чем заранее не думаешь.
Дело вот в чем. Изначально смайлики в Skype были просто зашиты в ресурсы приложения — они ехали внутри самого бандла, вместе с очередным релизом. Пока на это никто не смотрел под правильным углом, все казалось нормальным. А потом приходит маркетинг с совершенно разумной просьбой: давайте выпустим новый набор смайликов — к событию, к празднику, к кампании — прямо сейчас. И тут выясняется, что «прямо сейчас» невозможно в принципе: чтобы добавить хоть один смайлик, нужно собрать новую версию приложения, провести ее через ревью в App Store и дождаться, пока пользователи обновятся. Недели. Для маркетинговой активности это смерть.
То есть безобидное на вид решение «положим смайлики в ресурсы» на самом деле намертво привязало контент к циклу релизов. Задача, которая звучала как «добавить картинки», превратилась в серьезную инженерную работу: мы довольно долго проектировали механизм подгрузки облачных смайликов, чтобы контент можно было обновлять на лету, отдельно от самого приложения — с версионированием, кэшированием и аккуратной работой на слабой сети.
Чему это меня научило — если сжать:
«Мелких» решений не бывает. То, что при написании кода выглядит как незначащая деталь («да просто положим в ресурсы»), через год оказывается стеной, в которую упирается целый отдел. Заранее ты этого почти никогда не видишь.
Все, что зашито в релиз, потом придется оттуда выковыривать. Любую вещь, которую хочется менять чаще, чем выходит новая версия приложения, лучше сразу проектировать как обновляемую отдельно. Контент, конфиги, правила — все, что живет своей жизнью, не должно зависеть от цикла обновлений и от воли App Store.
Смирение как инженерная позиция. Люди, которые говорят «да тут нечему ломаться» или «да это на пять минут», на масштабе ошибаются чаще всех. Начинаешь относиться к любой «очевидной мелочи» с уважением — и строить так, чтобы ее потом можно было безболезненно поменять.
Работа над Skype велась международной командой. Как была устроена совместная разработка, как принимались технические решения и что помогало десяткам инженеров двигаться в одном направлении?
Skype исторически был очень «европейским» по инженерным корням продуктом — разработка жила не в одном месте, а была размазана по нескольким центрам. Я сам работал в московском офисе, в Зеленограде. А поскольку я занимался мобильным клиентом, больше всего пересекался со Стокгольмом — там сидела значительная часть мобильной разработки. Плюс постоянное взаимодействие с Таллином и другими европейскими офисами. То есть ты по умолчанию работаешь через несколько часовых поясов, и «просто подойти и договориться у доски» физически невозможно.
Что реально помогает десяткам людей грести в одну сторону:
Документ важнее разговора. Крупные технические решения не рождаются в устном споре, который никто не помнит через неделю. Пишется дизайн-документ: вот проблема, вот варианты, вот их плюсы и минусы, вот что выбираем и почему. Его читают, комментируют асинхронно, спорят в письменном виде. Когда команда размазана по континентам, письменная культура — это не бюрократия, это единственный способ сохранить общий контекст. Устная договоренность в такой среде не масштабируется.
Явные владельцы решений. У каждой значимой области есть технический лид или ответственный, который в спорной ситуации имеет право сказать финальное слово. Это спасает от вечного консенсусного паралича, когда двадцать умных людей бесконечно обсуждают и ничего не решают. Обсуждение — демократия, но у решения есть хозяин.
Код-ревью как способ синхронизации, а не только контроля качества. Когда ты обязан просмотреть чужой код, ты волей-неволей остаешься в курсе того, что происходит в соседних частях системы. Ревью — это еще и распространение знаний по команде.
«Следуй за солнцем». Иногда распределенность по поясам — это преимущество: задачу можно передавать по кругу, и работа над проблемой не останавливается на ночь. Но чтобы это работало, снова нужна дисциплина письменной передачи контекста — иначе смена в другом полушарии просто не поймет, где ты остановился.
Если совсем коротко: международную команду держит вместе не харизма менеджера и не корпоративные лозунги, а инфраструктура общего контекста — документы, четкие зоны ответственности и привычка все записывать.
Какие инженерные принципы, технологии или подходы, которым вы научились в Microsoft, до сих пор считаете эталонными? Есть ли практики, которых, на ваш взгляд, сегодня не хватает многим IT-командам?
Из того, что я считаю по-настоящему эталонным и вожу с собой из проекта в проект:
Решения на данных, а не на статусе. Право на истину дает график, а не должность. Самый junior-инженер с хорошим экспериментом переспорит директора с интуицией — и это правильно.
Дисциплина постепенной выкатки и мгновенного отката. Не «выкатили и молимся», а «выкатываем по чуть-чуть, смотрим на метрики и при необходимости быстро откатываемся». Это, наверное, самая ценная вещь, которую я вынес.
Уважение к обратной совместимости. Ты не можешь заставить всех пользователей обновиться. Значит, новая версия сервера обязана уметь дружить со старым клиентом, которому семь лет. Это ограничение дисциплинирует и учит проектировать интерфейсы, за которые не стыдно через годы.
Разбор инцидентов без поиска виноватых (blameless postmortem). Когда что-то падает, вопрос не «кто накосячил», а «какая часть системы позволила одному человеку так легко все уронить». Как только начинается охота на ведьм, люди перестают честно рассказывать, что произошло, — и ты теряешь возможность чему-то научиться.
«Ты написал — ты и дежуришь». Ответственность за качество нельзя перебросить через забор.
Многие мечтают о масштабе, но не имеют наблюдаемости — то есть выкатывают вслепую и узнают о проблемах из отзывов в сторах, а не из графиков. Многие пренебрегают постепенной выкаткой, потому что «у нас и так мало пользователей» — а потом резко становится много, и оказывается, что культуры безопасного релиза нет. И почти все недооценивают ценность письменной инженерной культуры: решения принимаются в чатах и голове тимлида, а через полгода никто не помнит, почему сделали именно так. Инструменты сейчас доступны как никогда, а вот дисциплина — по-прежнему дефицит.
Если бы сегодня вам предложили заново проектировать Skype для современной аудитории и технологий, что вы сделали бы иначе? Какие инженерные решения изменились бы за последние годы, а какие, наоборот, остались бы актуальными?
Хороший и немного грустный вопрос — с учетом того, что настоящего Skype больше нет. Но именно поэтому он честный: за прошедшие годы изменилось почти все вокруг, кроме базовых законов, по которым работают сети и связь в реальном времени.
Что бы я делал принципиально иначе.
Первое — облачная архитектура с первого дня. Skype родился как гениальная для своего времени пиринговая (P2P) система: звонки шли напрямую между пользователями через оверлейную сеть «суперузлов». Это было изящно, но со временем этот же фундамент стал тяжелым наследием, и его пришлось мучительно перетаскивать в централизованную облачную инфраструктуру. Сегодня я бы даже не рассматривал P2P-легаси — сразу строил бы на облаке и на пограничных серверах поближе к пользователю.
Второе — работа на плечах стандарта, а не своего велосипеда. В эпоху Skype многое приходилось изобретать самим, потому что готовых стандартов реального времени в браузере просто не было. Сегодня есть WebRTC — фактический индустриальный стандарт для голоса и видео в вебе, — и переизобретать этот слой самому было бы странно. Огромный пласт того, что раньше было уникальным ноу-хау, стал общедоступной базой.
Третье — сквозное шифрование по умолчанию и мобайл-ферст как аксиома. Не «десктопное приложение, к которому потом прикрутили телефон», а ровно наоборот.
Четвертое — то, чего в те годы просто не существовало: машинное обучение прямо в тракте звонка. Подавление шумов нейросетью, отделение голоса от лающей собаки за стеной, замена и размытие фона, апскейл картинки на плохом канале. Сегодня это ожидаемая база, а не магия.
И, наверное, стоит честно сказать про сам продукт, а не только про технологии: мир ушел от парадигмы «позвони другу» к парадигме «встреча по ссылке». Zoom и Teams выиграли не потому, что у них лучше кодек, а потому, что они точнее попали в новый сценарий — быстрые созвоны, «зайти по ссылке без установки», работа и учеба из дома. Skype опоздал именно здесь, а не в инженерии.
Что осталось бы абсолютно актуальным.
Фундамент, как ни странно, почти не постарел. NAT по-прежнему приходится пробивать тем же механизмом (ICE/STUN/TURN) — домашние роутеры никуда не делись. Adaptive bitrate, буфер джиттера, сокрытие потерь, эхоподавление — все это по-прежнему сердце любого звонка, просто алгоритмы стали умнее. Кодек Opus, выросший в том числе из наработок той эпохи, до сих пор индустриальный стандарт и никуда уходить не собирается. И самое главное осталось нетронутым — принципы эксплуатации на масштабе: постепенная выкатка, телеметрия, мгновенный откат, обратная совместимость. Технологии сменились, а законы, по которым живут большие сервисы, — те же самые.
Если совсем коротко: я бы поменял почти весь стек — протоколы, архитектуру, инструменты; по сути это означало бы выбросить все и переписать заново — но не тронул бы почти ни одного принципа о том, как это все безопасно эксплуатировать для миллионов людей.
Напоследок не могу не спросить. Что вы почувствовали, когда Microsoft окончательно отключила Skype?
Когда Skype официально выключили 5 мая 2025 года, я, честно говоря, почувствовал грусть. Не обиду, не «ну наконец-то» — именно сожаление, что ушла целая эпоха. Я всегда ценил эту работу, и ценил по-особому. Мы ведь занимались не абстрактным продуктом — мы давали людям возможность быть на связи друг с другом. Для кого-то это было просто удобно, а для кого-то жизненно необходимо: кто-то не мог встретиться с родными по тем или иным причинам и виделся с ними только по видеосвязи через Skype, кто-то удаленно учился. Работая над таким, ты все время ощущаешь тихую социальную ответственность — понимаешь, что по ту сторону экрана живые люди и их важные моменты. Это не забывается, даже когда сам продукт уходит в историю.