shareConnections() in Server to Server Simulation

Hi,
I’m making some investigation at shareConnections() at Gatling 3.8.4 and I’m wondering how it’s work :slight_smile:

From my tests it’s look like that shareConnections() it’s reusing connections after when some pool have 24 (baseUrl) + 1 (warmUp) HTTPS connections. It’s this true?
Can I change in any way starting value of connections in this pool to e.g. 1 or 5?
When connections in this pool changing and how?
When I do 1req/s it’s make really not nice charts:

1 Like

Hi,

it’s reusing connections after when some pool have 24 (baseUrl) + 1 (warmUp) HTTPS connections. It’s this true?

It’s not.
The connection for warmup request doesn’t goes in the pool as it’s closed, see https://github.com/gatling/gatling/blob/e6bd5c4599b319d7d26ed91db2ec43027270fb9f/gatling-http/src/main/scala/io/gatling/http/engine/HttpEngine.scala#L80.

shareConnections means you’ll be using a global connection pool for all your virtual users.
The number of connections depends on your use case. If a virtual user tries to perform a request and there’s no available connection, it will open a new one.

I can’t say anything about your case without being able to reproduce. It could be lots of different things, Gatling warming up or your application warming up.

Yes you are right warmUp doesn’t matter in connection pool, so connection pool is 24, but why ? :slight_smile:

For Scenario:

package pl.gemiusz;

import io.gatling.javaapi.core.ScenarioBuilder;
import io.gatling.javaapi.core.Simulation;
import io.gatling.javaapi.http.HttpProtocolBuilder;

import static io.gatling.javaapi.core.CoreDsl.constantUsersPerSec;
import static io.gatling.javaapi.core.CoreDsl.scenario;
import static io.gatling.javaapi.http.HttpDsl.http;

public class GeMi_FooBarSimulation extends Simulation {

    HttpProtocolBuilder httpProtocol =
            http
                    .baseUrl("https://gatling.io")
                    .shareConnections()
                    .connectionHeader("keep-alive")
                    .disableCaching()
                    .disableWarmUp();

    ScenarioBuilder scn =
            scenario("GeMi_FooBarSimulation")
                    .exec(
                            http("GeMi_FooBarSimulation_get")
                                    .get("/")
                    ).exec(session -> {
                        System.out.println("GeMi_DONE");
                        return session;
                    });

    {
        setUp(scn.injectOpen(constantUsersPerSec(1).during(30)).protocols(httpProtocol));
    }
}

when I have logger:

<logger name="io.gatling.http.client.impl.DefaultHttpClient" level="TRACE" />

I have below log:

