<?xml version="1.0" encoding="utf-8" ?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:tt="http://teletype.in/" xmlns:opensearch="http://a9.com/-/spec/opensearch/1.1/"><title>Dmitriy Melnik</title><subtitle>Founder of Drim Dev · Software Architect · Educator · Community Builder

mailto:dmitriy.melnik@drim.dev
https://t.me/mitro52</subtitle><author><name>Dmitriy Melnik</name></author><id>https://teletype.in/atom/drimdev</id><link rel="self" type="application/atom+xml" href="https://teletype.in/atom/drimdev?offset=0"></link><link rel="alternate" type="text/html" href="https://teletype.in/@drimdev?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=drimdev"></link><link rel="next" type="application/rss+xml" href="https://teletype.in/atom/drimdev?offset=10"></link><link rel="search" type="application/opensearchdescription+xml" title="Teletype" href="https://teletype.in/opensearch.xml"></link><updated>2026-04-07T03:18:21.190Z</updated><entry><id>drimdev:ticketon-postmortem-2025-analysis</id><link rel="alternate" type="text/html" href="https://teletype.in/@drimdev/ticketon-postmortem-2025-analysis?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=drimdev"></link><title>Анализ постмортема сбоя Ticketon 11 апреля 2025 года</title><published>2025-05-07T09:28:23.338Z</published><updated>2025-05-13T06:43:59.575Z</updated><summary type="html">Как и обещали, Ticketon опубликовали постмортем по итогам сбоя 11 апреля. Вот мой анализ этого документа.</summary><content type="html">
  &lt;p id=&quot;CU0S&quot;&gt;Как и обещали, Ticketon &lt;a href=&quot;https://freedomlabs.kz/analiz-intsidienta-s-prodazhiei-bilietov-na-jlo-na-tikietonie/&quot; target=&quot;_blank&quot;&gt;опубликовали постмортем&lt;/a&gt; по итогам сбоя 11 апреля. Вот мой анализ этого документа.&lt;/p&gt;
  &lt;p id=&quot;SmBA&quot;&gt;Стала понятна главная причина дублирования билетов. При массовом наплыве пользователей сервера Ticketon перестали справляться с нагрузкой и сайт периодически становился недоступным. Чтобы решить эту проблему, команда экстренно решила использовать Cloudflare Waiting Room. В постмортеме напрямую не называется Cloudflare, но этот сервис упоминается в &lt;a href=&quot;https://www.threads.com/@alexnomad/post/DIWntcuokzV&quot; target=&quot;_blank&quot;&gt;прошлом сообщении&lt;/a&gt; Алексея Ли.&lt;/p&gt;
  &lt;p id=&quot;6TlX&quot;&gt;Когда используется Cloudflare Waiting Room, пользователи перенаправляются на специальную страницу ожидания вместо того, чтобы случайным образом получать ошибки загрузки сайта. И система следит за тем, чтобы те пользователи, кто пришёл раньше, получили доступ к сайту раньше. Виртуальная очередь как снижает нагрузку на сайт, так и явно информирует пользователей, когда они смогут воспользоваться сервисом. Рекомендую прочитать&lt;a href=&quot;https://blog.cloudflare.com/cloudflare-waiting-room/&quot; target=&quot;_blank&quot;&gt; статью о том, как использовать Waiting Room&lt;/a&gt;. А для тех, кто хочет узнать больше, есть &lt;a href=&quot;https://blog.cloudflare.com/how-waiting-room-queues/&quot; target=&quot;_blank&quot;&gt;хорошая статья о технических деталях&lt;/a&gt; работы сервиса.&lt;/p&gt;
  &lt;p id=&quot;VrHN&quot;&gt;Проблемы начались сразу же после включения электронной очереди. Чтобы понять причину, необходимо знать, как работает оплата на веб-сайтах. Для этого рекомендую посмотреть &lt;a href=&quot;https://youtu.be/bKJ-bzcTm7U?si=eBcOpqxwt9pMRd_-&quot; target=&quot;_blank&quot;&gt;видео&lt;/a&gt;, где я рассказываю про работу платёжных провайдеров на примере Stripe. Другие платёжные провайдеры работают аналогично.&lt;/p&gt;
  &lt;p id=&quot;jYyH&quot;&gt;Когда пользователь заходит на сайт Ticketon, выбирает билет и нажимает &amp;quot;Оплатить&amp;quot;, то оплату принимает не Ticketon, а отдельный сервис - платёжный провайдер. После того, как пользователь оплатил билет и платёжный провайдер снял деньги с карты, необходимо уведомить об этом Ticketon, чтобы он у себя отметил, что этот билет продан, и затем выслал ваучер покупателю. Для этого у Ticketon есть HTTP API эндпоинт, на который платёжный провайдер шлёт HTTP запросы с подтверждениями покупок билетов.&lt;/p&gt;
  &lt;p id=&quot;kc9K&quot;&gt;Проблема возникла именно с этим эндпоинтом.&lt;/p&gt;
  &lt;p id=&quot;BbPJ&quot;&gt;Для повышения безопасности и надёжности системы Ticketon позволял слать запросы на эндпоинт только с ограниченного списка IP адресов - адресов платёжного провайдера. Это грамотное решение. Нельзя давать возможность кому угодно слать запросы на такой важный эндпоинт.&lt;/p&gt;
  &lt;p id=&quot;gBws&quot;&gt;Так что же произошло после того, как команда подключила Cloudflare Waiting Room? В постмортеме это явно не указано, но я вижу только один возможный сценарий. Для того, чтобы Waiting Room заработал, нужно начать проксировать трафик через Cloudflare. То есть запросы от пользователей сначала отправляются на сервера Cloudflare и потом Cloudflare переотправляет запросы на сервера Ticketon. Это позволяет решить, перегружен ли сайт, и, если да, то вместо запроса на сайт Ticketon вернуть HTML-страницу электронной очереди.&lt;/p&gt;
  &lt;p id=&quot;mS3L&quot;&gt;Думаю, внимательные читатели уже поняли, что пошло не так.&lt;/p&gt;
  &lt;p id=&quot;ItIn&quot;&gt;&lt;strong&gt;После включения проксирования через Cloudflare запросы от платёжного провайдера стали также проходить через Cloudflare. И запросы на эндпоинт подтверждения покупок в Ticketon стали приходить с IP адресов Cloudflare, а не с IP адресов платёжного провайдера. Поэтому эти запросы блокировались. Покупки перестали подтверждаться.&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;FtcH&quot;&gt;Вот как это выглядело с точки зрения покупателя. Он заходил на сайт, выбирал место, нажимал &amp;quot;Оплатить&amp;quot; и вводил платёжные данные. После этого платёжный провайдер списывал деньги и говорил покупателю, что платёж успешно завершён. Покупатель думал, что всё хорошо, и билет теперь его.&lt;/p&gt;
  &lt;p id=&quot;WRuz&quot;&gt;Но подтверждение оплаты покупателем не доходило от платёжного провайдера до Ticketon. И Ticketon думал, что покупатель выбрал билет, перешёл на его оплату, но оплату не произвёл. Из-за этого через некоторое время бронь с билета снималась, и его мог купить уже другой человек. В итоге, было совершено более 10 тысяч таких повторных продаж.&lt;/p&gt;
  &lt;p id=&quot;ppAw&quot;&gt;К сожалению, в постмортеме не указано, как можно было предотвратить эту проблему. Поэтому я напишу 2 технических решения, которые позволили бы избежать сбоя:&lt;/p&gt;
  &lt;ol id=&quot;yjNo&quot;&gt;
    &lt;li id=&quot;SFd8&quot;&gt;Можно было начать проксировать через Cloudflare не все запросы на Ticketon, а только запросы от пользователей. Но для этого эндпоинт подтверждения платежей должен был изначально быть на другом (под)домене. Cloudflare позволяет включать проксировать только для конкретных доменов. Если бы эндпоинт был, к примеру, по адресу &lt;a href=&quot;https://payments.ticketon.kz/webhook&quot; target=&quot;_blank&quot;&gt;https://payments.ticketon.kz/webhook&lt;/a&gt;, то можно было не включать проксирование для &lt;a href=&quot;https://payments.ticketon.kz/webhook&quot; target=&quot;_blank&quot;&gt;payments.ticketon.kz&lt;/a&gt;, и проблема бы не возникла&lt;/li&gt;
    &lt;li id=&quot;XdB7&quot;&gt;Использование прокси по пути запроса от клиента к целевому серверу это частая практика. И поэтому нельзя смотреть только на IP адрес пришедшего запроса, чтобы понять, кто его изначальный отправитель. Для сохранения информации об IP адресе исходного отправителя прокси в переотправляемые запросы добавляют HTTP-заголовок &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/X-Forwarded-For&quot; target=&quot;_blank&quot;&gt;X-Forwarded-For&lt;/a&gt;. Cloudflare &lt;a href=&quot;https://developers.cloudflare.com/fundamentals/reference/http-headers/#x-forwarded-for&quot; target=&quot;_blank&quot;&gt;тоже так делает&lt;/a&gt;. Поэтому сервера Ticketon должны были проверять наличие этого заголовка и брать IP адрес отправителя оттуда. Там бы они нашли адрес платёжного провайдера и проблема бы не возникла.&lt;/li&gt;
  &lt;/ol&gt;
  &lt;p id=&quot;j2ei&quot;&gt;Указанные выше меры позволили бы избежать сбоя в этом конкретном случае. Но могут возникнуть и другие проблемы. Поэтому у команды должен был быть план на случай, когда такая важная часть общего процесса покупки перестала работать. К примеру, должна быть метрика отношения количества бронирований к количеству покупок. И в случае аномального изменения этой метрики, команде должен сразу прилетать алёрт. И затем у команды должны были быть средства быстро предотвращения проблемы. Например, автоматическое продление бронирования для всех неоплаченных билетов. Чтобы их нельзя было купить, пока команда не решит проблему.&lt;/p&gt;
  &lt;p id=&quot;2NWP&quot;&gt;На этом я завершаю анализ технических деталей и хочу поделиться своим мнением о постмортеме в целом.&lt;/p&gt;
  &lt;p id=&quot;hvIC&quot;&gt;Упор в документе сделан на организационных проблемах и на том, как их предотвращать в будущем. Я бы хотел, чтобы технические проблемы были проанализированы так же глубоко. Чтобы в посмортеме было больше технических деталей, таких как графики потребления ресурсов и времени обработки запросов, и описание того, что в сайте отказало под нагрузкой.&lt;/p&gt;
  &lt;p id=&quot;3SUi&quot;&gt;Но нужно отдать должное команде Ticketon и Freedom Holding в целом. Казахстанские компании всё ещё очень редко публикуют постмортемы, и шаг Ticketon заслуживает большого уважения. Это повышает прозрачность и помогает всему сообществу казахстанских ИТ-специалистов учиться на реальных ситуациях. Надеюсь, другие компании последуют примеру Ticketon и тоже будут публиковать разбор сбоев своих ИТ-систем. Это сделает рынок более зрелым, а продукты надёжнее.&lt;/p&gt;
  &lt;p id=&quot;NgFz&quot;&gt;P.S. Подписывайтесь на мой канал, чтобы получать подобные глубокие технические разборы и быть в курсе событий ИТ-индустрии &lt;a href=&quot;https://t.me/drim_channel&quot; target=&quot;_blank&quot;&gt;https://t.me/drim_channel&lt;/a&gt;&lt;/p&gt;
  &lt;p id=&quot;hKgq&quot;&gt;ДОПОЛНЕНИЕ от 13 мая 2025 года:&lt;/p&gt;
  &lt;p id=&quot;nFYx&quot;&gt;В комментарии ниже написали, что причина сбоя была несколько другой. И заключалась в том, что запросы от платёжного провайдера просто не доходили до эндпоинта, потому что они вставали в очередь наравне с запросами от пользователей. Для корректной работы нужно было в конфигурации Cloudflare Waiting Room настроить &lt;a href=&quot;https://developers.cloudflare.com/waiting-room/additional-options/waiting-room-rules/bypass-rules/&quot; target=&quot;_blank&quot;&gt;Bypass Rules&lt;/a&gt;, чтобы запросы с IP адресов платёжных провайдеров не попадали в очередь ожидания. Либо настроить правило, чтобы в очередь не попадали запросы на конкретный URL эндпоинта Ticketon. Спасибо комментатору Владимиру за уточнение, это ценно.&lt;/p&gt;

