Я запускаю очень простой RESTful API на AWS, используя Node.js. API принимает запрос в виде «/ отдых/пользователей/JDoe» и возвращает следующее (это не все сделано в памяти, не баз данных, участвующих):Медленная производительность для Node.js, работающая на AWS
{
username: 'jdoe',
firstName: 'John',
lastName: 'Doe'
}
производительность этого API на Node.js + AWS ужасен по сравнению с локальной сетью - всего 9 запросов/сек против 2214 запросов в секунду в локальной сети. AWS запускает экземпляр m1.medium, тогда как локальный Node-сервер - настольный компьютер с процессором Intel i7-950. Попытка выяснить, почему такая огромная разница в производительности.
контрольные показатели с помощью Apache Bench заключаются в следующем:
Локальная сеть
10000 запросов с параллелизмом 100/группы
> ab -n 10000 -c 100 http://192.168.1.100:8080/rest/users/jdoe
Document Path: /rest/users/jdoe
Document Length: 70 bytes
Concurrency Level: 100
Time taken for tests: 4.516 seconds
Complete requests: 10000
Failed requests: 0
Write errors: 0
Total transferred: 2350000 bytes
HTML transferred: 700000 bytes
Requests per second: 2214.22 [#/sec] (mean)
Time per request: 45.163 [ms] (mean)
Time per request: 0.452 [ms] (mean, across all concurrent requests)
Transfer rate: 508.15 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 0 0.4 0 2
Processing: 28 45 7.2 44 74
Waiting: 22 43 7.5 42 74
Total: 28 45 7.2 44 74
Percentage of the requests served within a certain time (ms)
50% 44
66% 46
75% 49
80% 51
90% 54
95% 59
98% 65
99% 67
100% 74 (longest request)
AWS
1000 запросов с параллельности от 100/группа (10000 запросов заняло бы слишком много времени)
C:\apps\apache-2.2.21\bin>ab -n 1000 -c 100 http://54.200.x.xxx:8080/rest/users/jdoe
Document Path: /rest/users/jdoe
Document Length: 70 bytes
Concurrency Level: 100
Time taken for tests: 105.693 seconds
Complete requests: 1000
Failed requests: 0
Write errors: 0
Total transferred: 235000 bytes
HTML transferred: 70000 bytes
Requests per second: 9.46 [#/sec] (mean)
Time per request: 10569.305 [ms] (mean)
Time per request: 105.693 [ms] (mean, across all concurrent requests)
Transfer rate: 2.17 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 98 105 3.8 106 122
Processing: 103 9934 1844.8 10434 10633
Waiting: 103 5252 3026.5 5253 10606
Total: 204 10040 1844.9 10540 10736
Percentage of the requests served within a certain time (ms)
50% 10540
66% 10564
75% 10588
80% 10596
90% 10659
95% 10691
98% 10710
99% 10726
100% 10736 (longest request)
Вопросы:
- Connect время AWS 105 мс (средн) по сравнению с 0 мс в локальной сети. Я предполагаю, что это связано с тем, что для открытия сокета AWS на сервер в локальной сети требуется намного больше времени. Есть ли что-то, что можно сделать здесь для повышения производительности при загрузке, если запросы поступают с нескольких компьютеров по всему миру.
- Более серьезное время обработки сервера - 45 мс для локального сервера по сравнению с 9,9 секундами для AWS! Я не могу понять, что здесь происходит. Сервер только нажимает 9.46 запросов/сек. который является арахисом!
Любое понимание этих вопросов очень ценится. Я нервничаю из-за серьезного применения на Node + AWS, если он не может выполнить супер быстро на таком простом приложении.
Для справки вот мой код сервера:
var express = require('express');
var app = express();
app.get('/rest/users/:id', function(req, res) {
var user = {
username: req.params.id,
firstName: 'John',
lastName: 'Doe'
};
res.json(user);
});
app.listen(8080);
console.log('Listening on port 8080');
Редактировать
Single запрос, отправленный в изоляции (-n 1 -с 1)
Requests per second: 4.67 [#/sec] (mean)
Time per request: 214.013 [ms] (mean)
Time per request: 214.013 [ms] (mean, across all concurrent requests)
Transfer rate: 1.07 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 104 104 0.0 104 104
Processing: 110 110 0.0 110 110
Waiting: 110 110 0.0 110 110
Total: 214 214 0.0 214 214
10 запрос все отправленные одновременно (-n 10 -c 10)
Requests per second: 8.81 [#/sec] (mean)
Time per request: 1135.066 [ms] (mean)
Time per request: 113.507 [ms] (mean, across all concurrent requests)
Transfer rate: 2.02 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 98 103 3.4 102 110
Processing: 102 477 296.0 520 928
Waiting: 102 477 295.9 520 928
Total: 205 580 295.6 621 1033
Результаты использования Wrk
Как полагает Андрей Сидоров.Результаты гораздо лучше - 2821 запросов в секунду:
Running 30s test @ http://54.200.x.xxx:8080/rest/users/jdoe
12 threads and 400 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 137.04ms 48.12ms 2.66s 98.89%
Req/Sec 238.11 27.97 303.00 88.91%
84659 requests in 30.01s, 19.38MB read
Socket errors: connect 0, read 0, write 0, timeout 53
Requests/sec: 2821.41
Transfer/sec: 661.27KB
Так что, конечно, выглядит как преступник ApacheBench! Невероятно!
Рассекая это на более мелкие куски, то первый вопрос, который выскакивает есть то, что делает один запрос, отправленный в изоляции выглядеть так далеко, как время отклика? Это разумно? Во-вторых, во время бенчмаркинга вы максимизируете CPU на машине AWS? Существует ли нижняя точка останова параллелизма, где уровни отклика? –
Я добавил числа для одного запроса и 10 одновременных запросов (см. Правки в вопросе). Время отклика все еще довольно велико: 214 мс и 580 мс (4,67 запросов/сек и 8,81 запросов/сек). CPU на AWS практически бездействует (1,25%). – Naresh
Вы хотите провести тесты в рамках AWS, чтобы получить лучший ответ от яблок к яблокам, потому что я подтвердил то, что я подозревал (в моих собственных тестах), что «connect» никогда не может быть меньше приблизительного времени пинга от ' ab 'на сервер, а «total» никогда не может быть меньше 2 x ping ... это синхронизация * всего * соединения от открытого до закрытого; поэтому, хотя у вас действительно есть что-то стоящее, чтобы расследовать, я подозреваю, что вы не увидите числа, которые особенно значимы или действительно сопоставимы с местным тестом, пока вы не попробуете «локальный» тест, инициированный в той же зоне доступности EC2. –