РИТ++ 2017
Зал Конгресс-холл, 5 июня, 12:00
Тезисы:
http://ritfest.ru/2017/abstracts/2749.html
Раньше HeadHunter был большим монолитным приложением. Несколько лет назад мы приняли решение выделять из него микросервисы. За несколько лет мы поняли, что микросервисы - это не серебряная пуля и при неправильном "распиле" создают существенные проблемы: сложность разработки, деплоя, эксплуатации и др. Иногда эти проблемы сводят на нет преимущества от использования микросервисов.
В докладе хочу взвесить преимущества и недостатки микросервисов при вертикальном и горизонтальном делении на микросервисы.
9. ЧТО КРУТО?
● Декомпозиция монолита
(несколько простых сервисов с явным API проще монстра-монолита)
● Проще тестировать
(застабил внешние походы и вперед)
● Независимые релизы
(когда хочу, тогда тестирую и выпускаю свой сервис)
9
10. ЧТО ЕЩЕ КРУТО?
● Независимая деградация
(когда лежит сервис А, сервис Б продолжает работать)
● Независимое масштабирование
(закупаем серверы только под те сервисы,
которые нужно отмасштабировать)
● Возможность пробовать новые технологии
(небольшой сервис переписать проще)
● Команда-владелец
(отвечает за сервис, заинтересована в поддержке и развитии)
10
12. ВЕСЬ КОНТЕКСТ ЗАПРОСА
Сервис А:
● сделал то
● сделал се
● сходил туда
● сходил сюда
● ошибка
Сервис Б:
● сделал то
● сделал се
● сходил туда
● сходил сюда
● сделал тото
● вернул тото
Сервис В:
● сделал что
● сделал то
● сходил ли
● вернул ли
Сервис Г:
● сделал то
● сделал се
● сделал тото
● сделал сето
Сервис Ж:
● сделал то
● сходил туда
● сделал се
● упал
12
13. ВЕСЬ КОНТЕКСТ ЗАПРОСА
● Присваиваем каждому пользовательскому запросу идентификатор
● Ищем все логи по идентификатору с помощью Graylog:
○ Много логов (1.3 TB / день)
○ 100% CPU на машинах Graylog
○ Много потерь
● Вложились в собственное решение
(timestamped request id + бинарный поиск в логах)
13
14. RPC ТЯЖЕЛЕЕ ВЫЗОВА МЕТОДА
Железо дешевое,
а его обслуживание?
https://github.com/AntonIvanov87/java-benchmarks/tree/master/rpc-benchmarks
14
15. RPC СЛОЖНЕЕ ВЫЗОВА МЕТОДА
● Пулы соединений, пулы байт-буферов, эвент-лупы…
Все это — много непростого кода с множеством настроек
● Требуется думать, что будет при ошибках RPC
Search client
HH http client
Async http client
Netty
15
17. таймаут 2 сек
balancer
service A service A
balancer
service B service B
balancer
service C service C
● Все запросы на service C укладываются
в 0.25 сек?
● Есть запас?
● Отдельные таймауты для “тяжелых”
запросов?
● Как не завалить себя ретраями во
время проблем с базой сервиса C?
● Что делать, если service A хочет ходить
в service C напрямую?
● Что делать, если хотим не один ретрай,
а больше?
1 сек
1 сек
0.5 сек
0.5 сек
0.25 сек
17
18. ЦЕРЕМОНИЯ: НОВЫЙ СЕРВИС
● Выбираем на чем писать, дописываем под себя
● Упаковываем (деабинизируем / докеризируем / ...)
● Настраиваем процедуру выкладки
● Настраиваем ротацию и заливку логов
● Настраиваем мониторинг и триггеры
● Подключаем систему мониторинга низкочастотных ошибок
● ...
18
19. ПОДДЕРЖКА В АКТУАЛЬНОМ СОСТОЯНИИ
● Решили замониторить походы в memcached
○ Выделяем библиотеку hh-memcached-client
○ Проходимся по 100500 сервисов и обновляем
● Решили отпинывать запросы, если сервис перегружен
○ Выделяем библиотеку hh-http-server-utils
○ Проходимся по 100500 сервисов и обновляем
○ Опять проходимся по 100500 сервисов и донастраиваем пороги срабатывания
● Часто выбираем 3-5 главных сервиса, на остальные забиваем (((
○ Потом таки надо обновить и долго обновляем, перепрыгивая несколько версий
19
22. ЕСТЬ ЛИ ЕЩЕ СПОСОБЫ ДЕКОМПОЗИРОВАТЬ?
● ru.hh.dao
○ public VacancyDAO
○ public ResumeDAO
○ public UserDAO
○ ...
● ru.hh.service
○ public VacancyService
○ public ResumeService
○ public UserService
○ ...
● ru.hh.resource
○ public VacancyResource
○ public ResumeResource
○ public UserResource
○ …
22
● Пакеты (“папки”) классов по бизнес-
фичам, а не по слоям
● Модули - коллекция пакетов - с явными
зависимости от других модулей
● Потом проще выделять сервис
23. “ПРОЩЕ” ТЕСТИРОВАТЬ
Протестировать сервис — хорошо, а как протестировать всю систему?
Сложные стенды, в которых нужно развернуть все сервисы,
откорректировать настройки (таймауты, например),
а потом поддерживать.
23
24. “НЕЗАВИСИМЫЕ” РЕЛИЗЫ
Предположим, вам нужно изменить API одного из вызовов сервиса C:
● релиз C с совместимым API
● релиз B с совместимым API
● переключение A на использование нового API
● выпиливание старого API из B
● выпиливание старого API из C
service A service B service C
24
25. “НЕЗАВИСИМАЯ” ДЕГРАДАЦИЯ
● Лежит сервис поиска
○ лежит половина сайта
● Лежит сервис откликов и приглашений
○ лежит половина сайта
● Лежит сервис сессии
○ лежит весь сайт
25
27. СЛОЖНОСТИ МАСШТАБИРОВАНИЯ
● Виртуалки, docker, оркестрация…
● “Независимое” масштабирование круто,
когда требуется специфичное оборудование.
Server
App
Server
App
Server
App
Server
App
Server
App
Server
AppApp
App
App
App
App
AppApp App App
27
28. ВОЗМОЖНОСТЬ ПРОБОВАТЬ ТЕХНОЛОГИИ
● Зоопарк технологий
(где-то Spring, где-то Guice, надо знать оба)
● Зоопарк подходов
(где-то юнит-тесты пишутся так, где-то — иначе)
● Гибко, но не единообразно.
28
29. КОМАНДА-ВЛАДЕЛЕЦ
● В некоторые сервисы пишут все
● SRE быстрее реагирует на проблемы, чем бизнес-команда-владелец,
у них — свои задачи
● В SRE больше технологических знаний
29