POC para comparação de performance e consumo de recursos entre:
- Golang X Nodejs em container
- Golang X Nodejs em lambda
Golang Ping 500 RPS
(base) marcelo@marcelo-A72-LIV:~/Documents/ambiente/projetos/benchmark-langs/k6-scripts$ k6 run golang-ping.js --out json=result-golang-app.json
/\ |‾‾| /‾‾/ /‾‾/
/\ / \ | |/ / / /
/ \/ \ | ( / ‾‾\
/ \ | |\ \ | (‾) |
/ __________ \ |__| \__\ \_____/ .io
execution: local
script: golang-ping.js
output: json (result-golang-app.json)
scenarios: (100.00%) 1 scenario, 500 max VUs, 5m30s max duration (incl. graceful stop):
* constant_request_rate: 500.00 iterations/s for 5m0s (maxVUs: 100-500, gracefulStop: 30s)
WARN[0008] Insufficient VUs, reached 500 active VUs and cannot initialize more executor=constant-arrival-rate scenario=constant_request_rate
running (5m01.0s), 000/500 VUs, 148894 complete and 0 interrupted iterations
constant_request_rate ✓ [======================================] 000/500 VUs 5m0s 500 iters/s
✓ status was 200
checks.........................: 100.00% ✓ 148894 ✗ 0
data_received..................: 21 MB 70 kB/s
data_sent......................: 17 MB 57 kB/s
dropped_iterations.............: 1107 3.677719/s
http_req_blocked...............: avg=5.43µs min=861ns med=2.42µs max=36.71ms p(90)=7.57µs p(95)=8.42µs
http_req_connecting............: avg=1.54µs min=0s med=0s max=36.55ms p(90)=0s p(95)=0s
http_req_duration..............: avg=223.02µs min=91.82µs med=202.53µs max=15.15ms p(90)=333.5µs p(95)=371.7µs
{ expected_response:true }...: avg=223.02µs min=91.82µs med=202.53µs max=15.15ms p(90)=333.5µs p(95)=371.7µs
http_req_failed................: 0.00% ✓ 0 ✗ 148894
http_req_receiving.............: avg=23.57µs min=8.59µs med=19.36µs max=834.67µs p(90)=38.76µs p(95)=48.27µs
http_req_sending...............: avg=16.8µs min=3.99µs med=10.05µs max=2.22ms p(90)=36.12µs p(95)=40.22µs
http_req_tls_handshaking.......: avg=0s min=0s med=0s max=0s p(90)=0s p(95)=0s
http_req_waiting...............: avg=182.64µs min=74.57µs med=164.19µs max=14.91ms p(90)=276.42µs p(95)=309.97µs
http_reqs......................: 148894 494.661502/s
iteration_duration.............: avg=1s min=1s med=1s max=1.03s p(90)=1s p(95)=1s
iterations.....................: 148894 494.661502/s
vus............................: 500 min=297 max=500
vus_max........................: 500 min=297 max=500
Nodejs Ping 500 RPS
(base) marcelo@marcelo-A72-LIV:~/Documents/ambiente/projetos/benchmark-langs/k6-scripts$ k6 run nodejs-ping.js --out json=result-nodejs-app.json
/\ |‾‾| /‾‾/ /‾‾/
/\ / \ | |/ / / /
/ \/ \ | ( / ‾‾\
/ \ | |\ \ | (‾) |
/ __________ \ |__| \__\ \_____/ .io
execution: local
script: nodejs-ping.js
output: json (result-nodejs-app.json)
scenarios: (100.00%) 1 scenario, 500 max VUs, 5m30s max duration (incl. graceful stop):
* constant_request_rate: 500.00 iterations/s for 5m0s (maxVUs: 100-500, gracefulStop: 30s)
WARN[0006] Insufficient VUs, reached 500 active VUs and cannot initialize more executor=constant-arrival-rate scenario=constant_request_rate
running (5m01.0s), 000/500 VUs, 148605 complete and 0 interrupted iterations
constant_request_rate ✓ [======================================] 000/500 VUs 5m0s 500 iters/s
✓ status was 200
checks.........................: 100.00% ✓ 148605 ✗ 0
data_received..................: 28 MB 93 kB/s
data_sent......................: 17 MB 57 kB/s
dropped_iterations.............: 1396 4.637832/s
http_req_blocked...............: avg=5.74µs min=840ns med=2.52µs max=39.44ms p(90)=7.54µs p(95)=8.37µs
http_req_connecting............: avg=1.84µs min=0s med=0s max=39.35ms p(90)=0s p(95)=0s
http_req_duration..............: avg=349.6µs min=128.31µs med=260.65µs max=104.4ms p(90)=426.01µs p(95)=494.07µs
{ expected_response:true }...: avg=349.6µs min=128.31µs med=260.65µs max=104.4ms p(90)=426.01µs p(95)=494.07µs
http_req_failed................: 0.00% ✓ 0 ✗ 148605
http_req_receiving.............: avg=25.02µs min=9.4µs med=20.7µs max=4.79ms p(90)=40.24µs p(95)=48.86µs
http_req_sending...............: avg=16.72µs min=4.24µs med=10.43µs max=2.4ms p(90)=35.89µs p(95)=39.91µs
http_req_tls_handshaking.......: avg=0s min=0s med=0s max=0s p(90)=0s p(95)=0s
http_req_waiting...............: avg=307.85µs min=106.14µs med=220.24µs max=104.28ms p(90)=368.58µs p(95)=427.37µs
http_reqs......................: 148605 493.699864/s
iteration_duration.............: avg=1s min=1s med=1s max=1.1s p(90)=1s p(95)=1s
iterations.....................: 148605 493.699864/s
vus............................: 500 min=297 max=500
vus_max........................: 500 min=297 max=500
Golang 500 RPS
(base) marcelo@marcelo-A72-LIV:~/Documents/ambiente/projetos/benchmark-langs/k6-scripts$ k6 run golang-stocks.js --out json=result-golang-app-stocks.jsonclear
/\ |‾‾| /‾‾/ /‾‾/
/\ / \ | |/ / / /
/ \/ \ | ( / ‾‾\
/ \ | |\ \ | (‾) |
/ __________ \ |__| \__\ \_____/ .io
execution: local
script: golang-stocks.js
output: json (result-golang-app-stocks.jsonclear)
scenarios: (100.00%) 1 scenario, 500 max VUs, 5m30s max duration (incl. graceful stop):
* constant_request_rate: 500.00 iterations/s for 5m0s (maxVUs: 100-500, gracefulStop: 30s)
WARN[0003] Insufficient VUs, reached 500 active VUs and cannot initialize more executor=constant-arrival-rate scenario=constant_request_rate
running (5m01.2s), 000/500 VUs, 111375 complete and 0 interrupted iterations
constant_request_rate ✓ [======================================] 000/500 VUs 5m0s 500 iters/s
✗ status was 200
↳ 99% — ✓ 111259 / ✗ 116
checks.........................: 99.89% ✓ 111259 ✗ 116
data_received..................: 87 MB 288 kB/s
data_sent......................: 13 MB 44 kB/s
dropped_iterations.............: 38626 128.256452/s
http_req_blocked...............: avg=7.91µs min=854ns med=3.68µs max=38.81ms p(90)=8.4µs p(95)=9.57µs
http_req_connecting............: avg=2.83µs min=0s med=0s max=38.65ms p(90)=0s p(95)=0s
http_req_duration..............: avg=247.34ms min=26.02ms med=177.79ms max=2s p(90)=439.98ms p(95)=571.79ms
{ expected_response:true }...: avg=245.52ms min=26.02ms med=177.72ms max=1.98s p(90)=437.89ms p(95)=567.46ms
http_req_failed................: 0.10% ✓ 116 ✗ 111259
http_req_receiving.............: avg=46.45µs min=8.13µs med=25.8µs max=4.52ms p(90)=90.86µs p(95)=112.99µs
http_req_sending...............: avg=21.34µs min=3.85µs med=16.54µs max=2.73ms p(90)=38.65µs p(95)=43.79µs
http_req_tls_handshaking.......: avg=0s min=0s med=0s max=0s p(90)=0s p(95)=0s
http_req_waiting...............: avg=247.27ms min=25.96ms med=177.71ms max=2s p(90)=439.89ms p(95)=571.74ms
http_reqs......................: 111375 369.817284/s
iteration_duration.............: avg=1.24s min=1.02s med=1.17s max=3s p(90)=1.44s p(95)=1.57s
iterations.....................: 111375 369.817284/s
vus............................: 500 min=285 max=500
vus_max........................: 500 min=285 max=500
Nodejs 500 RPS
(base) marcelo@marcelo-A72-LIV:~/Documents/ambiente/projetos/benchmark-langs/k6-scripts$ k6 run nodejs-stocks.js --out json=result-nodejs-app-stocks.json
/\ |‾‾| /‾‾/ /‾‾/
/\ / \ | |/ / / /
/ \/ \ | ( / ‾‾\
/ \ | |\ \ | (‾) |
/ __________ \ |__| \__\ \_____/ .io
execution: local
script: nodejs-stocks.js
output: json (result-nodejs-app-stocks.json)
scenarios: (100.00%) 1 scenario, 500 max VUs, 5m30s max duration (incl. graceful stop):
* constant_request_rate: 500.00 iterations/s for 5m0s (maxVUs: 100-500, gracefulStop: 30s)
WARN[0002] Insufficient VUs, reached 500 active VUs and cannot initialize more executor=constant-arrival-rate scenario=constant_request_rate
running (5m01.2s), 000/500 VUs, 109669 complete and 0 interrupted iterations
constant_request_rate ✓ [======================================] 000/500 VUs 5m0s 500 iters/s
✓ status was 200
checks.........................: 100.00% ✓ 109669 ✗ 0
data_received..................: 90 MB 300 kB/s
data_sent......................: 13 MB 43 kB/s
dropped_iterations.............: 40332 133.910227/s
http_req_blocked...............: avg=9.5µs min=1.4µs med=3.51µs max=45.27ms p(90)=6µs p(95)=8.35µs
http_req_connecting............: avg=4.85µs min=0s med=0s max=45.21ms p(90)=0s p(95)=0s
http_req_duration..............: avg=268.93ms min=25.48ms med=185.47ms max=2s p(90)=490.99ms p(95)=615.47ms
{ expected_response:true }...: avg=268.93ms min=25.48ms med=185.47ms max=2s p(90)=490.99ms p(95)=615.47ms
http_req_failed................: 0.00% ✓ 0 ✗ 109669
http_req_receiving.............: avg=61.21µs min=15.05µs med=38.09µs max=15.12ms p(90)=97.56µs p(95)=139.78µs
http_req_sending...............: avg=20.66µs min=5.9µs med=16.4µs max=3.16ms p(90)=34.99µs p(95)=41.35µs
http_req_tls_handshaking.......: avg=0s min=0s med=0s max=0s p(90)=0s p(95)=0s
http_req_waiting...............: avg=268.85ms min=25.41ms med=185.37ms max=2s p(90)=490.86ms p(95)=615.39ms
http_reqs......................: 109669 364.122799/s
iteration_duration.............: avg=1.26s min=1.02s med=1.18s max=3s p(90)=1.49s p(95)=1.61s
iterations.....................: 109669 364.122799/s
vus............................: 500 min=295 max=500
vus_max........................: 500 min=295 max=500
Fase Inicial:
- Cria ou descongela a função
- Faz download do código;
- Configura as variáveis de ambiente;
- Roda as funções de inicialização - Tudo que não pertença à função handler
Fase Execução:
- A função handler é executada. Só pagamos por esse tempo (Billing execution).
Fase Desligamento:
- Quando a função não recebe requisições por x segundos, a lambda é desligada.
Lamdba Golang 100 RPS
running (5m30.0s), 000/500 VUs, 29110 complete and 10 interrupted iterations
constant_request_rate ✓ [======================================] 008/500 VUs 5m0s 100 iters/s
✗ status was 200
↳ 87% — ✓ 25462 / ✗ 3648
checks.........................: 87.46% ✓ 25462 ✗ 3648
data_received..................: 28 MB 86 kB/s
data_sent......................: 4.8 MB 15 kB/s
dropped_iterations.............: 880 2.666643/s
http_req_blocked...............: avg=4.65ms min=0s med=8.5µs max=7.97s p(90)=11.52µs p(95)=13.52µs
http_req_connecting............: avg=1.79ms min=0s med=0s max=7.56s p(90)=0s p(95)=0s
http_req_duration..............: avg=205.2ms min=0s med=202.34ms max=1.73s p(90)=297.39ms p(95)=353.62ms
{ expected_response:true }...: avg=234.68ms min=161.96ms med=207.86ms max=1.73s p(90)=308.47ms p(95)=362.67ms
http_req_failed................: 12.56% ✓ 3658 ✗ 25462
http_req_receiving.............: avg=777.72µs min=0s med=89.85µs max=919.1ms p(90)=142.72µs p(95)=176.2µs
http_req_sending...............: avg=32.27µs min=0s med=38.4µs max=408.81µs p(90)=53.74µs p(95)=60.68µs
http_req_tls_handshaking.......: avg=2.83ms min=0s med=0s max=2.57s p(90)=0s p(95)=0s
http_req_waiting...............: avg=204.39ms min=0s med=202.12ms max=1.73s p(90)=296.27ms p(95)=352.17ms
http_reqs......................: 29120 88.241645/s
iteration_duration.............: avg=4.97s min=1.16s med=1.21s max=31.01s p(90)=31s p(95)=31s
iterations.....................: 29110 88.211342/s
vus............................: 500 min=100 max=500
vus_max........................: 500 min=100 max=500
Lambda Nodejs 100 RPS
running (5m30.0s), 000/500 VUs, 26924 complete and 18 interrupted iterations
constant_request_rate ✓ [======================================] 012/500 VUs 5m0s 100 iters/s
✗ status was 200
↳ 86% — ✓ 23328 / ✗ 3596
checks.........................: 86.64% ✓ 23328 ✗ 3596
data_received..................: 23 MB 69 kB/s
data_sent......................: 4.4 MB 13 kB/s
dropped_iterations.............: 3058 9.266587/s
http_req_blocked...............: avg=6.89ms min=0s med=8.59µs max=16.94s p(90)=11.34µs p(95)=13.29µs
http_req_connecting............: avg=3.19ms min=0s med=0s max=15.75s p(90)=0s p(95)=0s
http_req_duration..............: avg=341.54ms min=0s med=222.82ms max=7.33s p(90)=502.08ms p(95)=1.15s
{ expected_response:true }...: avg=394.45ms min=152.59ms med=237.24ms max=7.33s p(90)=593.6ms p(95)=1.28s
http_req_failed................: 13.41% ✓ 3614 ✗ 23328
http_req_receiving.............: avg=1.36ms min=0s med=90.58µs max=2.19s p(90)=131.64µs p(95)=155.06µs
http_req_sending...............: avg=31.98µs min=0s med=38.32µs max=1.45ms p(90)=52.24µs p(95)=58.42µs
http_req_tls_handshaking.......: avg=3.59ms min=0s med=0s max=1.29s p(90)=0s p(95)=0s
http_req_waiting...............: avg=340.14ms min=0s med=222.49ms max=7.33s p(90)=495.2ms p(95)=1.13s
http_reqs......................: 26942 81.641721/s
iteration_duration.............: avg=5.35s min=1.15s med=1.25s max=31.01s p(90)=31s p(95)=31s
iterations.....................: 26924 81.587176/s
vus............................: 500 min=100 max=500
vus_max........................: 500 min=100 max=500
Query CloudWatch Log Insights:
filter @type = "REPORT" |
parse @message /Init Duration: (?<init>\S+)/ |
stats avg(@billedDuration) as avgBilledDuration,count() as total, count(init) as coldStarts, median(init) as avgInitDuration, max(init) as maxInitDuration, avg(@maxMemoryUsed)/1000/1000 as memoryused
Golang
[
{
"avgBilledDuration": "7.2808",
"total": "25466",
"coldStarts": "34",
"avgInitDuration": "82.71",
"maxInitDuration": "710.04",
"memoryused": "24.8359"
}
]
Nodejs
[
{
"avgBilledDuration": "39.5122",
"total": "23330",
"coldStarts": "109",
"avgInitDuration": "278.9925",
"maxInitDuration": "687.43",
"memoryused": "117.6351"
}
]
aws ecr get-login-password \
--region us-east-1 | docker login \
--username AWS \
--password-stdin 779882487479.dkr.ecr.us-east-1.amazonaws.com
export VERSION=latest
docker build -t golang-app .
docker tag golang-app:latest 779882487479.dkr.ecr.us-east-1.amazonaws.com/golang-app:$VERSION
docker push 779882487479.dkr.ecr.us-east-1.amazonaws.com/golang-app:$VERSION
docker run --publish 8080:8080 779882487479.dkr.ecr.us-east-1.amazonaws.com/golang-app:latest
export VERSION=latest
docker build -t nodejs-app .
docker tag nodejs-app:latest 779882487479.dkr.ecr.us-east-1.amazonaws.com/nodejs-app:$VERSION
docker push 779882487479.dkr.ecr.us-east-1.amazonaws.com/nodejs-app:$VERSION
terraform init
terraform destroy --auto-approve
terraform apply --auto-approve
k6 run golang-ping.js --out json=result-golang-app.json
k6 run nodejs-ping.js --out json=result-nodejs-app.json
k6 run golang-stocks.js --out json=result-golang-app-stocks.json
k6 run nodejs-stocks.js --out json=result-nodejs-app-stocks.json
k6 run golang-lambda-stocks.js --out json=result-golang-lambda-stocks.json
k6 run nodejs-lambda-stocks.js --out json=result-nodejs-lambda-stocks.json
k6 run golang-ping.js --out json=result-golang-app.json
Reports AWS