Test prędkości HTTP dla usług SMS REST

Potrzebujesz zmierzyć wydajność swojej usługi SMS opartej na HTTP? Test prędkości HTTP dla usług SMS REST to potężne narzędzie zaprojektowane do oceny szybkości i niezawodności Twoich punktów końcowych API JSON/REST. To narzędzie do pobrania pozwala symulować wysokoobjętościowe żądania SMS, śledzić wskaźniki sukcesu i obliczać żądania na sekundę, pomagając zoptymalizować wydajność serwera pod obciążeniem. Niezależnie od tego, czy przeprowadzasz testy obciążeniowe w lokalnym środowisku developerskim, czy benchmarkujesz produkcyjną bramkę SMS, to narzędzie dostarcza jasnych metryk dotyczących całkowitej liczby żądań, równoczesnych połączeń i efektywności HTTP Keep-Alive. Pobierz gotowe rozwiązanie w C# lub zintegruj dostarczony kod źródłowy do swojego przepływu testowego, aby przeprowadzić precyzyjną analizę wydajności API.

Pobierz

HttpSpeedTest.zip

Przykład użycia

Rysunek 1 - Jak używać narzędzia do testowania prędkości

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Net.Http;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;

class Program
{
    static readonly Random random = new Random();
    static readonly string[] sampleMessages = {
        "Witaj, to jest wiadomość testowa.",
        "Testowanie wydajności możliwości serwera HTTP.",
        "Pomiar liczby żądań na sekundę dla interfejsu API JSON.",
        "Losowa treść wiadomości do testów obciążeniowych.",
        "Kolejna wiadomość testowa z inną treścią.",
        "Sprawdzanie pojemności serwera pod obciążeniem.",
        "Ile żądań może obsłużyć serwer?",
        "Testowanie obciążeniowe punktu końcowego API SMS.",
        "Ta wiadomość jest generowana automatycznie.",
        "Ostatnia wiadomość testowa w zestawie próbek."
    };

