Skip to main content

HTTP

To work with HTTP, NBomber provides NBomber.Http plugin that includes:

  • API to create, send request, receive response with tracking of data transfer and status codes.
  • HttpMetricsPlugin to get real-time metrics about the current Http connections.
info

To start working with NBomber.Http plugin you should install it:

dotnet add package NBomber.Http

Http CreateRequest

This method should be used to create HTTP request.

public static HttpRequestMessage CreateRequest(string method, string url)

Example:

var scenario = Scenario.Create("my scenario", async context =>
{
var request = Http.CreateRequest("GET", "https://nbomber.com")
.WithHeader("Accept", "text/html");
// .WithHeader("Accept", "application/json")
// .WithBody(new StringContent("{ id: 1 }", Encoding.UTF8, "application/json");
// .WithBody(new ByteArrayContent(new [] {1,2,3}))
...
});

Http Send

This method should be used to send HTTP request.

public static Task<Response<HttpResponseMesage>> Send(HttpClient client, HttpRequestMessage request);

public static Task<Response<HttpResponseMesage>> Send(HttpClient client, HttpClientArgs clientArgs, HttpRequestMessage request);

Example 1:

using var httpClient = new HttpClient();

var scenario = Scenario.Create("my scenario", async context =>
{
var request = Http.CreateRequest("GET", "https://nbomber.com")
.WithHeader("Accept", "text/html");
// .WithHeader("Accept", "application/json")
// .WithBody(new StringContent("{ id: 1 }", Encoding.UTF8, "application/json");
// .WithBody(new ByteArrayContent(new [] {1,2,3}))

var response = await Http.Send(httpClient, request);

return response;
});

Example 2: in this example we use HttpClientArgs

using var httpClient = new HttpClient();

var scenario = Scenario.Create("my scenario", async context =>
{
var request = Http.CreateRequest("GET", "https://nbomber.com")
.WithHeader("Accept", "application/json");
// .WithHeader("Accept", "application/json")
// .WithBody(new StringContent("{ id: 1 }", Encoding.UTF8, "application/json");
// .WithBody(new ByteArrayContent(new [] {1,2,3}))

// with HttpClientArgs you can add:
// -- CancellationToken
// -- HttpCompletionOption - https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpcompletionoption?view=net-7.0

var clientArgs = new HttpClientArgs(HttpCompletionOption.ResponseHeadersRead, CancellationToken.None);

var response = await Http.Send(httpClient, clientArgs, request);

return response;
});

HttpMetricsPlugin

HttpMetricsPlugin - provides a monitoring layer for HTTP connections.

Example:

NBomberRunner
.RegisterScenarios(scenario)
.WithWorkerPlugins(new HttpMetricsPlugin(new [] { HttpVersion.Version1 }))
// .WithWorkerPlugins(new HttpMetricsPlugin(new [] { HttpVersion.Version1, HttpVersion.Version2 }))
.Run();

After running with HttpMetricsPlugin, you will get real-time HTTP connections metrics for the Console output:

Also, after running with HttpMetricsPlugin, you will get HTTP connections history metrics for the HTML report:

Connections limit

You may need to limit the sockets connections count.

var socketsHandler = new SocketsHttpHandler
{
MaxConnectionsPerServer = 3
};

using var httpClient = new HttpClient(socketsHandler);

Best practices

Blog posts

Load simulation

HTTP services should be considered as Open system. Open systems - it's where you control the arrival rate of users. For Open systems NBomber provides the following load simulations: Inject, RampingInject and InjectRandom.

HttpClient

HttpClient should be used carefully since the wrong use of it can cause socket exhaustion problems. You can read more about this problem in this article: You are using HttpClient wrong. The basic recommendations are:

  • Use a singleton HttpClient (shared instance) per Scenario.
  • Do not create many HttpClient instances. Instead just reuse a single instance per Scenario.
  • Disposing HttpClient is not a cheap operation. It can cause socket exhaustion problems.
// this usage is WRONG
// since HttpClient will be created and disposed for each Scenario iteration

var scenario = Scenario.Create("my scenario", async context =>
{
using var httpClient = new HttpClient();

var request = Http.CreateRequest("GET", "https://nbomber.com")
var response = await Http.Send(httpClient, request);

...
});
// this usage is OK
// since HttpClient will be created once and then reused for each Scenario iteration

using var httpClient = new HttpClient();

var scenario = Scenario.Create("my scenario", async context =>
{
var request = Http.CreateRequest("GET", "https://nbomber.com")
var response = await Http.Send(httpClient, request);

...
});