История проекта, который никогда не падает / Андрей...

Post on 26-Jun-2015

578 Views

Category:

Documents

6 Downloads

Preview:

Click to see full reader

TRANSCRIPT

История проекта, который никогда не падает

Андрей Шетухин

О докладчике

http://slonik-v-domene.livejournal.com

http://stellar.moikrug.ru

Тема доклада

Разработка онлайн-игры для Facebook

Выбор новых технологий

Как понять, что дела идут скверно

Что делать, когда проект не работает

Как не делать так, чтобы проект не работал

На что обратить внимание после запуска

Начало

Мы, молодая, амбициозная команда,..

...хотим написать игру для Facebook

Средняя игра для Facebook, это:

100 000+ пользователей

10 000 игроков онлайн

3 - 5 тысяч запросов в секунду

А еще у нас жестко со сроками:

Два месяца до сдачи прототипа

Три месяца до запуска в тестирование

Четыре месяца до первых пользователей

Полгода — до продакшена

Выбор технологий

Пишем сервис с нуля, а значит можно выбрать все самое передовое и интересное

Проблем с идеями нет — спасибо Slideshare, конференциям и Opennet

Всегда интересно разобраться с новой технологией и получить опыт

Мы ничем не хуже других: если у них работает, то и у нас тоже все получится

Ведущий разработчик слышал, что:

ZeroMQ — очередь сообщений которая выглядит как BSD-сокеты с гарантией доставки данных

Mongrel — вебсервер-транслятор HTTP в ZeroMQ и обратно

Google Protobuf — универсальный сериализатор данных

Google Logger — отличное решение для ведения логов

Ведущий разработчик не знал, что:

ZeroMQ имеет ряд существенных отличий от BSD-сокетов

Библиотека C++ для Mongrel нигде толком не использовалась

Сериализация в Google Protobuf требует CPU

Google Logger вызывает НЕНАВИСТЬ у сисадминов

Началось проектирование

Для проверки идеи написали однопоточный сервер на ZeroMQ, пример кода взяли из руководства

От чтения примера до запуска — всего 15 минут!

Затем прикрутили пару функций бизнес-логики

Проверили — все работает (на одном онлайн-пользователе)

Общая идея

Развитие идеи

Нам нужен один игровой сервер (лучше - два), а еще — сервер сессий, кэш для БД и балансировщик запросов

Взаимодействие систем построим через Google Protobuf

Клиентами будут Flash (со своим протоколом обмена) и jQuery/REST

В теории все отлично, но есть одно «но»...

…или даже не одно...

Но мы — команда,а значит — справимся!

Mongrel

Версия 1.7.5 еще не работает, а версия 1.8.0 уже не работает с C++ клиентом

Автор C++ клиента уехал в Тибет искать Шамбалу

Из версий 1.7.5, 1.8.0 и своих патчей собираем рабочий Mongrel

Патчим С++ клиент

Проверяем — вроде, работает

Protobuf

• Для каждой функции игры надо писать сериализатор из протокола Flash в Protobuf и обратно

• Таких функций десятки уже сейчас, а в будущем их будут сотни

• Структуры Protobuf не имеют механизмов наследования и версионирования

• Сериализация обходится дорого по CPU и потому мало пригодна для однопоточных серверов

Готовим прототип к запуску

Геймсервер

Сервер сессий

Прокси-кэш для БД

C++ клиент для Mongrel, он же — балансировщик

Mongrel

Сервер статики - nginx

Запуск

Почему-то всё заметно тормозит уже на 10 пользователях

Падение одного сервиса лечится только рестартом всей системы

При этом при падении одного сервиса виснет вообще всё

Иногда система не стартует вовсе

Обсчет игр 40 онлайн-пользователей занимает до 30% CPU сервера

Причины

ZeroMQ гарантирует доставку, поэтому то, что не доставилось при падении сервиса, доставится при рестарте. И сервис упадет еще раз.