</content></entry><entry><id>drimdev:ticketon-reliability</id><link rel="alternate" type="text/html" href="https://teletype.in/@drimdev/ticketon-reliability?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=drimdev"></link><title>Подходы к созданию надёжных систем на примере ситуации с Ticketon</title><published>2025-04-21T07:38:28.161Z</published><updated>2025-04-21T07:38:28.161Z</updated><summary type="html">1 августа в Астане состоится концерт Дженнифер Лопес. Звёзды такой величины редко посещают Казахстан, поэтому это событие ожидаемо вызвало ажиотаж. Почитатели таланта знаменитости стали терпеливо ждать 11 апреля - день, когда в сервисе Ticketon должны были начаться продажи билетов. В первые минуты этого дня десятки тысяч покупателей устремились на сайт.</summary><content type="html">
  &lt;p id=&quot;ooF5&quot;&gt;1 августа в Астане состоится концерт Дженнифер Лопес. Звёзды такой величины редко посещают Казахстан, поэтому это событие ожидаемо вызвало ажиотаж. Почитатели таланта знаменитости стали терпеливо ждать 11 апреля - день, когда в сервисе Ticketon должны были начаться продажи билетов. В первые минуты этого дня десятки тысяч покупателей устремились на сайт.&lt;/p&gt;
  &lt;p id=&quot;SqWe&quot;&gt;И сервис упал.&lt;/p&gt;
  &lt;p id=&quot;X1UQ&quot;&gt;Ситуация, когда интернет-сервисы не справляются с нагрузкой и перестают стабильно работать, не является редкой. На это есть разные причины. Возможно, маркетологи недооценили спрос. Или техническая команда неверно рассчитала сколько железа необходимо. Или с нагрузкой не справились внешние сервисы. Ситуация плохая и она бьёт по репутации компании. Но всё же она не критичная. Обычно команда достаточно быстро находит причины падения и устраняет их. Те, кто не смог купить билеты сразу, могут это сделать через некоторое время.&lt;/p&gt;
  &lt;p id=&quot;P8kw&quot;&gt;Но в случае с Ticketon ситуация оказалась гораздо хуже.&lt;/p&gt;
  &lt;p id=&quot;12lt&quot;&gt;После падения сервис подняли и люди продолжили покупать билеты. И только позже стало понятно, что Ticketon даёт возможность купить несколько билетов &lt;strong&gt;на одно и то же место&lt;/strong&gt; 💥&lt;/p&gt;
  &lt;p id=&quot;Eila&quot;&gt;А вот это уже катастрофа. Представьте, что человек за 100 тысяч тенге купил билет и пришёл на концерт. А вокруг его места стоит ещё 5 человек с таким же билетом. На трибунах будет одна большая драка. И это сто процентов приведёт к срыву концерта.&lt;/p&gt;
  &lt;p id=&quot;IZhi&quot;&gt;Как только стала понятна проблема дублирования билетов, продажи тут же прекратили. Но множество одинаковых билетов уже было продано. Начались действия по минимизации ущерба. Кому-то смогли найти новые места, кому-то пришлось возвращать деньги вместа с компенсацией. Как итог - тысячи разгневанных клиентов, сотни миллионов тенге убытков для Ticketon и большой репутационный ущерб. Детали рекомендую прочитать в сообщениях руководителей Freedom Holding - компании, владеющей Ticketon. Вот сообщения Тимура Турлова - https://www.threads.net/@timurturlov/post/DIePx8Zt_VX Вот сообщения Алексея Ли - https://www.threads.net/@alexnomad/post/DIWntcuokzV&lt;/p&gt;
  &lt;p id=&quot;nrXf&quot;&gt;Как говорится, умные учатся на чужих ошибках. Поэтому давайте подумаем, как должны были отработать менеджмент и техническая команда Ticketon, чтобы исключить возможность подобных катастроф. И попробуем сформулировать конкретные рекомендации.&lt;/p&gt;
  &lt;p id=&quot;HfV5&quot;&gt;&lt;strong&gt;Менеджмент и маркетинг:&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;S4Xv&quot;&gt;1. &lt;strong&gt;Реалистичная оценка ажиотажа&lt;/strong&gt;: Понятно, что JLo – это мегазвезда для Казахстана. Ожидать стандартной нагрузки было нельзя. Менеджменту следовало не просто &lt;em&gt;предположить&lt;/em&gt; высокий спрос, а заложить в планы пиковую, возможно, даже чрезмерную нагрузку, исходя из масштаба события и медийного шума. Это включает коммуникацию с технической командой о &lt;em&gt;порядке&lt;/em&gt; ожидаемых цифр (не &amp;quot;будет много&amp;quot;, а &amp;quot;ожидаем X десятков тысяч одновременных запросов в первую минуту&amp;quot;).&lt;/p&gt;
  &lt;p id=&quot;YOSg&quot;&gt;2. &lt;strong&gt;Стратегия продаж&lt;/strong&gt;: Запуск всех билетов одномоментно в полночь – классический рецепт для создания пиковой нагрузки. Менеджмент мог рассмотреть альтернативы:&lt;/p&gt;
  &lt;p id=&quot;eOsw&quot;&gt;* &lt;strong&gt;Предрегистрация/лотерея&lt;/strong&gt;: Собрать заявки заранее и распределить возможность покупки.&lt;/p&gt;
  &lt;p id=&quot;LBby&quot;&gt;* &lt;strong&gt;Поэтапный старт&lt;/strong&gt;: Начинать продажи по секторам или ценовым категориям с интервалом в несколько часов.&lt;/p&gt;
  &lt;p id=&quot;UYOI&quot;&gt;* &lt;strong&gt;Очередь&lt;/strong&gt;: Внедрить систему виртуальной очереди, которая пропускает на сайт ограниченное количество пользователей одновременно. Да, это тоже вызывает недовольство ожидающих, но предотвращает падение и хаос.&lt;/p&gt;
  &lt;p id=&quot;Dspm&quot;&gt;3. &lt;strong&gt;Коммуникация&lt;/strong&gt;: Заранее предупредить пользователей о возможном высоком спросе и потенциальных сложностях, объяснить, как будет работать система (если используется очередь или поэтапный старт). Это управляет ожиданиями.&lt;/p&gt;
  &lt;p id=&quot;d8w5&quot;&gt;&lt;strong&gt;Техническая команда:&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;ij06&quot;&gt;1. &lt;strong&gt;Нагрузочное тестирование&lt;/strong&gt;: Это альфа и омега подготовки к таким событиям. Нужно было не просто проверить, что сайт работает, а &lt;em&gt;симулировать&lt;/em&gt; реалистичный сценарий: одновременный заход десятков тысяч пользователей, массовые запросы к базе данных (проверка наличия мест, создание заказов). Тестирование должно выявить &amp;quot;узкие места&amp;quot; – будь то серверные мощности, пропускная способность сети, неоптимизированные запросы к БД или проблемы во внешних сервисах (например, эквайринг).&lt;/p&gt;
  &lt;p id=&quot;8HEY&quot;&gt;2. &lt;strong&gt;Масштабируемая архитектура&lt;/strong&gt;: Современные облачные технологии позволяют гибко наращивать мощности (auto-scaling) под нагрузку. Команда должна была убедиться, что инфраструктура настроена на автоматическое или быстрое ручное масштабирование всех компонентов системы: веб-серверов, серверов приложений, баз данных.&lt;/p&gt;
  &lt;p id=&quot;gHFf&quot;&gt;3. &lt;strong&gt;Оптимизация&lt;/strong&gt;: Проанализировать и оптимизировать самые ресурсоемкие операции, особенно те, что связаны с проверкой и бронированием мест. Использовать кэширование где возможно (например, для статической информации о мероприятии).&lt;/p&gt;
  &lt;p id=&quot;j251&quot;&gt;4. &lt;strong&gt;Самое главное! - предотвращение продажи дубликатов&lt;/strong&gt;: Вот здесь и произошла катастрофа. Падение сервера – полбеды. Продажа одного места нескольким людям – это фундаментальная ошибка в логике приложения или управлении данными. Как это предотвратить:&lt;/p&gt;
  &lt;p id=&quot;Fwbg&quot;&gt;* &lt;strong&gt;Атомарность операций&lt;/strong&gt;: Процесс &amp;quot;проверить доступность места -&amp;gt; занять место -&amp;gt; создать заказ&amp;quot; должен быть &lt;em&gt;атомарным&lt;/em&gt;. Это означает, что он либо выполняется целиком и успешно, либо полностью откатывается, если на каком-то этапе произошел сбой или место уже занято другим запросом. Это достигается с помощью механизмов транзакций в базах данных.&lt;/p&gt;
  &lt;p id=&quot;7cWg&quot;&gt;* &lt;strong&gt;Блокировки&lt;/strong&gt;: При попытке купить конкретное место, на него должна ставиться блокировка на короткое время (пока идет оформление), чтобы другой процесс не мог его занять. Важно использовать правильный уровень изоляции транзакций и грамотно управлять блокировками, чтобы не парализовать систему, но гарантировать эксклюзивность места.&lt;/p&gt;
  &lt;p id=&quot;N62D&quot;&gt;* &lt;strong&gt;Уникальные ограничения (unique constraints)&lt;/strong&gt;: На уровне базы данных должно быть жесткое ограничение, не позволяющее добавить две записи с одинаковым местом на одно и то же мероприятие. Это последняя линия обороны, которая не даст записать дубликат, даже если логика приложения даст сбой.&lt;/p&gt;
  &lt;p id=&quot;e9Se&quot;&gt;* &lt;strong&gt;Тестирование конкурентного доступа&lt;/strong&gt;: Нужно было &lt;em&gt;специально&lt;/em&gt; тестировать сценарии, когда несколько &amp;quot;покупателей&amp;quot; одновременно пытаются купить одно и то же место. Эти тесты должны доказать, что система корректно обрабатывает такие &amp;quot;гонки запросов&amp;quot; (race conditions).&lt;/p&gt;
  &lt;p id=&quot;SCzM&quot;&gt;5. &lt;strong&gt;План действий при сбоях (incident response plan)&lt;/strong&gt;: Что делать, если система все-таки упала? Как быстро ее поднять? &lt;em&gt;Критически важно&lt;/em&gt;: перед тем как снова открывать продажи после сбоя, необходимо провести проверку целостности данных. Убедиться, что не возникло аномалий вроде &amp;quot;подвисших&amp;quot; заказов или некорректного статуса мест. Похоже, именно этот шаг был пропущен, что и привело к продаже дублей после восстановления работы.&lt;/p&gt;
  &lt;p id=&quot;LDSj&quot;&gt;Катастрофа с Ticketon – это результат целого комплекса проблем: недооценка нагрузки менеджментом, недостаточная подготовка и тестирование со стороны технической команды, и, вероятно, отсутствие должного контроля и стратегического видения со стороны технического руководства (CTO) в части обеспечения фундаментальной надежности критически важной функции – продажи уникального товара (билета на место). Падение сервера – это плохо. Продажа дубликатов – это показатель системного сбоя на уровне архитектуры, процессов разработки и тестирования.&lt;/p&gt;
  &lt;p id=&quot;W7LA&quot;&gt;Ticketon обещали опубликовать постмортем, где они опишут все причины, приведшие к этой ситуации. Посмотрим, насколько они будут пересекаться с тем, что я написал выше.&lt;/p&gt;
  &lt;p id=&quot;xgcS&quot;&gt;Этот случай – болезненный, но ценный урок для всей IT-индустрии Казахстана о том, насколько важен не только внешний функционал сервиса, но и его внутренняя надежность, особенно когда на кону стоят большие деньги и доверие тысяч людей. Надеюсь, нужные выводы будут сделаны и подобных ситуаций в будущем удастся избежать.&lt;/p&gt;

</content></entry></feed>