Simulation pl.gemiusz.GeMi_FooBarSimulation started...
21:41:43.148 [DEBUG] i.g.h.c.i.DefaultHttpClient - Opening new channel
21:41:43.332 [DEBUG] i.g.h.c.i.DefaultHttpClient - Installing SslHandler for https://gatling.io/
21:41:43.395 [DEBUG] i.g.h.c.i.DefaultHttpClient - TLS handshake successful: protocol=TLSv1.3 cipher suite=TLS_AES_256_GCM_SHA384
GeMi_DONE
21:41:44.081 [DEBUG] i.g.h.c.i.DefaultHttpClient - Opening new channel
21:41:44.123 [DEBUG] i.g.h.c.i.DefaultHttpClient - Installing SslHandler for https://gatling.io/
21:41:44.169 [DEBUG] i.g.h.c.i.DefaultHttpClient - TLS handshake successful: protocol=TLSv1.3 cipher suite=TLS_AES_256_GCM_SHA384
GeMi_DONE
21:41:45.083 [DEBUG] i.g.h.c.i.DefaultHttpClient - Opening new channel
21:41:45.126 [DEBUG] i.g.h.c.i.DefaultHttpClient - Installing SslHandler for https://gatling.io/
21:41:45.170 [DEBUG] i.g.h.c.i.DefaultHttpClient - TLS handshake successful: protocol=TLSv1.3 cipher suite=TLS_AES_256_GCM_SHA384
GeMi_DONE
21:41:46.083 [DEBUG] i.g.h.c.i.DefaultHttpClient - Opening new channel
21:41:46.125 [DEBUG] i.g.h.c.i.DefaultHttpClient - Installing SslHandler for https://gatling.io/
21:41:46.168 [DEBUG] i.g.h.c.i.DefaultHttpClient - TLS handshake successful: protocol=TLSv1.3 cipher suite=TLS_AES_256_GCM_SHA384
GeMi_DONE
21:41:47.084 [DEBUG] i.g.h.c.i.DefaultHttpClient - Opening new channel
21:41:47.127 [DEBUG] i.g.h.c.i.DefaultHttpClient - Installing SslHandler for https://gatling.io/
21:41:47.171 [DEBUG] i.g.h.c.i.DefaultHttpClient - TLS handshake successful: protocol=TLSv1.3 cipher suite=TLS_AES_256_GCM_SHA384
GeMi_DONE
21:41:48.080 [DEBUG] i.g.h.c.i.DefaultHttpClient - Opening new channel
21:41:48.127 [DEBUG] i.g.h.c.i.DefaultHttpClient - Installing SslHandler for https://gatling.io/
21:41:48.174 [DEBUG] i.g.h.c.i.DefaultHttpClient - TLS handshake successful: protocol=TLSv1.3 cipher suite=TLS_AES_256_GCM_SHA384
GeMi_DONE
21:41:49.079 [DEBUG] i.g.h.c.i.DefaultHttpClient - Opening new channel
21:41:49.120 [DEBUG] i.g.h.c.i.DefaultHttpClient - Installing SslHandler for https://gatling.io/
21:41:49.165 [DEBUG] i.g.h.c.i.DefaultHttpClient - TLS handshake successful: protocol=TLSv1.3 cipher suite=TLS_AES_256_GCM_SHA384
GeMi_DONE
21:41:50.078 [DEBUG] i.g.h.c.i.DefaultHttpClient - Opening new channel
21:41:50.119 [DEBUG] i.g.h.c.i.DefaultHttpClient - Installing SslHandler for https://gatling.io/
21:41:50.164 [DEBUG] i.g.h.c.i.DefaultHttpClient - TLS handshake successful: protocol=TLSv1.3 cipher suite=TLS_AES_256_GCM_SHA384
GeMi_DONE
21:41:51.079 [DEBUG] i.g.h.c.i.DefaultHttpClient - Opening new channel
21:41:51.122 [DEBUG] i.g.h.c.i.DefaultHttpClient - Installing SslHandler for https://gatling.io/
21:41:51.168 [DEBUG] i.g.h.c.i.DefaultHttpClient - TLS handshake successful: protocol=TLSv1.3 cipher suite=TLS_AES_256_GCM_SHA384
GeMi_DONE
21:41:52.077 [DEBUG] i.g.h.c.i.DefaultHttpClient - Opening new channel
21:41:52.120 [DEBUG] i.g.h.c.i.DefaultHttpClient - Installing SslHandler for https://gatling.io/
21:41:52.166 [DEBUG] i.g.h.c.i.DefaultHttpClient - TLS handshake successful: protocol=TLSv1.3 cipher suite=TLS_AES_256_GCM_SHA384
GeMi_DONE
21:41:53.074 [DEBUG] i.g.h.c.i.DefaultHttpClient - Opening new channel
21:41:53.117 [DEBUG] i.g.h.c.i.DefaultHttpClient - Installing SslHandler for https://gatling.io/
21:41:53.163 [DEBUG] i.g.h.c.i.DefaultHttpClient - TLS handshake successful: protocol=TLSv1.3 cipher suite=TLS_AES_256_GCM_SHA384
GeMi_DONE
21:41:54.073 [DEBUG] i.g.h.c.i.DefaultHttpClient - Opening new channel
21:41:54.115 [DEBUG] i.g.h.c.i.DefaultHttpClient - Installing SslHandler for https://gatling.io/
21:41:54.156 [DEBUG] i.g.h.c.i.DefaultHttpClient - TLS handshake successful: protocol=TLSv1.3 cipher suite=TLS_AES_256_GCM_SHA384
GeMi_DONE
21:41:55.091 [DEBUG] i.g.h.c.i.DefaultHttpClient - Opening new channel
21:41:55.169 [DEBUG] i.g.h.c.i.DefaultHttpClient - Installing SslHandler for https://gatling.io/
21:41:55.240 [DEBUG] i.g.h.c.i.DefaultHttpClient - TLS handshake successful: protocol=TLSv1.3 cipher suite=TLS_AES_256_GCM_SHA384
GeMi_DONE
21:41:56.074 [DEBUG] i.g.h.c.i.DefaultHttpClient - Opening new channel
21:41:56.116 [DEBUG] i.g.h.c.i.DefaultHttpClient - Installing SslHandler for https://gatling.io/
21:41:56.162 [DEBUG] i.g.h.c.i.DefaultHttpClient - TLS handshake successful: protocol=TLSv1.3 cipher suite=TLS_AES_256_GCM_SHA384
GeMi_DONE
21:41:57.091 [DEBUG] i.g.h.c.i.DefaultHttpClient - Opening new channel
21:41:57.134 [DEBUG] i.g.h.c.i.DefaultHttpClient - Installing SslHandler for https://gatling.io/
21:41:57.174 [DEBUG] i.g.h.c.i.DefaultHttpClient - TLS handshake successful: protocol=TLSv1.3 cipher suite=TLS_AES_256_GCM_SHA384
GeMi_DONE
21:41:58.086 [DEBUG] i.g.h.c.i.DefaultHttpClient - Opening new channel
21:41:58.130 [DEBUG] i.g.h.c.i.DefaultHttpClient - Installing SslHandler for https://gatling.io/
21:41:58.173 [DEBUG] i.g.h.c.i.DefaultHttpClient - TLS handshake successful: protocol=TLSv1.3 cipher suite=TLS_AES_256_GCM_SHA384
GeMi_DONE
21:41:59.074 [DEBUG] i.g.h.c.i.DefaultHttpClient - Opening new channel
21:41:59.116 [DEBUG] i.g.h.c.i.DefaultHttpClient - Installing SslHandler for https://gatling.io/
21:41:59.161 [DEBUG] i.g.h.c.i.DefaultHttpClient - TLS handshake successful: protocol=TLSv1.3 cipher suite=TLS_AES_256_GCM_SHA384
GeMi_DONE
21:42:00.075 [DEBUG] i.g.h.c.i.DefaultHttpClient - Opening new channel
21:42:00.118 [DEBUG] i.g.h.c.i.DefaultHttpClient - Installing SslHandler for https://gatling.io/
21:42:00.164 [DEBUG] i.g.h.c.i.DefaultHttpClient - TLS handshake successful: protocol=TLSv1.3 cipher suite=TLS_AES_256_GCM_SHA384
GeMi_DONE
21:42:01.082 [DEBUG] i.g.h.c.i.DefaultHttpClient - Opening new channel
21:42:01.126 [DEBUG] i.g.h.c.i.DefaultHttpClient - Installing SslHandler for https://gatling.io/
21:42:01.171 [DEBUG] i.g.h.c.i.DefaultHttpClient - TLS handshake successful: protocol=TLSv1.3 cipher suite=TLS_AES_256_GCM_SHA384
GeMi_DONE
21:42:02.076 [DEBUG] i.g.h.c.i.DefaultHttpClient - Opening new channel
21:42:02.118 [DEBUG] i.g.h.c.i.DefaultHttpClient - Installing SslHandler for https://gatling.io/
21:42:02.162 [DEBUG] i.g.h.c.i.DefaultHttpClient - TLS handshake successful: protocol=TLSv1.3 cipher suite=TLS_AES_256_GCM_SHA384
GeMi_DONE
21:42:03.072 [DEBUG] i.g.h.c.i.DefaultHttpClient - Opening new channel
21:42:03.115 [DEBUG] i.g.h.c.i.DefaultHttpClient - Installing SslHandler for https://gatling.io/
21:42:03.159 [DEBUG] i.g.h.c.i.DefaultHttpClient - TLS handshake successful: protocol=TLSv1.3 cipher suite=TLS_AES_256_GCM_SHA384
GeMi_DONE
21:42:04.085 [DEBUG] i.g.h.c.i.DefaultHttpClient - Opening new channel
21:42:04.127 [DEBUG] i.g.h.c.i.DefaultHttpClient - Installing SslHandler for https://gatling.io/
21:42:04.173 [DEBUG] i.g.h.c.i.DefaultHttpClient - TLS handshake successful: protocol=TLSv1.3 cipher suite=TLS_AES_256_GCM_SHA384
GeMi_DONE
21:42:05.083 [DEBUG] i.g.h.c.i.DefaultHttpClient - Opening new channel
21:42:05.128 [DEBUG] i.g.h.c.i.DefaultHttpClient - Installing SslHandler for https://gatling.io/
21:42:05.172 [DEBUG] i.g.h.c.i.DefaultHttpClient - TLS handshake successful: protocol=TLSv1.3 cipher suite=TLS_AES_256_GCM_SHA384
GeMi_DONE
21:42:06.080 [DEBUG] i.g.h.c.i.DefaultHttpClient - Opening new channel
21:42:06.124 [DEBUG] i.g.h.c.i.DefaultHttpClient - Installing SslHandler for https://gatling.io/
21:42:06.168 [DEBUG] i.g.h.c.i.DefaultHttpClient - TLS handshake successful: protocol=TLSv1.3 cipher suite=TLS_AES_256_GCM_SHA384
GeMi_DONE
GeMi_DONE
GeMi_DONE
GeMi_DONE
GeMi_DONE
GeMi_DONE
GeMi_DONE
Simulation pl.gemiusz.GeMi_FooBarSimulation completed in 29 seconds

