Микросервисы - это круто, модно и интересно. Переход на их использование принесет команде заметные преимущества. Но сервис-ориентированная архитектура (SOA) не лишена недостатков. Один их них - это то, что, заменяя простой вызов функции на RPC, мы в неявном виде вводим в уравнение, отвечающее за стабильность системы, целую плеяду новых неизвестных. Например, простейший HTTP-запрос за время своей жизни проходит через множество всевозможных буферов, очередей и алгоритмов на своем пути от клиента к серверу и обратно. Совокупное поведение этих составляющих трудно предсказать, понять и правильно интерпретировать. И особенно трудно это сделать в нестандартных ситуациях.
В своем докладе я хочу поделиться опытом решения проблем, с которыми я столкнулся за время работы в Booking.com. Я расскажу, как небольшой тюнинг сервера и клиента существенно влиял на конечную стабильность системы.
11. • в определенный момент
запускалась цепная реакция
• все машины покидали кластер
в течение 5-10 секунд
• кластер впадал в deadlock
• приходилось рестартовать все
машины
• не могли переключить трафик
на другой кластер, боясь
положить его
15. гистограмма результатов
запросов за последние 10 секунд
* – успешный запрос(ы)
E – ошибочный запрос(ы)
временные интервалы от 0 до ~1 сек
логарифмическая шкала
текущий/требуемый RPS
https://github.com/ikruglov/slapper
31. Решение проблемы
• Краткосрочное:
• снижение длины очереди
• «разрыв» цикла
• дешевый повтор
• Долгосрочное:
• переход на двухступенчатую архитектуру
34. Что делать с быстрыми ошибками?
• при насыщении
• ничего!!
• мягкое деградирование (graceful degradation)
• при кратковременном переполнении очереди
• повтор (retry)
36. retry
• бюджет
• идемпотентная операция
• до записи в сокет – OK, после - ?
• GET – OK, POST – not OK
• в реальности - ?
• быстрый повтор неэффективен
• нужен back-off
38. back-off
• вставить паузу между
попытками
• увеличивает шансы на успех
• алгоритмы:
• фиксированный
• экспоненциальный
• важна рандомизация – jitter
interval = 100 ms
randomization factor = 0.5
multiplier = 2
delta = interval * randomization factor
result = interval ± (delta * rand())
interval = interval * multiplier
53 ms
129 ms
555 ms
719 ms
431 ms
644 ms
934 ms
1605 ms
1732 ms
2126 ms
https://github.com/cenkalti/backoff/
42. Виды Chaos Monkey
• проверить HTTP клиент
• 50x-ый ответ
• работает в production
• мягкое деградирование
приложения
• 400-ый ответ
• работает только внутри компании
• есть список критических запросов
• готовность к задержкам в
репликации
• 200-ый ответ c логической ошибкой
• работает в production
43. transport transport
load balancingdiscovery
chaos monkeytimeouts
circuit breakerretry
…back-off
queue timeouts
chaos monkeyprioritization
throttling
service consumer service provider
client library server
…
44. Заключение
• Предсказуемая отправка HTTP запроса – это сложно!
• тестируйте и проверяйте!
• Посмотрите:
• frameworks - grpc, finagle, …
• proxy - linkerd, envoy, …
• Поэкспериментируйте с очередями:
• длина очереди влияет на время ответа
• контроль над клиентом
• nginx + unix socket