nodejs в highload проекте / Акрицкий Владимир (iage engineering)
TRANSCRIPT
NodeJS в HighLoad проектеВладимир Акрицкий
О себе
Тимлид в компании iAGE Engineering в разработке высоконагруженных проектов
Сооснователь хакерспейса FutureLab в г. Ульяновске
О проектеDMP (Data Management Platform) — база данных интересов пользователей
Помечаем пользователя при помощи Cookie
Сортируем по интересам
10 000 запросов в секунду
время ответа не более 10 мс
обработка 100+ ГБ логов в сутки
Нагрузка
7 микросервисов
около 80% кода на NodeJS
Архитектура
Никто не знает, как это готовить...
Выбор технологий
• .Net
• PHP
• Ruby
• Go
• Python
• NodeJS
Хорошее начало
Быстрая разработка
Быстрые результаты
Довольный клиент
Хорошо - хорошо, да не очень-то...
Проблемы
• Спагетти код = Callback hell
• Сторонние модули
• Утечка
• Нехватка памяти
Нехватка памяти
• 2GB хватит всем
• Максимальное увеличение до 8GB
• Обязательно учитывать этот факт и при необходимости разносить на процессы
Утечка
• Чем больше памяти уходит, тем дольше ответ на запрос
• heapdump не дает никаких результатов
• За неделю утечки время ответа переваливало за 20 мс
Что же делать???
Временное решениеПерезапуск приложения каждую ночь.
Cторонние модули
• Оказалось для нас самой страшной проблемой
Крах базы — крах всего
Попытка разобраться
• Ошибка воспроизводится в случайный момент и только под определенной нагрузкой
• Откат версии не помогает
• Разработчики модуля не могут воспроизвести
Спасение
Спустя больше месяца получили фикс
А с ним и сюрприз…..
После обновления модуля пропала утечка
Спагетти код
Модель
Модуль
Микросервис
М
М
М
1 Этап• Выделяем большие функциональности в отдельные
проекты, они же микросервисы
• Назначаем ответственных за каждый сервис
Плюсы:
– Из одной большой свалки в несколько поменьше
– У ответственности есть границы
Минусы:
– Увеличилось время обмена данными
Микросервисы
Было...
≤ 3мс
Дима
Вася
Петя
Стало...
≤ 3мс
< 1мс < 1мс < 1мс
Дима
Вася
Петя
Коммуникация• HTTP
– QPS: 10k — 30k– Time: 1 — 3 мс
• Наша реализация
– QPS: 100+k– Time: < 1 мс
aud-socket-server
aud-socket-client
2 Этап• Все, что возможно, выносим в модели, оставляя
только бизнес логику;
• Но не углубляемся в ООП;
Плюсы:
– Код становится читабельнее
Минусы:
– Увеличивается порог вхождения
Без моделей
this.db.getUsers(id, function(err, user) {
this.db.getProfiles(user.profileId, function(err, profile) {
doSomthingWithProfile(profile);
});
});
С моделями
Profiles.getByUser(id, doSomthingWithProfile);
Users = {
...
}
Profiles = {
...
}
3 Этап• Группы моделей оборачиваем в API и превращаем в
модули (npm)
Плюсы:
– Код становится переносимым
Минусы:
– Надо следить за версиями в каждом микросервисе
Модули
v1.0.3
Модули
v2.0.0 v1.0.3
Package.json
"dependencies": {
...
"my_module": "git+ssh://git@gitrepo:user/repo.git#v1.0.3",
...
}
Вывод• Дробите все на мелкие части (МММ);
• При поиске проблем в первую очередь отсекайте все чужое;
• Не забывайте про лимиты;
• Воспринимайте NodeJS как прототип, который требуется впоследствии переделывать.