HTTP-Geschwindigkeitstest für REST-SMS-Dienste

Müssen Sie die Leistung Ihres HTTP-basierten SMS-Dienstes messen? Der HTTP-Geschwindigkeitstest für REST-SMS-Dienste ist ein leistungsstarkes Tool, das entwickelt wurde, um die Geschwindigkeit und Zuverlässigkeit Ihrer JSON/REST-API-Endpunkte zu bewerten. Diese herunterladbare Anwendung ermöglicht es Ihnen, SMS-Anfragen mit hohem Volumen zu simulieren, Erfolgsquoten zu verfolgen und Anfragen pro Sekunde zu berechnen – und hilft Ihnen so, die Serverleistung unter Last zu optimieren. Egal, ob Sie eine lokale Entwicklungsumgebung einem Stresstest unterziehen oder ein Produktions- SMS-Gateway benchmarken möchten, dieses Tool liefert klare Metriken für Gesamtanfragen, gleichzeitige Verbindungen und HTTP-Keep-Alive-Effizienz. Laden Sie die sofort einsetzbare C#-Lösung herunter oder integrieren Sie den bereitgestellten Quellcode in Ihren Testworkflow für eine präzise API- Leistungsanalyse.

Download

HttpSpeedTest.zip

Beispielnutzung

Abbildung 1 - So verwenden Sie das Geschwindigkeitstest-Tool

Quellcode
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 = {
        "Hallo, dies ist eine Testnachricht.",
        "Leistungstest der HTTP-Server-Fähigkeiten.",
        "Messung der Anfragen pro Sekunde für die JSON-API.",
        "Zufälliger Nachrichteninhalt für Lasttests.",
        "Eine weitere Testnachricht mit anderem Inhalt.",
        "Überprüfung der Serverkapazität unter Last.",
        "Wie viele Anfragen kann der Server verarbeiten?",
        "Stresstest des SMS-API-Endpunkts.",
        "Diese Nachricht wird automatisch generiert.",
        "Letzte Testnachricht im Beispielset."
    };

    static async Task Main(string[] args)
    {
        Console.WriteLine("HTTP-Server JSON-API Leistungstester");
        Console.WriteLine("---------------------------------------");

        if (args.Length < 3)
        {
            Console.WriteLine("Verwendung: Programm    [useKeepAlive]");
            Console.WriteLine("Beispiel: Programm http://198.50.122.178:8080 1000 50 true");
            Console.WriteLine("Beispiel: Programm https://api.example.com/sms 5000 100 false");
            Console.WriteLine("Beispiel: Programm 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("Ungültige Basis-URL. Muss eine gültige HTTP- oder HTTPS-URL sein.");
            return;
        }

        if (!int.TryParse(args[1], out int totalRequests) || totalRequests <= 0)
        {
            Console.WriteLine("Ungültiger totalRequests-Wert. Muss eine positive Ganzzahl sein.");
            return;
        }

        if (!int.TryParse(args[2], out int concurrentRequests) || concurrentRequests <= 0)
        {
            Console.WriteLine("Ungültiger concurrentRequests-Wert. Muss eine positive Ganzzahl sein.");
            return;
        }

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

        Console.WriteLine($"Testparameter:");
        Console.WriteLine($"- Basis-URL: {baseUrl}");
        Console.WriteLine($"- Gesamte Anfragen: {totalRequests}");
        Console.WriteLine($"- Gleichzeitige Anfragen: {concurrentRequests}");
        Console.WriteLine($"- HTTP Keep-Alive: {(useKeepAlive ? "Aktiviert" : "Deaktiviert")}");
        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("Test wird gestartet...");

        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($"Anfrage fehlgeschlagen mit Status: {response.StatusCode}");
                    }
                }
                catch (Exception ex)
                {
                    System.Threading.Interlocked.Increment(ref completedRequests);
                    System.Threading.Interlocked.Increment(ref failedRequests);
                    Console.WriteLine($"Anfrage fehlgeschlagen: {ex.Message}");
                }
                finally
                {
                    semaphore.Release();
                }
            }));
        }

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

        Console.WriteLine("\nTest abgeschlossen!");
        Console.WriteLine($"Gesamtzeit: {stopwatch.Elapsed.TotalSeconds:F2} Sekunden");
        Console.WriteLine($"Abgeschlossene Anfragen: {completedRequests}");
        Console.WriteLine($"Erfolgreiche Anfragen: {successfulRequests}");
        Console.WriteLine($"Fehlgeschlagene Anfragen: {failedRequests}");
        Console.WriteLine($"Anfragen pro Sekunde: {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)];
    }
}

Code-Erklärung

1. Übersicht

Diese C#-Konsolenanwendung führt Lasttests für einen HTTP(S)-SMS-API-Endpunkt durch, indem sie gleichzeitige JSON-Anfragen sendet und Leistungsmetriken wie folgt misst:

  • Anfragen pro Sekunde (RPS)
  • Erfolgs-/Fehlerquoten
  • Gesamtausführungszeit

2. Hauptkomponenten

A. Einrichtung und Konfiguration

