Teste de Velocidade HTTP para serviços REST de SMS

Precisa medir o desempenho do seu serviço de SMS baseado em HTTP? O Teste de Velocidade HTTP para Serviços REST de SMS é uma ferramenta poderosa projetada para avaliar a velocidade e a confiabilidade dos seus endpoints de API JSON/REST. Este utilitário para download permite simular solicitações de SMS de alto volume, rastrear taxas de sucesso e calcular solicitações por segundo—ajudando você a otimizar o desempenho do servidor sob carga. Seja para testar o estresse de um ambiente de desenvolvimento local ou para avaliar um gateway de SMS em produção, esta ferramenta fornece métricas claras para total de solicitações, conexões simultâneas e eficiência do HTTP Keep-Alive. Baixe a solução em C# pronta para uso ou integre o código-fonte fornecido no seu fluxo de trabalho de testes para uma análise precisa do desempenho da API.

Download HttpSpeedTest.zip Exemplo de uso

Figura 1 - Como usar a ferramenta de teste de velocidade

Código fonte

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 = {
        "Olá, esta é uma mensagem de teste.",
        "Testando o desempenho das capacidades do servidor HTTP.",
        "Medindo requisições por segundo para API JSON.",
        "Conteúdo de mensagem aleatória para teste de carga.",
        "Outra mensagem de teste com conteúdo diferente.",
        "Verificando a capacidade do servidor sob carga.",
        "Quantas requisições o servidor pode lidar?",
        "Teste de estresse no endpoint da API de SMS.",
        "Esta mensagem é gerada automaticamente.",
        "Mensagem de teste final no conjunto de exemplos."
    };

    static async Task Main(string[] args)
    {
        Console.WriteLine("Testador de Desempenho de API JSON do Servidor HTTP");
        Console.WriteLine("----------------------------------------------------");

        if (args.Length < 3)
        {
            Console.WriteLine("Uso: Programa    [usarKeepAlive]");
            Console.WriteLine("Exemplo: Programa http://198.50.122.178:8080 1000 50 true");
            Console.WriteLine("Exemplo: Programa https://api.exemplo.com/sms 5000 100 false");
            Console.WriteLine("Exemplo: Programa 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("URL base inválida. Deve ser uma URL HTTP ou HTTPS válida.");
            return;
        }

        if (!int.TryParse(args[1], out int totalRequests) || totalRequests <= 0)
        {
            Console.WriteLine("Valor de totalRequests inválido. Deve ser um inteiro positivo.");
            return;
        }

        if (!int.TryParse(args[2], out int concurrentRequests) || concurrentRequests <= 0)
        {
            Console.WriteLine("Valor de concurrentRequests inválido. Deve ser um inteiro positivo.");
            return;
        }

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

        Console.WriteLine($"Parâmetros do Teste:");
        Console.WriteLine($"- URL Base: {baseUrl}");
        Console.WriteLine($"- Total de Requisições: {totalRequests}");
        Console.WriteLine($"- Requisições Concorrentes: {concurrentRequests}");
        Console.WriteLine($"- HTTP Keep-Alive: {(useKeepAlive ? "Ativado" : "Desativado")}");
        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("Iniciando teste...");

        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($"Requisição falhou com status: {response.StatusCode}");
                    }
                }
                catch (Exception ex)
                {
                    System.Threading.Interlocked.Increment(ref completedRequests);
                    System.Threading.Interlocked.Increment(ref failedRequests);
                    Console.WriteLine($"Requisição falhou: {ex.Message}");
                }
                finally
                {
                    semaphore.Release();
                }
            }));
        }

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

        Console.WriteLine("\nTeste concluído!");
        Console.WriteLine($"Tempo total: {stopwatch.Elapsed.TotalSeconds:F2} segundos");
        Console.WriteLine($"Requisições concluídas: {completedRequests}");
        Console.WriteLine($"Requisições bem-sucedidas: {successfulRequests}");
        Console.WriteLine($"Requisições falhas: {failedRequests}");
        Console.WriteLine($"Requisições por segundo: {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)];
    }
}

Explicação do código

1. Visão Geral

Esta aplicação de console em C# testa a carga de um endpoint de API HTTP(S) para SMS enviando requisições JSON concorrentes, medindo métricas de desempenho como:

  • Requisições por segundo (RPS)
  • Taxas de sucesso/falha
  • Tempo total de execução
2. Componentes Principais