    static async Task Main(string[] args)
    {
        Console.WriteLine("Tester wydajności interfejsu API JSON serwera HTTP");
        Console.WriteLine("---------------------------------------");

        if (args.Length < 3)
        {
            Console.WriteLine("Użycie: Program    [useKeepAlive]");
            Console.WriteLine("Przykład: Program http://198.50.122.178:8080 1000 50 true");
            Console.WriteLine("Przykład: Program https://api.example.com/sms 5000 100 false");
            Console.WriteLine("Przykład: Program http://localhost/innotest/innotest.php 50 10 false");
        
            return;
        }

        string baseUrl = args[0];
        if (!Uri.TryCreate(baseUrl, UriKind.Absolute, out Uri uriResult) ||
            (uriResult.Scheme != Uri.UriSchemeHttp && uriResult.Scheme != Uri.UriSchemeHttps))
        {
            Console.WriteLine("Nieprawidłowy adres URL. Musi to być prawidłowy adres HTTP lub HTTPS.");
            return;
        }

        if (!int.TryParse(args[1], out int totalRequests) || totalRequests <= 0)
        {
            Console.WriteLine("Nieprawidłowa wartość totalRequests. Musi to być dodatnia liczba całkowita.");
            return;
        }

        if (!int.TryParse(args[2], out int concurrentRequests) || concurrentRequests <= 0)
        {
            Console.WriteLine("Nieprawidłowa wartość concurrentRequests. Musi to być dodatnia liczba całkowita.");
            return;
        }

        bool useKeepAlive = args.Length > 3 && bool.TryParse(args[3], out bool keepAlive) && keepAlive;

        Console.WriteLine($"Parametry testu:");
        Console.WriteLine($"- Bazowy URL: {baseUrl}");
        Console.WriteLine($"- Łączna liczba żądań: {totalRequests}");
        Console.WriteLine($"- Współbieżne żądania: {concurrentRequests}");
        Console.WriteLine($"- HTTP Keep-Alive: {(useKeepAlive ? "Włączone" : "Wyłączone")}");
        Console.WriteLine();

        var httpClientHandler = new HttpClientHandler
        {
            UseProxy = false,
            MaxConnectionsPerServer = concurrentRequests
        };

        var httpClient = new HttpClient(httpClientHandler)
        {
            Timeout = TimeSpan.FromSeconds(30),
            BaseAddress = new Uri(baseUrl)
        };

        if (useKeepAlive)
        {
            httpClient.DefaultRequestHeaders.ConnectionClose = false;
            httpClient.DefaultRequestHeaders.Connection.Add("keep-alive");
        }
        else
        {
            httpClient.DefaultRequestHeaders.ConnectionClose = true;
        }

        httpClient.DefaultRequestHeaders.UserAgent.ParseAdd(
         "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 "+
         "(KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36");
        httpClient.DefaultRequestHeaders.Accept.ParseAdd("application/json");

        var stopwatch = Stopwatch.StartNew();
        var tasks = new List(concurrentRequests);
        var completedRequests = 0;
        var successfulRequests = 0;
        var failedRequests = 0;

        Console.WriteLine("Rozpoczynanie testu...");

        var semaphore = new System.Threading.SemaphoreSlim(concurrentRequests, concurrentRequests);
        var jsonOptions = new JsonSerializerOptions
        {
            PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
            WriteIndented = false
        };

        for (int i = 0; i < totalRequests; i++)
        {
            await semaphore.WaitAsync();

            tasks.Add(Task.Run(async () =>
            {
                try
                {
                    var requestData = new
                    {
                        sender = "+0000000",
                        gsm = GenerateRandomPhoneNumber(),
                        text = GetRandomMessage(),
                        usrClient = "Pruebas",
                        pasClient = "Pruebas"
                    };

                    var json = JsonSerializer.Serialize(requestData, jsonOptions);
                    var content = new StringContent(json, Encoding.UTF8, "application/json");

                    var response = await httpClient.PostAsync(baseUrl, content);

                    System.Threading.Interlocked.Increment(ref completedRequests);

                    if (response.IsSuccessStatusCode)
                    {
                        System.Threading.Interlocked.Increment(ref successfulRequests);
                    }
                    else
                    {
                        System.Threading.Interlocked.Increment(ref failedRequests);
                        Console.WriteLine($"Żądanie nie powiodło się z statusem: {response.StatusCode}");
                    }
                }
                catch (Exception ex)
                {
                    System.Threading.Interlocked.Increment(ref completedRequests);
                    System.Threading.Interlocked.Increment(ref failedRequests);
                    Console.WriteLine($"Żądanie nie powiodło się: {ex.Message}");
                }
                finally
                {
                    semaphore.Release();
                }
            }));
        }

        await Task.WhenAll(tasks);
        stopwatch.Stop();

        Console.WriteLine("\nTest zakończony!");
        Console.WriteLine($"Całkowity czas: {stopwatch.Elapsed.TotalSeconds:F2} sekund");
        Console.WriteLine($"Zakończone żądania: {completedRequests}");
        Console.WriteLine($"Udane żądania: {successfulRequests}");
        Console.WriteLine($"Nieudane żądania: {failedRequests}");
        Console.WriteLine($"Żądania na sekundę: {totalRequests / stopwatch.Elapsed.TotalSeconds:F2}");
    }

    static string GenerateRandomPhoneNumber()
    {
        return $"+{random.Next(100, 999)}{random.Next(1000000, 9999999)}";
    }

    static string GetRandomMessage()
    {
        return sampleMessages[random.Next(sampleMessages.Length)];
    }
}

Wyjaśnienie kodu

1. Przegląd

Ta aplikacja konsolowa w języku C# testuje obciążenie punktu końcowego HTTP(S) SMS API, wysyłając równoległe żądania JSON i mierząc metryki wydajności, takie jak:

  • Żądania na sekundę (RPS)
  • Wskaźniki sukcesu/porażki
  • Całkowity czas wykonania

2. Kluczowe komponenty

A. Konfiguracja i ustawienia

Generowanie losowych danych:

  • sampleMessages: Predefiniowany zestaw przykładowych wiadomości SMS do realistycznego testowania.
  • GenerateRandomPhoneNumber(): Tworzy losowe numery telefonów (np. +1234567890).
  • GetRandomMessage(): Wybiera losową wiadomość z sampleMessages.

Argumenty wiersza poleceń:

Program <baseUrl> <totalRequests> <concurrentRequests> [useKeepAlive]
  • Weryfikuje dane wejściowe (format URL, dodatnie liczby całkowite dla liczby żądań).
  • Konfiguruje ustawienia klienta HTTP (limit czasu, keep-alive, user-agent).