I make tests on https://postman-echo.com and Wiremock (locally) and always I have 24 Opening new channel - when I have warm Up a one additional appear.
Of corse when at beginning is more UsersPerSecond or endpoint don’t response enought fast there can be more Opening new channel.

Questions are:

  • why always is this 24?
  • it is possible to change this?
  • how this pool is working?

My Setup details:
OS: Windows 10 Pro (21H2)
JDK: java 17.0.4 2022-07-19 LTS
Gatling: 3.8.4 (MVN gatling-charts-highcharts)

Questions are:

why always is this 24?

Gatling’s connection pool is actually 1 connection pool per eventloop. There are by default 2 eventloops per core. Virtual users are distributed over the evenloops with a round robin strategy.
It seems you have 12 cores (which is a surprising number).

it is possible to change this?

no

My CPU have 6 cores and 12 threads :slight_smile:

As I remember there is possibility to reduce number of Cores that JVM can use, and I found documentation for that:

-XX:ActiveProcessorCount=x
Overrides the number of CPUs that the VM will use to calculate the size of thread pools it will use for various operations such as Garbage Collection and ForkJoinPool.

The VM normally determines the number of available processors from the operating system. This flag can be useful for partitioning CPU resources when running multiple Java processes in docker containers. This flag is honored even if UseContainerSupport is not enabled. See -XX:-UseContainerSupport for a description of enabling and disabling container support.