ZeroMQ требует двустороннего взаимодействия: нельзя не ответить на запрос. Поэтому клиент упавшего сервиса виснет в ожидании ответа.

У каждой проблемы есть простое, очевидное для

всехи при этом

неправильноерешение.

«Решение»

Раз однопоточные сервисы не масштабируются, сделаем их многопоточными

Рестартовать всё будем при помощи скриптов и в четкой последовательности

Купим еще серверов

Напишем миллион правил Nginx для REST

Что-то забыли?

ZeroMQ — не BSD-сокеты (хотя и очень похоже), и в многопоточной среде ведет себя иначе

А еще у ZeroMQ есть странные проблемы с таймаутами и IPv6

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

Миллион правил Nginx для REST сложно поддерживать

Внимание, вопрос:

— Знали ли разработчики об этих проблемах при

выборе технологии?

— Конечно, нет!

Почему?

Потому, что на конференциях, в докладах и на сайтах разработчиков — сплошные success stories.

А описание проблем — это списки рассылки, багтрекеры и личная переписка.

И пока не столкнешься с проблемами, подводная часть айсберга не видна. Особенно, если у команды нет опыта работы с данной технологией

Внезапно!!!

Случился Дедлайн

Времени «выкинуть все и переписать с нуля» нет

Поэтому запускаемся «как есть», нагрузка небольшая

Сразу после запуска — ревью всего проекта

Проект не работает, что делать?

Ищем проблемные места

Оцениваем стоимость переделок

Оцениваем риски

Планируем последовательность переделок

Перезапускаем сервисы

Переделки

Вместо Mongrel и однопоточного балансировщика будет проверенная и знакомая разработчикам технология

Заменяем REST на JSON-RPC и убираем миллион правил Nginx

Пишем врапперы к ZeroMQ для замены на BSD-сокеты. Шедулер — проверенный и работающий libev

Protobuf оставляем — слишком дорого менять

Логгер будет системный (syslog)

Результат

Вместо неизвестных технологий используются простые и понятные

Сервисы можно рестартовать отдельно и в любой последовательности

Система масштабируется на большое количество серверов

Тем не менее, в проекте остались плохие решения

— Можно ли было сделать лучше?

— Да, но...

Если бы:

Было больше времени на проектирование и рефакторинг

Проект еще не вышел в предпродакшен

Не было других задач

И т. д., и т. п...

В итоге:

По сравнению с тем, что было, стало лучше

Однако, определенные проблемы остались, и, видимо, исправить их полностью не получится

Тем не менее, проект запущен и работает

Выводы

Плохо:

«Я где-то слышал об этой технологии»

«Прототип написали по учебнику за 15 минут, весь проект займет неделю»

«Нет проблем за ночь пропатчить основной компонент»

«Разберемся по ходу дела»

«На одном пользователе все работает»

«Я сам буду учить новичков»

Хорошо

Команда продолжительное работала с этой технологией

Нет проблем найти специалистов

Мы знаем, как растет нагрузка от числа онлайн-пользователей

Новички сами учатся, не отвлекая ведущих разработчиков

Менеджер, помни!

Новые технологии — хорошо, неизвестные технологии — плохо.

Скорость разработки прототипа к скорости разработки проекта не имеет практически никакого отношения.

Сначала — архитектура всей системы, затем — частности

Нет плана деплоймента — нет проекта

Тимлид, знай!

Реклама может нести заведомо ложную информацию или показывать только положительные стороны технологии

«Тестирование» «прототипа» на одном пользователе на своем десктопе — не тестирование вовсе. И это — не прототип

Невозможно одновременно учить новичков и писать код

Всегда надо закладывать время на непредвиденные проблемы

Разработчик, будь готов к:

Ошибкам в выборе технологии

Переписыванию проекта под нагрузкой

К тому, что зачастую единственный результат — знание, как не надо делать и что технология вам не подходит

Вопросы?

top related