Zufällige Datengenerierung:

  • sampleMessages: Vordefinierter Satz von SMS-Textbeispielen für realistische Tests.
  • GenerateRandomPhoneNumber(): Erstellt gefälschte Telefonnummern (z.B. +1234567890).
  • GetRandomMessage(): Wählt eine zufällige Nachricht aus sampleMessages aus.

Kommandozeilenargumente:

Program <baseUrl> <totalRequests> <concurrentRequests> [useKeepAlive]
  • Validiert Eingaben (URL-Format, positive Ganzzahlen für Anfragezahlen).
  • Konfiguriert HTTP-Client-Einstellungen (Timeout, Keep-Alive, User-Agent).

B. HTTP-Client-Konfiguration

HttpClient-Anpassung:

  • MaxConnectionsPerServer: Begrenzt parallele Verbindungen zum Server.
  • ConnectionClose/keep-alive: Schaltet persistente HTTP-Verbindungen ein/aus.
  • Timeout: 30 Sekunden pro Anfrage.
  • Header: Setzt User-Agent und Accept: application/json.

C. Lasttest-Ausführung

Nebenläufigkeitssteuerung:

  • Verwendet SemaphoreSlim, um gleichzeitige Anfragen zu drosseln (z.B. 50 gleichzeitig).
  • Async/await (Task.Run) für nicht-blockierende I/O-Operationen.

Anfrageablauf:

  1. Serialisiert eine JSON-Nutzlast mit zufälligen Telefonnummern/Nachrichten:
    {
        "sender": "+0000000",
        "gsm": "+1234567890",
        "text": "Hallo, dies ist eine Testnachricht.",
        "usrClient": "Pruebas",
        "pasClient": "Pruebas"
    }
  2. Sendet eine POST-Anfrage an den angegebenen Endpunkt.
  3. Verfolgt Erfolge/Fehler mit Interlocked für threadsichere Zähler.

D. Metriken und Berichterstattung

  • Stoppuhr: Misst die gesamte Testdauer.
  • Ausgabemetriken:
    • Gesamt verstrichene Zeit.
    • Abgeschlossene/erfolgreiche/fehlgeschlagene Anfragen.
    • Anfragen pro Sekunde (RPS): totalRequests / elapsedTime.

3. Technische Highlights

  • Thread-Sicherheit:
    • Interlocked.Increment gewährleistet atomare Zähleraktualisierungen über Threads hinweg.
    • SemaphoreSlim verhindert eine Überlastung des Servers oder Clients.
  • Fehlerbehandlung:
    • Fängt Ausnahmen (z.B. Timeouts, Netzwerkfehler) ab und protokolliert Fehler.
    • Validiert HTTP-Statuscodes (IsSuccessStatusCode).
  • Leistungsoptimierungen:
    • Wiederverwendet HttpClient (beste Praxis zur Vermeidung von TCP-Port-Erschöpfung).
    • Konfigurierbares Keep-Alive, um reale Szenarien nachzubilden.

4. Beispielanwendungsfall

Um eine SMS-API unter http://localhost:8080/sms mit 1.000 Gesamtanfragen (50 gleichzeitig, Keep-Alive aktiviert) zu testen:

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

Ausgabe:

Test abgeschlossen!
Gesamtzeit: 12,34 Sekunden
Abgeschlossene Anfragen: 1000
Erfolgreiche Anfragen: 980
Fehlgeschlagene Anfragen: 20
Anfragen pro Sekunde: 81,04

5. Warum dies wichtig ist

  • Benchmarking: Identifiziert API-Engpässe (z.B. Serverlimits, Netzwerklatenz).
  • Regressionstests: Stellt sicher, dass die Leistung nach Updates nicht abnimmt.
  • Kapazitätsplanung: Bestimmt die maximale Last, die der Dienst bewältigen kann.

6. Mögliche Erweiterungen

  • Hinzufügen von Wiederholungslogik für vorübergehende Fehler.
  • Unterstützung für Authentifizierung (OAuth/API-Schlüssel).
  • Export der Ergebnisse in CSV/JSON zur Analyse.

Dieses Tool ist ideal für Entwickler und DevOps-Teams, die die Leistung von SMS-Gateways vor der Bereitstellung validieren.

Fazit

Der HTTP-Geschwindigkeitstest für REST-SMS-Dienste bietet eine robuste, benutzerfreundliche Lösung zum Benchmarking der Leistung und Zuverlässigkeit von SMS-API-Endpunkten. Durch die Simulation realen Datenverkehrs mit konfigurierbarer Nebenläufigkeit, zufälliger Nachrichtengenerierung und detaillierten Leistungsmetriken hilft dieses Tool Entwicklern und QA-Teams, Engpässe zu identifizieren, Skalierbarkeit zu validieren und die API-Reaktionsfähigkeit zu optimieren. Egal, ob Sie einen neuen Bereitstellungsstress testen oder ein bestehendes SMS-Gateway überprüfen, der enthaltene C#-Quellcode bietet Anpassungsflexibilität, während die vorkompilierte ausführbare Datei schnelle, umsetzbare Erkenntnisse liefert. Laden Sie das Tool noch heute herunter, um sicherzustellen, dass Ihr SMS-Dienst die Leistungserwartungen unter Last erfüllt – und bieten Sie Endnutzern ein nahtloses Erlebnis.

More information