SOA:
послать запрос на сервер?
что может быть проще?!
Иван Круглов - Booking.com
плюсы
минусы
снижение гибкости
сложность внесения
атомарных изменений
сложная отладка
сложная инфраструктура
RPC
слабая связанность
независимый деплой
независимая разработка
быстрее onboarding
быстрее разработка
Booking.com
application
transport transport
provider
client library server
service consumer service provider
История одной проблемы
Архитектура поиска в Booking.com
https://goo.gl/gW7Jd6
https://goo.gl/BQFlJG
AVinv материализация AVAV
MR
веб-сервер
MR
MR
master
worker worker worker worker
coordinate/reduce
map
поисковый запрос
client 2
worker 1 worker 2 worker 3 worker 4 worker 5
client 1
client 2
worker 1 worker 2 worker 3 worker 4 worker 5
client 1
• в определенный момент
запускалась цепная реакция
• все машины покидали кластер
в течение 5-10 секунд
• кластер впадал в deadlock
• приходилось рестартовать все
машины
• не могли переключить трафик
на другой кластер, боясь
положить его
Демо
Setup
Server:
• nginx
• 24 workers
• backlog = 2048
• uwsgi
• 96 workers
• listen = 2048
• mixed CPU/IO bound
workload
Client:
• HTTP
• timeout 500 ms
• many small (< 1KB) / medium
(< 100 KB) requests
Сценарий
0
1000
2000
3000
4000
5000
6000
7000
8000
1 5 9 13 17 21 25 29 33 37 41 45
количество запросов
секунда
1 2 3
гистограмма результатов
запросов за последние 10 секунд
* – успешный запрос(ы)
E – ошибочный запрос(ы)
временные интервалы от 0 до ~1 сек
логарифмическая шкала
текущий/требуемый RPS
https://github.com/ikruglov/slapper
scenario-queues-2048-cut.gif
0
1000
2000
3000
4000
5000
6000
7000
8000
0
100
200
300
400
500
600
700
время ответа, мсколичество ответов
p99
успешные запросы
ошибочные запросы
Что происходит?
www
www
www
www
w
w
w
w
uwsgi
www
www
www
nginx
tnginx_worker
tuwsgi_worker
ttotal = tnginx_worker + tuwsgi_worker
scenario-queues-2048-part-1.gif
96 uwsgi workers
scenario-queues-2048-part-2.gif
Что происходит?
www
www
www
www
w
w
w
w
uwsgi
www
www
www
nginx
tnginx_worker
tuwsgi_worker
TCP socket unix socket
ttcp_socket
tunix_socket
ttotal = ttcp_socket + tnginx_worker + tunix_socket + tuwsgi_worker
Что происходит?
www
www
www
www
w
w
w
w
uwsgi
www
www
www
nginx
TCP socket unix socket
ttotal = ttcp_socket + tnginx_worker + tunix_socket + tuwsgi_worker
timeout
tnginx_worker
tuwsgi_worker
ttcp_socket
tunix_socket
Что происходит?
www
www
www
www
w
w
w
w
uwsgi
www
www
www
nginx
TCP socket unix socket
ttotal = ttcp_socket + tnginx_worker + tunix_socket + tuwsgi_worker
timeout
tnginx_worker
tuwsgi_worker
ttcp_socket
tunix_socket
100% CPU на сервере
scenario-queues-2048-part-3.gif
Что происходит?
www
www
www
www
w
w
w
w
uwsgi
www
www
www
nginx
TCP socket unix socket
502 Bad Gateway
ttotal = ttcp_socket + tnginx_worker + tunix_socket + tuwsgi_worker
timeout
client 2
worker 1 worker 2 worker 3 worker 4 worker 5
timeout
slowslow
timeout
Что происходит?
www
www
www
www
w
w
w
w
uwsgi
www
www
www
nginx
TCP socket unix socket
попробуем
сделать
меньше?!
listen=96
scenario-queues-96-3-cut.gif
0
1000
2000
3000
4000
5000
6000
7000
8000
0
10
20
30
40
50
60
70
80
90
100
время ответа, мсколичество ответов
p99
успешные запросы
ошибочные запросы
стабилизация стабилизация
сохранение
QoS
сохранение
QoS
0
1000
2000
3000
4000
5000
6000
7000
8000
0
10
20
30
40
50
60
70
80
90
100
время ответа, мсколичество ответов
p99
успешные запросы
ошибочные запросы
стабилизация стабилизация
сохранение
QoS
сохранение
QoS
0
10
20
30
40
50
60
70
80
90
100
p99 backlog=192
p99 backlog=96
p99 backlog=20
мс
Решение проблемы
• Краткосрочное:
• снижение длины очереди
• «разрыв» цикла
• дешевый повтор
• Долгосрочное:
• переход на двухступенчатую архитектуру
Конец истории
transport transport
service consumer service provider
client library
timeouts
server
queue
Что делать с быстрыми ошибками?
• при насыщении
• ничего!!
• мягкое деградирование (graceful degradation)
• при кратковременном переполнении очереди
• повтор (retry)
transport transport
timeouts queue
retry
service consumer service provider
client library server
retry
• бюджет
• идемпотентная операция
• до записи в сокет – OK, после - ?
• GET – OK, POST – not OK
• в реальности - ?
• быстрый повтор неэффективен
• нужен back-off
transport transport
timeouts queue
retry
back-off
service consumer service provider
client library server
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/
transport transport
timeouts queue
retry
back-off
timeouts
service consumer service provider
client library server
Согласованность таймаутов
• отмена запроса (request cancellation)
• X-Booking-Timeout-Ms
• таймаут сервера = таймаут клиента + дельта
transport transport
timeouts queue
retry
back-off
timeouts
chaos monkey
service consumer service provider
client library server
chaos monkey
Виды Chaos Monkey
• проверить HTTP клиент
• 50x-ый ответ
• работает в production
• мягкое деградирование
приложения
• 400-ый ответ
• работает только внутри компании
• есть список критических запросов
• готовность к задержкам в
репликации
• 200-ый ответ c логической ошибкой
• работает в production
transport transport
load balancingdiscovery
chaos monkeytimeouts
circuit breakerretry
…back-off
queue timeouts
chaos monkeyprioritization
throttling
service consumer service provider
client library server
…
Заключение
• Предсказуемая отправка HTTP запроса – это сложно!
• тестируйте и проверяйте!
• Посмотрите:
• frameworks - grpc, finagle, …
• proxy - linkerd, envoy, …
• Поэкспериментируйте с очередями:
• длина очереди влияет на время ответа
• контроль над клиентом
• nginx + unix socket
Спасибо!
Иван Круглов
ivan.kruglov@booking.com
Ссылки
• https://github.com/ikruglov/slapper
• SRE book
• resiliency patterns
• https://developers.redhat.com/blog/2017/05/16/it-takes-more-than-a-circuit-breaker-to-create-a-resilient-application/
• https://www.youtube.com/watch?v=dlixGkelP9U
• https://www.youtube.com/watch?v=modXC5IWTJI
• circuit breaker
• SRE book Chapter 21 - Handling Overload
• https://docs.microsoft.com/en-us/azure/architecture/patterns/circuit-breaker
• backoff
• https://www.awsarchitectureblog.com/2015/03/backoff.html
• tcp_abort_on_overflow
• http://veithen.github.io/2014/01/01/how-tcp-backlog-works-in-linux.html
• https://www.frozentux.net/ipsysctl-tutorial/chunkyhtml/tcpvariables.html
• https://github.com/ton31337/tools/wiki/Is-net.ipv4.tcp_abort_on_overflow-good-or-not%3F

SOA: послать запрос на сервер? Что может быть проще?!