Прежде всего, у меня очень мало опыта по балансировке нагрузки / масштабированию веб-приложений. У меня есть мобильная игра (клиент) и внутренний сервер.
Внутренний сервер:
- Кодируется
Java/Spring
- Имеет ~ 50 конечных точек веб-служб
- Большинство конечных точек имеют среднее время обслуживания
20ms
, включая вызовы базы данных. Существуют более дорогие конечные точки, но они не используются регулярно (/login
, et c.) - Работает на
Heroku
, используя Postgres
- Разработан с возможностью горизонтального масштабирования
- Прямо сейчас каждый веб-дино имеет
10 DB connections
макс
Я пытаюсь масштабировать серверную часть, поэтому я смогу обрабатывать более 1 million daily active users
. Я понятия не имею, каким будет RPS в таком случае, но в настоящее время с 3000 DAU
это ~7 RPS
, поэтому я могу предположить, что это будет что-то около 2300 RPS
.
Итак, я вычислил среднее значение моих наиболее часто используемых конечных точек в производственной среде, и оказалось, что они принимают 20ms
в среднем
Итак, технически 1 соединение с базой данных должно поддерживать 1000/20 = 50 requests per second
. Как я уже говорил, у меня в пуле есть 10 DB connections
, поэтому 1 web dyno
должен обрабатывать 500 RPS
. Конечно, это не так просто, потому что большинство конечных точек выполняют более одного вызова базы данных, et c.
Итак, я протестировал его с loader.io
, и оказалось, что сервер может обрабатывать 250RPS
, сохраняя при этом нормальное время обслуживания (20ms)
. На 260 RPS
иногда немного отстает (60-80 мс), а иногда наступает сумасшедшая смерть l oop и запросы застревают на hikari.getConnection()
на срок до 5 секунд (из-за того, что пакеты все еще накапливаются. в других потоках и c. Он просто не успевает, если он застрял).
Эти тесты, которые я запускал, были просто простыми, 1-minute
тесты с 250RPS load
, одним из наиболее часто используемых конечные точки.
Теперь по делу
Я подумал - ОК. Теперь, если я запустил 2 веб-сервера, я смогу легко справиться с 500RPS
. Так что мне понадобится всего 10 dynos
, чтобы обработать все 2300 RPS
, которые я хочу. Угадайте, что ... Это не так просто :)
При запуске 2 dynos
я могу обрабатывать ~300-330 RPS
, и самое главное, когда я увеличиваю количество дино до 3 or 4
, это тоже самое. Начинает сходить с ума после ~300 RPS
.
У меня 2 вопроса:
Это из-за Heroku
' s балансировщик нагрузки, который просто беспорядочно перенаправляет пакеты на динамометрические станции? (это мое предположение). Если у нас есть 2 dynos
, каждый из которых может обрабатывать 250RPS
, ничто не останавливает LB Heroku
для маршрута 300 packets to 1 dyno at the same time
- это случайно. И сервер переполняется. Я думаю, что round-robin load balancer
полностью решит мою проблему, не так ли?
Когда я загружаю тестовые материалы, мне обычно приходится прогревать систему, потому что во время начальных запусков это отстает. Я думал, что это классы Java инициализируются / разогреваются, но это становится еще более безумным. Иногда мне приходится делать 3-4 прогона со скоростью 250 об / сек, пока дино не стабилизируется, а затем каждый прогон работает отлично. Но иногда мне нужно прогреть его в течение ~ 20 минут ... Это обычное / нормальное поведение?