日期:2014-05-17  浏览次数:20825 次

性能/压力测试工具Apache ab修改系列:Part3——从文件中读取压力/性能测试的 url、header、cookie信息

需求:

修改Apache AB 工具,使其能够从文件中读取压力/性能测试的 url、header、cookie信息,并采用这些信息进行随机组合访问的压力和性能测试。

?

解决方案:

1. 如何从文件中读取url、header、cookie信息,并保证该操作不影响Apache AB的性能及数据统计?

首先,我所考虑的方法是,在ab读取设置参数的时候,如果配置为需要从文件中读取url、header、cookie等信息,则立即将这些信息读入到内存中备用,这样就能在Apache AB开始压测前完成所有的数据准备工作。

?

?

/* edit by gongyuan.cz */
    while ((status = apr_getopt(opt, "J:O:Q:n:c:t:b:T:p:u:v:rkVhwix:y:z:C:H:P:A:g:X:de:Sq"
#ifdef USE_SSL
            "Z:f:"
#endif
            ,&c, &optarg)) == APR_SUCCESS) {
        switch (c) {
			/* edit by gongyuan.cz start --- */
			case 'J':
				if(0 != (r = open_pathfile(optarg)))
					exit(r);
				break;
			case 'O':
				if(0 != (r = open_cookiefile(optarg)))
					exit(r);
				break;
			case 'Q':
				if(0 != (r = open_headerfile(optarg)))
					exit(r);
				break;
			/* edit by gongyuan.cz end ----- */
?

其次,我设计的数据在文件中的存放格式为:

?

数据在文件中存放的格式 写道
5
/url/xxx1.html
/url/xxx2.html
/url/xxx3.html
/url/xxx4.html
/url/xxx5.html

?其中,5代表文件中url的个数,而其后面的5行,每行代表一个url内容。

?

?接下来是读取文件的代码介绍:

?

/* read data to Path from file, edit by gongyuan.cz */

static int open_pathfile(const char *file)
{
    int file_len = 0, pos_cur = 0, line_size = 0, index = 0;
    char* databuff = NULL; 
    char* dataline = NULL;
    
    // 读取文件,并判断是否读取成功    
    FILE * in = fopen(file, "r");
    if (!in) {
        perror("Cannot open path file");
        exit(1);
    }
	
    // 获取文件的总长度大小
    fseek(in, 0, SEEK_END); 
    file_len = ftell(in); 
    fseek(in, 0, SEEK_SET); 
		
    // 设置一个数据buffer,并将文件的所有内容放入该buffer中
    databuff = (char*)malloc(file_len + 1); 
    fread(databuff, 1, file_len, in); 
    *(databuff+file_len) = '\0'; 

    // 以换行符“\n”为分隔符,获取每一行的数据
    // 在此,先读取第一行的数据,即url的数目,之后根据该数值为存放
    // url的数组申请空间
    dataline = strstr(databuff + pos_cur, "\n"); 
    if(dataline) 
    { 
        line_size = dataline - databuff - pos_cur; 
        dataline = (char*)malloc(line_size + 1); 
        strncpy(dataline, databuff + pos_cur, line_size); 
	*(dataline + line_size)= '\0'; 
	// 为存储url内容的数组 char ** pathName分配空间
        pathNum = atoi(dataline);
	pathName = (char**)malloc((pathNum + 1) * sizeof(char *));
	if(pathName == NULL){
		perror("Malloc path name error");
		exit(1);
	}
			
        pos_cur += line_size + 1; 
    } 

    //	读取后续的url内容,并存放到数组中
    do 
    {
        dataline = strstr(databuff + pos_cur, "\n"); 
        // 在此加了限制,防止数组越界
        if(dataline&&index < pathNum) 
        { 
            line_size = dataline - databuff - pos_cur; 
	    // set pathName
            pathName[index] = (char*)malloc(line_size + 1); 
            strncpy(pathName[index], databuff + pos_cur, line_size); 
            *(pathName[index] + line_size) = '\0'; 
	    index++;
            pos_cur += line_size + 1; 
        }
    }while(dataline); 

    // 最后结束,关闭文件,返回0	
    fclose(in);
    return 0;
}

/* ------------------------------------------------------- */
?

?

2. 如何构建url、header、cookie信息的随机组合访问的压力和性能测试?

为了能够根据我们的需求对AB的请求信息进行设置,我将AB内设置请求信息的代码独立编写成一个函数。

?

?

/* set request, edit by gongyuan.cz */

static void set_request()
{
	int snprintf_res = 0;
	/* setup request */
    if (posting <= 0) {
        snprintf_res = apr_snprintf(request, sizeof(_request),
            "%s %s HTTP/1.0\r\n"
            "%s" "%s" "%s"
            "%s" "\r\n",
            (posting == 0) ? "GET" : "HEAD",
            (isproxy) ? fullurl : path,
            keepalive ? "Connection: Keep-Alive\r\n" : "",
            cookie, auth, 
			headerNum ? hdrs_cp : hdrs);
    }
    else {
        snprintf_res = apr_snprintf(request,  sizeof(_request),
            "%s %s HT