B. Konfiguracja klienta HTTP

Dostosowanie HttpClient:

  • MaxConnectionsPerServer: Ogranicza równoległe połączenia do serwera.
  • ConnectionClose/keep-alive: Przełącza trwałe połączenia HTTP.
  • Limit czasu: 30 sekund na żądanie.
  • Nagłówki: Ustawia User-Agent i Accept: application/json.

C. Wykonanie testu obciążenia

Kontrola współbieżności:

  • Używa SemaphoreSlim do ograniczania równoległych żądań (np. 50 na raz).
  • Async/await (Task.Run) dla operacji I/O bez blokowania.

Przebieg żądania:

  1. Serializuje ładunek JSON z losowymi numerami telefonów/wiadomościami:
    {
        "sender": "+0000000",
        "gsm": "+1234567890",
        "text": "Hello, this is a test message.",
        "usrClient": "Pruebas",
        "pasClient": "Pruebas"
    }
  2. Wysyła żądanie POST do określonego punktu końcowego.
  3. Śledzi sukcesy/porażki za pomocą Interlocked dla bezpiecznych liczników wątków.

D. Metryki i raportowanie

  • Stopwatch: Mierzy całkowity czas trwania testu.
  • Metryki wyjściowe:
    • Całkowity czas.
    • Zakończone/udane/nieudane żądania.
    • Żądania na sekundę (RPS): totalRequests / elapsedTime.

3. Wyróżnienia techniczne

  • Bezpieczeństwo wątków:
    • Interlocked.Increment zapewnia atomowe aktualizacje liczników między wątkami.
    • SemaphoreSlim zapobiega przeciążeniu serwera lub klienta.
  • Obsługa błędów:
    • Przechwytuje wyjątki (np. limity czasu, błędy sieciowe) i rejestruje porażki.
    • Weryfikuje kody statusu HTTP (IsSuccessStatusCode).
  • Optymalizacje wydajności:
    • Ponownie używa HttpClient (najlepsza praktyka dla uniknięcia wyczerpania portów TCP).
    • Konfigurowalny keep-alive do symulacji rzeczywistych scenariuszy.

4. Przykładowe zastosowanie

Aby przetestować SMS API pod adresem http://localhost:8080/sms z 1000 żądaniami (50 równoległych, keep-alive włączony):

Program http://localhost:8080/sms 1000 50 true

Wynik:

Test zakończony!
Całkowity czas: 12.34 sekundy
Zakończone żądania: 1000
Udane żądania: 980
Nieudane żądania: 20
Żądania na sekundę: 81.04

5. Dlaczego to ma znaczenie

  • Testowanie wydajności: Identyfikuje wąskie gardła API (np. limity serwera, opóźnienia sieciowe).
  • Testy regresji: Zapewnia, że wydajność nie pogarsza się po aktualizacjach.
  • Planowanie pojemności: Określa maksymalne obciążenie, które usługa może obsłużyć.

6. Potencjalne ulepszenia

  • Dodanie logiki ponawiania dla przejściowych błędów.
  • Obsługa uwierzytelniania (OAuth/klucze API).
  • Eksport wyników do CSV/JSON do analizy.

To narzędzie jest idealne dla developerów i zespołów DevOps weryfikujących wydajność bramki SMS przed wdrożeniem.

Podsumowanie

Test wydajności HTTP dla usług REST SMS zapewnia solidne, łatwe w użyciu rozwiązanie do benchmarkowania wydajności i niezawodności punktów końcowych SMS API. Symulując rzeczywisty ruch z konfigurowalną współbieżnością, generowaniem losowych wiadomości i szczegółowymi metrykami wydajności, to narzędzie pomaga developerom i zespołom QA identyfikować wąskie gardła, weryfikować skalowalność i optymalizować responsywność API. Niezależnie od tego, czy testujesz nowe wdrożenie pod kątem obciążenia, czy audytujesz istniejącą bramkę SMS, dołączony kod źródłowy w C# oferuje elastyczność dostosowania, a gotowy plik wykonywalny dostarcza szybkie, działające wnioski. Pobierz narzędzie już dziś, aby upewnić się, że Twoja usługa SMS spełnia oczekiwania wydajnościowe pod obciążeniem — i zapewnij użytkownikom końcowym płynne doświadczenie.

More information