A. Configuração e Definição

Geração de Dados Aleatórios:

  • sampleMessages: Conjunto pré-definido de amostras de texto SMS para testes realistas.
  • GenerateRandomPhoneNumber(): Cria números de telefone falsos (ex.: +1234567890).
  • GetRandomMessage(): Seleciona uma mensagem aleatória de sampleMessages.

Argumentos de Linha de Comando:

Program <baseUrl> <totalRequests> <concurrentRequests> [useKeepAlive]
  • Valida entradas (formato de URL, números inteiros positivos para contagem de requisições).
  • Configura as definições do cliente HTTP (timeout, keep-alive, user-agent).

B. Configuração do Cliente HTTP

Personalização do HttpClient:

  • MaxConnectionsPerServer: Limita conexões paralelas ao servidor.
  • ConnectionClose/keep-alive: Alterna entre conexões HTTP persistentes.
  • Timeout: 30 segundos por requisição.
  • Cabeçalhos: Define User-Agent e Accept: application/json.

C. Execução do Teste de Carga

Controle de Concorrência:

  • Usa SemaphoreSlim para limitar requisições concorrentes (ex.: 50 por vez).
  • Async/await (Task.Run) para operações de I/O não bloqueantes.

Fluxo de Requisição:

  1. Serializa um payload JSON com números de telefone/mensagens aleatórios:
    {
        "sender": "+0000000",
        "gsm": "+1234567890",
        "text": "Olá, esta é uma mensagem de teste.",
        "usrClient": "Pruebas",
        "pasClient": "Pruebas"
    }
  2. Envia uma requisição POST para o endpoint especificado.
  3. Rastreia sucessos/falhas usando Interlocked para contadores thread-safe.

D. Métricas e Relatórios

  • Stopwatch: Mede a duração total do teste.
  • Métricas de Saída:
    • Tempo total decorrido.
    • Requisições completadas/sucedidas/falhas.
    • Requisições por segundo (RPS): totalRequests / elapsedTime.
3. Destaques Técnicos
  • Segurança em Threads:
    • Interlocked.Increment garante atualizações atômicas de contadores entre threads.
    • SemaphoreSlim evita sobrecarregar o servidor ou cliente.
  • Tratamento de Erros:
    • Captura exceções (ex.: timeouts, erros de rede) e registra falhas.
    • Valida códigos de status HTTP (IsSuccessStatusCode).
  • Otimizações de Desempenho:
    • Reutiliza HttpClient (melhor prática para evitar esgotamento de portas TCP).
    • Keep-alive configurável para simular cenários do mundo real.
4. Exemplo de Uso

Para testar uma API SMS em http://localhost:8080/sms com 1.000 requisições totais (50 concorrentes, keep-alive ativado):

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

Saída:

Teste concluído!
Tempo total: 12.34 segundos
Requisições completadas: 1000
Requisições bem-sucedidas: 980
Requisições falhas: 20
Requisições por segundo: 81.04
5. Por Que Isso Importa
  • Benchmarking: Identifica gargalos na API (ex.: limites do servidor, latência de rede).
  • Teste de Regressão: Garante que o desempenho não degrade após atualizações.
  • Planejamento de Capacidade: Determina a carga máxima que o serviço pode suportar.
6. Possíveis Melhorias
  • Adicionar lógica de repetição para falhas transitórias.
  • Suporte para autenticação (OAuth/chaves de API).
  • Exportar resultados para CSV/JSON para análise.

Esta ferramenta é ideal para desenvolvedores e equipes de DevOps validarem o desempenho de gateways SMS antes da implantação.

Conclusão

O HTTP Speed Test para Serviços REST de SMS oferece uma solução robusta e fácil de usar para avaliar o desempenho e a confiabilidade de endpoints de API SMS. Ao simular tráfego do mundo real com concorrência configurável, geração de mensagens aleatórias e métricas detalhadas de desempenho, esta ferramenta ajuda desenvolvedores e equipes de QA a identificar gargalos, validar escalabilidade e otimizar a responsividade da API. Seja para testar a carga de uma nova implantação ou auditar um gateway SMS existente, o código-fonte em C# incluído oferece flexibilidade para personalização, enquanto o executável pré-construído fornece insights rápidos e acionáveis. Baixe a ferramenta hoje para garantir que seu serviço SMS atenda às expectativas de desempenho sob carga—e ofereça uma experiência perfeita aos usuários finais.

More information