So after use of this parameter with value 1 I got only 2 Opening new channel

I wondering if it’s possible to Override number of eventloops, are they managed by Netty?

Additionally will be nice if there will be something like warmUp that prepare active HTTPS connections as many eventloops when is used option shareConnections(), what do you think? :slight_smile:

What’s your goal here?
It looks like you’re focused on the first virtual users at a very low injection rate, which can hardly be called a load test.

I want to understand how its working and how its affect very specific case - performance of application when load is very rare, one request every X seconds/minutes during X minutes/hours.
In this case Servers can have specific number of connections and they are keep-alive them for seconds/minutes.

I am investigating whether this type of test makes sense and how to do it with Gatling.
In all presentations about performance testing it is omitted but in my opinion it should be shown because it is very important test in some cases.

Example of Injection profile:

        setUp(scn.injectOpen(Stream.of(
                                Stream.generate(
                                        () -> new OpenInjectionStep[]{
                                                atOnceUsers(1),
                                                nothingFor(Duration.ofSeconds(15))
                                        }
                                ).limit(4).flatMap(Stream::of),
                                Stream.generate(
                                        () -> new OpenInjectionStep[]{
                                                atOnceUsers(1),
                                                nothingFor(Duration.ofSeconds(10))
                                        }
                                ).limit(6).flatMap(Stream::of),
                                Stream.generate(
                                        () -> new OpenInjectionStep[]{
                                                atOnceUsers(1),
                                                nothingFor(Duration.ofSeconds(5))
                                        }
                                ).limit(12).flatMap(Stream::of)
                        ).flatMap(i -> i).toArray(OpenInjectionStep[]::new)
                )
                .protocols(httpProtocol));