Node js server and Apache ab tool: unexpected behavior - node.js

While testing a simple node server (written with Hapi.js):
'use strict';
var Hapi = require("hapi");
var count = 0;
const server = Hapi.server({
port: 3000,
host: 'localhost'
});
server.route({
method: 'GET',
path: '/test',
handler: (request, h) => {
count ++;
console.log(count);
return count;
}
});
const init = async () => {
await server.start();
};
process.on('unhandledRejection', (err) => {
process.exit(1);
});
init();
start the server:
node ./server.js
run the Apache ab tool:
/usr/bin/ab -n 200 -c 30 localhost:3000/test
Env details:
OS: CentOS release 6.9
Node: v10.14.1
Hapi.js: 17.8.1
I found unexpected results in case of multiple concurrent requests (-c 30): the request handler function has been called more times than the number of requests to be performed (-n 200).
Ab output example:
Benchmarking localhost (be patient)
Server Software:
Server Hostname: localhost
Server Port: 3000
Document Path: /test
Document Length: 29 bytes
Concurrency Level: 30
Time taken for tests: 0.137 seconds
Complete requests: 200
Failed requests: 0
Write errors: 0
Total transferred: 36081 bytes
HTML transferred: 6119 bytes
Requests per second: 1459.44 [#/sec] (mean)
Time per request: 20.556 [ms] (mean)
Time per request: 0.685 [ms] (mean, across all concurrent requests)
Transfer rate: 257.12 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 0 0.1 0 0
Processing: 15 17 1.5 16 20
Waiting: 2 9 3.9 9 18
Total: 15 17 1.5 16 21
Percentage of the requests served within a certain time (ms)
50% 16
66% 16
75% 17
80% 18
90% 20
95% 20
98% 21
99% 21
100% 21 (longest request)
And the node server print out 211 log lines. During various tests the mismatch is variable but always present:
-n 1000 -c 1 -> 1000 log
-n 1000 -c 2 -> ~1000 logs
-n 1000 -c 10 -> ~1001 logs
-n 1000 -c 70 -> ~1008 logs
-n 1000 -c 1000 -> ~1020 logs
It seems that as concurrency increases, the mismatch increases.
I couldn't figure out whether the ab tool performs more http requests or the node server responds more times than necessary.
Could you please help?

Its very strange and I don't get the same results as you on my machine. I would be very surprised if it was ab that was issuing different numbers of actual requests.
Things i would try:
Write a simple server using express rather than hapi. If the issue still occurs you at least know its not a problem with hapi.
Intercept the network calls using fiddler
ab -X localhost:8888 -n 100 -c 30 http://127.0.0.1:3000/test will use the fiddler proxy which will then let you see the actual calls across the network interface. more details
wireshark if you need more power and your feeling brave (I'd only use it if fiddler has let you down)
If after all these you are still finding an issue then it has been narrowed down to an issue with node, I'm not sure what else it could be. Try using node 8 rather than 10.

Using the Fiddler proxy I found that AB tool runs more times than the number of requests to be performed (example: -n 200).
By running a series of consecutive tests:
# 11 consecutive times
/usr/bin/ab -n 200 -c 30 -X localhost:8888 http://localhost:3000/test
Both the proxy and the node server report a total of 2209 requests. It looks like that AB is less imprecise with the proxy in the middle, but still imprecise.
In general, and more important, I never found mismatches between the requests passed through the proxy and the requests received by the node server.
Thanks!

Related

Problems configuring LivyOperator in Airflow

For LivyOperator we set the following parameters:
polling_interval=60
retries_num_timeout=100
We set it up according to this documentation: https://airflow.apache.org/docs/apache-airflow-providers-apache-livy/stable/_api/airflow/providers/apache/livy/operators/livy/index.html
But, in this configuration after 100 * 60 seconds = 6000 seconds = 1 hour 40 minutes Livy-session is interrupted, operator becomes failed, loading is interrupted. Is there any way to resove such inconsistency on Airflow/Livy side?

Does the httperf tool send all requests within a second even if the request rate/connection rate is way lower in the response?

Running the following httperf command, wanting to hit the API 500 times with a rate of 500 requests per second.
./httperf --server <server IP> --port <server port> --uri <api uri> --num-conns 500 --rate 500 --ssl --add-header "<cookie values>"
The response is taking longer than a second to complete, more like 60 seconds, with a request rate/connection rate of around 8.2 req/s.
Output below:
Total: connections 500 requests 500 replies 500 test-duration 61.102 s
Connection rate: 8.2 conn/s (122.2 ms/conn, <=500 concurrent connections)
Connection time [ms]: min 60011.9 avg 60523.1 max 61029.1 median 60526.5 stddev 290.7
Connection time [ms]: connect 8.1
Connection length [replies/conn]: 1.000
Request rate: 8.2 req/s (122.2 ms/req)
Request size [B]: 3106.0
Reply rate [replies/s]: min 0.0 avg 0.0 max 0.0 stddev 0.0 (12 samples)
Reply time [ms]: response 4.3 transfer 60510.6
Reply size [B]: header 178.0 content 12910.0 footer 2.0 (total 13090.0)
Reply status: 1xx=0 2xx=500 3xx=0 4xx=0 5xx=0
CPU time [s]: user 28.27 system 32.59 (user 46.3% system 53.3% total 99.6%)
Net I/O: 129.4 KB/s (1.1*10^6 bps)
Errors: total 0 client-timo 0 socket-timo 0 connrefused 0 connreset 0
Errors: fd-unavail 0 addrunavail 0 ftab-full 0 other 0
So does this mean that the requests are really only getting sent at around 8 per second, or are they technically send to the server, but the server is queing them up.

rampUser method is getting stuck in gatling 3.3

I am having issues using rampUser() method in my gatling script. The request is getting stuck after the following entry which had passed half way through.
Version : 3.3
================================================================================
2019-12-18 09:51:44 45s elapsed
---- Requests ------------------------------------------------------------------
> Global (OK=2 KO=0 )
> graphql / request_0 (OK=1 KO=0 )
> rest / request_0 (OK=1 KO=0 )
---- xxxSimulation ---------------------------------------------------
[##################################### ] 50%
waiting: 1 / active: 0 / done: 1
================================================================================
I am seeing the following in the log which gets repeated for ever and the log size increases
09:35:46.495 [GatlingSystem-akka.actor.default-dispatcher-2] DEBUG io.gatling.core.controller.inject.open.OpenWorkload - Injecting 0 users in scenario xxSimulation, continue=true
09:35:47.494 [GatlingSystem-akka.actor.default-dispatcher-6] DEBUG io.gatling.core.controller.inject.open.OpenWorkload - Injecting 0 users in scenario xxSimulation, continue=true
The above issue is happening only with rampUser and not happening with
atOnceUsers()
rampUsersPerSec()
rampConcurrentUsers()
constantConcurrentUsers()
constantUsersPerSec()
incrementUsersPerSec()
Is there a way to mimic rampUser() in some other way or is there a solution for this.
My code is very minimal
setUp(
scenarioBuilder.inject(
rampUsers(2).during(1 minutes)
)
).protocols(protocolBuilder)
I am stuck with this for some time and my earlier post with more information can be found here
Can any of the gatling experts help me on this?
Thanks for looking into it.
It seems you have slightly incorrect syntax for a rampUsers. You should try remove a . before during.
I have in my own script this code and it works fine:
setUp(userScenario.inject(
// atOnceUsers(4),
rampUsers(24) during (1 seconds))
).protocols(httpProtocol)
Also, in Gatling documentation example is also without a dot Open model:
scn.inject(
nothingFor(4 seconds), // 1
atOnceUsers(10), // 2
rampUsers(10) during (5 seconds), // HERE
constantUsersPerSec(20) during (15 seconds), // 4
constantUsersPerSec(20) during (15 seconds) randomized, // 5
rampUsersPerSec(10) to 20 during (10 minutes), // 6
rampUsersPerSec(10) to 20 during (10 minutes) randomized, // 7
heavisideUsers(1000) during (20 seconds) // 8
).protocols(httpProtocol)
)
My guess is that syntax can't be parsed, so instead 0 is substituted. (Here is example of rounding. Not applicable, but as reference: gatling-user-injection-constantuserspersec)
Also, you mentioned that others method work, could you paste working code as well?

gearman jobs after running for some time, request will timeout

Use a gearman server, registered a function 'stop_xxxxx', then do fatigue testing (cycle request 1000000 times).
At first, the response speed is normal, but by about 1000 times Request timed out.
I'm using gearman 1.1.12 and gearman-python
When timeouts are, gearman server logs are:
DEBUG 2014-07-09 02:26:34.899149 [proc] Received submission, function: A_stop_xxxxxxxx unique: 98588d0149f0a2deb32919e36e395a8a with 2 arguments -> libgearman-server/server.cc: 248
   DEBUG 2014-07-09 02:26:34.899166 [proc] Comparing queue 1 to limit 0 for priority 1 -> libgearman-server/job.cc: 175
   DEBUG 2014-07-09 02:26:34.899281 [proc] JOB H: orainxiong-vm: 1734: 2878034076 -> libgearman-server/job.cc: 240
   DEBUG 2014-07-09 02:26:34.899542 [12] Received RUN wakeup event -> libgearman-server/gearmand_thread.cc: 624
  NOTICE 2014-07-09 02:26:34.899573 [proc] accepted, A_stop_one_perf_collect, 98588d0149f0a2deb32919e36e395a8a, 0 -> libgearman-server/server.cc: 317
   DEBUG 2014-07-09 02:26:34.899631 [12] send () 32 bytes to peer -> libgearman-server/io.cc: 403
   DEBUG 2014-07-09 02:26:34.899646 [12] Sent JOB_CREATED -> libgearman-server/thread.cc: 356
**no more output**
Did not seem to send the request to the worker, how to locate the problem?
My boot parameters are:
gearmand - job-retries = 3 - worker-wakeup = 1 - round-robin - verbose DEBUG - queue-type = MySQL - mysql-host = 127.0.0.1 - mysql-port = 3306 - mysql -user = xxx - mysql-password = xxx - mysql-db = xxxx - mysql-table = job_queue-p 4371-t 16-lstderr

Analysis of nodeload result

Can anyone explain me the nodeload result below.
./nl.js -c 1 -n 10000 -i 1 "http://localhost:3000/
Server: localhost:3000
HTTP Method: GET
Document Path: /
Concurrency Level: 1
Number of requests: 10000
Body bytes transferred: 3516274
Elapsed time (s): 1172.70
Requests per second: 9.23
Mean time per request (ms): 107.95
Time per request standard deviation: 187.76
Percentages of requests served within a certain time (ms)
Min: 38
Avg: 107.9
50%: 84
95%: 141
99%: 1076
Max: 5820
How is the percentage of requests calculated?
Thanks

Resources