Узкое место нагрузочного тестирования на nodejs с Google Compute Engine

Я не могу понять, в чем причина узкого места на этом сайте, очень плохое время отклика после того, как достигло около 400 пользователей. Сайт находится на вычислительной машине Google с использованием группы экземпляров с балансировкой сетевой нагрузки. Мы создали проект с помощью sailjs.
Я проводил нагрузочное тестирование с контейнерным движком Google, используя kubernetes, используя скрипт locust.py.

Основные результаты одного из тестов:

RPS : 30
Spawn rate: 5 p/s
TOTALS USERS: 1000
AVG(res time): 27500!! (27,5 seconds)

Первоначально время отклика велико, менее одной секунды, но когда оно достигает примерно 400 пользователей, время отклика начинает резко возрастать.

Я проверил очевидные факторы, которые могут повлиять на время отклика, результаты приведены ниже:

Экземпляры вычислительного ядра (2 стандартных n2, диск 200 ГБ, оперативная память: 7,5 ГБ на экземпляр):

Only about 20% cpu utilization used
Outgoing network bytes: 340k bytes/sec
Incoming network bytes: 190k bytes/sec
Disk operations: 1 op/sec
Memory: below 10%

MySQL:

Max_used_connections : 41 (below total possible)
Connection errors: 0

Все остальные результаты для MySQL также кажутся хорошими, нет причин создавать узкое место.

Я попробовал тот же тест для нового проекта, созданного SailJS, и он показал себя лучше, но все равно имел ужасные результаты, время разрешения 5 секунд для примерно 2000 пользователей.

Что еще я должен протестировать? Что может быть узким местом?


person cfl    schedule 02.03.2016    source источник
comment
Вероятно, это в вашем коде node.js. Вероятно, что-то синхронное блокирует цикл событий, который взрывается, когда вы запускаете запросы в секунду. Попробуйте профилировать его.   -  person bbuckley123    schedule 02.03.2016
comment
Спасибо. Я нашел много людей, говорящих, что globalAgent.maxSockets может быть проблемой. Текущее значение по умолчанию - 5. Может ли это быть причиной? @ bbuckley123   -  person cfl    schedule 03.03.2016
comment
По умолчанию используется Infinity. Так было в нескольких выпусках узлов: nodejs.org/api/http.html#http_agent_maxsockets   -  person bbuckley123    schedule 03.03.2016
comment
Наша версия узла была «старой», но все еще оставалось ограничение. Но я обновил узел до версии с бесконечным MaxSockets, но это, похоже, ни на что не повлияло.   -  person cfl    schedule 04.03.2016
comment
Я создал новый проект sailsjs и таким же образом прогнал его через нагрузочное тестирование, результаты были лучше, но все равно ужасны !! Время отклика составило секунды уже около 2 тысяч пользователей. Хотите знать, не проблема ли в sailsjs?   -  person cfl    schedule 04.03.2016
comment
Профилирование указывает на то, что плохое время отклика исходит из (простоя).   -  person cfl    schedule 08.03.2016
comment
Вы проводите тесты для своего проекта? В своих тестах я обычно могу имитировать отправку запроса пользователем, вплоть до ответа от сервера. Обычно это указывает на то, где может быть узкое место.   -  person Bwaxxlo    schedule 09.03.2016
comment
Я тестирую основные части сайта с помощью locust.py, запросы на домашний url / и самую тяжелую часть нашего сайта, максимально возможную обработку данных. Они выбираются случайным образом от 2 до 7 секунд для каждого запроса на пользователя. У обоих плохое время отклика. Спасибо за ответ @Bwaxxlo 8   -  person cfl    schedule 09.03.2016
comment
Локализовать высокую задержку может быть сложно, особенно когда для подключения требуется много шагов, таких как балансировка нагрузки, асинхронное время выполнения, доступ к файлам и подключения к БД. Кроме того, использование GCE исключает удобное использование Cloud Trace. Сможете ли вы описать или продемонстрировать поток данного запроса и то, как каждый шаг обрабатывается распределенным образом? Какие типы подключений используются? Как и когда в течение срока службы запроса вы ведете журнал и профилируете? Вышеизложенное может помочь указать на конкретные проблемы, а не полагаться на общие узкие места.   -  person Nicholas    schedule 09.03.2016


Ответы (1)


Вы занимаетесь чтением / записью файлов? Это серьезное препятствие для node.js, которое всегда вызывает некоторые проблемы. Кэширование прочитанных файлов или устранение необходимости в таком коде должно выполняться в максимально возможной степени. По моему собственному опыту, обслуживание файлов, таких как изображения, css, js и т. Д., Через мой сервер узла могло бы вызвать проблемы, когда количество одновременных запросов увеличилось. Решением было обслуживать все это через CDN.

