artilleryio / artillery

The complete load testing platform. Everything you need for production-grade load tests. Serverless & distributed. Load test with Playwright. Load test HTTP APIs, GraphQL, WebSocket, and more. Use any Node.js module.
https://www.artillery.io
Mozilla Public License 2.0
8.03k stars 510 forks source link

Parallel requests not working #1436

Open Thibobbs opened 2 years ago

Thibobbs commented 2 years ago

Hello,

I'm trying to make parallel requests with artillery and I saw that this feature is supposed to be supported (not in the doc though). Unfortunately, it doesn't seem to do anything different than normal request behaviour.

Version info:

Artillery Core: 2.0.0-15
Artillery Pro:  not installed (https://artillery.io/product)

Node.js: v14.18.3
OS:      linux

This is my yml file :

config:
  target: "xxx"
  http:
    timeout: 360
  variables:
    token: "xxx"

scenarios:
  - flow:
      - parallel:
          - get:
              headers:
                Authorization: "Bearer {{ token }}"
              url: "/api/xxx1"
          - get:
              headers:
                Authorization: "Bearer {{ token }}"
              url: "/api/xxx2"
          - get:
              headers:
                Authorization: "Bearer {{ token }}"
              url: "/api/xxx3"
          - get:
              headers:
                Authorization: "Bearer {{ token }}"
              url: "/api/xxx4"

I was expecting to have a vusers.session_length similar to the max http.response_time. But here are the logs :

All VUs finished. Total time: 11 seconds

--------------------------------
Summary report @ 16:54:16(+0200)
--------------------------------

http.codes.200: ................................................................ 4
http.request_rate: ............................................................. 1/sec
http.requests: ................................................................. 4
http.response_time:
  min: ......................................................................... 2142
  max: ......................................................................... 2478
  median: ...................................................................... 2276.1
  p95: ......................................................................... 2276.1
  p99: ......................................................................... 2276.1
http.responses: ................................................................ 4
vusers.completed: .............................................................. 1
vusers.created: ................................................................ 1
vusers.created_by_name.0: ...................................................... 1
vusers.failed: ................................................................. 0
vusers.session_length:
  min: ......................................................................... 9337.7
  max: ......................................................................... 9337.7
  median: ...................................................................... 9416.8
  p95: ......................................................................... 9416.8
  p99: ......................................................................... 9416.8

As you can see, artillery seems to trigger the requests sequencially instead of being parallelized. There is little to no difference when I remove "parallel" from the flow.

Thank you in advance.

kevcube commented 2 years ago

@Thibobbs

I was expecting to have a vusers.session_length similar to the max http.response_time

Note that http.response_time is TTFB, and vusers.session_length is TTLB. Other than that, I'm hoping parallel is working as intended.

moarteavietii commented 2 years ago

Could it be because of the maxSockets param? https://www.artillery.io/docs/guides/guides/http-reference#max-sockets-per-virtual-user

kevin-lonestone commented 3 months ago

I just encountered the same behavior with parallel get requests executed sequentially.

Here are the lines that cause this behavior: https://github.com/artilleryio/artillery/blob/d77b7a298a9723641ae655afb5566489f3f4635a/packages/core/lib/engine_http.js#L908-L912

To work around this issue locally

  1. add a beforeScenario custom script

    [...]
    beforeScenario:
      - "setMaxSocketCount"
  2. the setMaxSocketCount script:

    export async function setMaxSocketCount(context, eventEmitter) {
    /**
    * @type {http.Agent} httpAgent
    */
    const httpAgent = context._httpAgent
    httpAgent.maxSockets = 10
    httpAgent.maxFreeSockets = 10
    /**
    * @type {https.Agent} httpsAgent
    */
    const httpsAgent = context._httpsAgent
    httpsAgent.maxSockets = 10
    httpsAgent.maxFreeSockets = 10
    }

In conclusion

Maybe some kind of PR would solve this issue:

    const agentOpts = Object.assign(DEFAULT_AGENT_OPTIONS, {
      maxSockets: this.config.http && this.config.http.maxSockets ? this.config.http.maxSockets : 1,
      maxFreeSockets: this.config.http && this.config.http.maxSockets ? this.config.http.maxSockets : 1,
    });