C语言简单实现一个 压力测试模拟程序

最近在做一个功能模块,目前功能上已经实现,但是性能暂时没有做过测试。

我的功能主要是接收 udp 消息,并将 udp 消息进行封装处理,发送到后端处理模块进行处理。

简单写一个小的 udp 客户端程序,去模拟压力测试。

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>

int main(int argc, char **argv)
{
    if (argc != 3)
    {
        printf("Usage: %s $SUM $RATE\n", argv[0]);
        exit(1);
    }

    struct sockaddr_in server_addr;
    memset(&server_addr, 0, sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
    server_addr.sin_port = htons(4020);

    int fd = socket(AF_INET, SOCK_DGRAM, 0);
    if (fd < 0)
    {
        printf("create socket failed: %s\n", strerror(errno));
        exit(2);
    }

    struct timeval start;
    gettimeofday(&start, NULL);
    unsigned long ustart = start.tv_sec*1000000 + start.tv_usec;

    usleep(1);

    struct timeval now;
    memset(&now, 0, sizeof(struct timeval));
    unsigned long unow = 0;

    int totalUdp = atoi(argv[1]);
    int maxRate = atoi(argv[2]); // caps
    printf("totalUdp: %d\n", totalUdp);
    printf("maxRate: %d\n", maxRate);

    int sum = 0;
    double rate = 0.0;

    char buff[1024*16] = ""; 
    while (sum < totalUdp)
    {
        gettimeofday(&now, NULL);
        unow = now.tv_sec*1000000 + now.tv_usec;
        rate = sum/(unow - ustart + 0.0);
        if (maxRate > 0 && rate * 1000000 > maxRate)
        {
            usleep(1000); // sleep 0.001 second
            continue;
        }
        sprintf(buff, "%d %d %d\0", now.tv_sec, now.tv_usec, sum);
        int res = sendto(fd, buff, strlen(buff), 0, (struct sockaddr*)&server_addr, sizeof(server_addr));
        if (res < 0)
        {
            printf("sendto error: %s\n", strerror(errno));
            exit(3);
        }
        // printf("send %d bytes ok\n", res);
        sum ++;
    }

    close(fd);

    printf("finish %d in %.3f, rate: %.f\n", sum, (unow-ustart+0.0)/1000000, rate*1000000);

    exit(0);
}

编码 && 运行:

[[email protected] test]$ gcc -o main main.c
[[email protected] test]$ ./main
Usage: ./main $SUM $RATE
[[email protected] test]$ ./main 10000 1000
totalUdp: 10000
maxRate: 1000
finish 10000 in 9.999, rate: 1000

程序原理很简单:

在未达到指定的发送消息数量时,不断去计算从开始发送时刻当前发送时刻平均发送速率,如果当前发送平均速率小于你指定的最大发送速率,则可以继续发送,否则暂停一小段时间,然后继续尝试发送。

例如:

我要测试 20k 的消息总量,2kcaps,如何运行?

./main 20000 2000

实际将在约 10s 后完成压力测试(发送)。

我们可以设定不同的模块配置参数(例如修改 udp 接收缓冲区的大小),以及每条 udp 消息的长度,每秒发送的 caps 量来做出一组性能测试结果,用以反映我们模块的性能。

压力测试模拟程序(C 实现)

Comments

Popular posts from this blog

Python Receiving and parse JSON Data via UDP protocol

ubus lua client method and event registration code demo/example