Другой проблемой может быть драйвер mysql. У нас были некоторые проблемы с некорректным закрытием соединения (не используя sails.js, но я думаю, что они использовали тот же драйвер в то время, когда я столкнулся с этим), поэтому они могут вызвать проблемы на сервере mysql, что приведет к долгим задержкам при извлечении данных из базы данных. Вы должны время / отслеживать количество запросов mysql и убедиться, что они не задерживаются.

Наконец, это может быть особая проблема с sails.js и вычислительным движком Google. Вы должны убедиться, что в любом из них нет открытых вопросов, связанных с той же проблемой, с которой вы столкнулись.

person Stian    schedule 07.03.2016
comment
Практически не было чтения / записи в нашем проекте, и совершенно новый проект sailsjs также «провалился», который практически не выполняет операций чтения / записи. Итак, хотя CDN и помогает с оптимизацией, он не показывает, почему наши результаты такие плохие? Я проверил экземпляр mysql, там нет узких мест, почти нет операций чтения / записи. Как уже упоминалось, мы попробовали новый проект sailsjs, который не использует запросы к базе данных. Последний пункт, о котором вы упомянули, возможен, я еще ничего не нашел, но буду искать. Благодарю за ваш ответ - person cfl; 08.03.2016
comment
@cfl, вы отправляете запросы POST или GET (я где-то читал о проблеме с POST в sails.js)? Не могли бы вы создать репо, чтобы показать, что именно вы делаете? - person amberv; 12.03.2016
comment
Да, это то, что мы используем для наших запросов. Мы используем это в нашем файле routes.js. Что это была за проблема, наверное, помните? Черт возьми, репо - сложное дело, потому что у меня есть проблемы с интеллектуальной собственностью. Что именно вы хотите от репо? Но чтобы дать представление о потоке, мы используем sails.get (/ get_info, message), который затем проходит через routes.js для вызова метода контроллера. Затем метод контроллера выполняет запросы к базе данных и т. Д. С ватерлинией, а затем отвечает. @amberv - person cfl; 14.03.2016
comment
@cfl, насколько я помню, был какой-то странный холостой ход POST-запросов на XX мс по сравнению с GET-запросами. Я не уверен, что это причина ваших проблем (и, скорее всего, это не так, как похоже, что вы выполняете GET), но вы можете сравнить время отклика при изменении запросов POST на GET (если у вас есть POST), сохраняя все остальное то же самое. В любом случае это не должно быть трудным. Наконец, в целях тестирования, может быть, вы могли бы создать новый базовый проект Express и посмотреть, достигнете ли вы аналогичных ограничений? Тогда вы сделаете вывод, вызвано ли это Express, а не sails.js - person amberv; 14.03.2016
comment
@amberv Спасибо за помощь. Я понимаю, что мы используем некоторые почтовые запросы, но нагрузочное тестирование проводилось только для запросов на получение. Однако я буду иметь это в виду и, возможно, использую это для улучшений. Хорошая идея, которую стоит протестировать, опубликую здесь, если результаты были из-за express, а не sails.js - person cfl; 14.03.2016
comment
@cfl, не могли бы вы узнать, в чем проблема? - person amberv; 31.03.2016
comment
@amberv Неа, я даже общался с техподдержкой гугла, но ничего полезного из этого не вышло. Тем не менее, я смог кое-что придумать. Я удалил sails.io и провел несколько тестов, которые затем показали, что ужасный rps каким-то образом связан с db. Если я загружаю тестовый URL-адрес, который не использует db, он остается быстрым до 2000 пользователей, но нагрузочный тест, требующий выбора db, ужасен и более 10 секунд отклика от 150 пользователей. Недавно я попытался использовать Google SQL 2-го поколения, пока не улучшилось. Итак, я играю с настройками pool, connectionLimit, waitForConnections на стороне sails.js. - person cfl; 31.03.2016
comment
@cfl, может быть, вам было бы интересно настроить очень простой сервер на чистом node.js с несколькими строками кода и посмотреть, какие ограничения вы попадете в этом случае? И если он намного лучше, чем текущий лимит 2000, который у вас есть, вы можете добавить собственный драйвер db и выполнять свой выбор во время запроса. Тогда вы точно узнаете, какой отзывчивости вы сможете достичь. Это всего лишь идея, но, похоже, ее несложно реализовать. И все же это могло быть довольно информативным. - person amberv; 31.03.2016