测试web服务器的压力测试程序

以下代码是自己写的一个测试web服务器的压力测试程序,采用epoll多路分发模型,虽然是单线程但可以产生足够的压力。感兴趣的同学可以修改一下测试自己的服务器程序。

</pre><pre name="code" class="cpp"><span style="font-size:12px;">#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <assert.h>
#include <time.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <signal.h>
#include <errno.h>
#include <netinet/in.h>
#include <unistd.h>
#include <sys/epoll.h>
#include <string.h>
#include <strings.h>
#include <sys/socket.h>
#include <arpa/inet.h>

#define MY_LOGFILE "./log_stress"

static char* ip = NULL;
static int port = 0;
void mydebug(const char *fmt, ...)
{
	time_t nowtime = time(NULL);
	struct tm *pNowtime=NULL;
	pNowtime = localtime(&nowtime);
	char debugbuff[2048];
	int outlen;
	FILE *fp;
	va_list ap;
	fp = fopen(MY_LOGFILE,"a");
	if(fp==NULL)
	{
		fp = fopen(MY_LOGFILE,"w");
		if(fp == NULL)
			return;
	}
	va_start(ap, fmt);
	outlen=vsprintf(debugbuff,fmt,ap);
	va_end(ap);
	*(debugbuff+outlen) = 0;
	fprintf(fp,"%d-%02d-%02d %02d:%02d:%02d====",pNowtime->tm_year+1900,pNowtime->tm_mon+1,pNowtime->tm_mday,pNowtime->tm_hour,pNowtime->tm_min,pNowtime->tm_sec);
	fprintf(fp,"%s",debugbuff);
	fclose(fp);
}


int setnonblocking(int fd){
	int old_option = fcntl(fd,F_GETFL);
	int new_option = old_option | O_NONBLOCK;
	fcntl(fd,F_SETFL,new_option);
	return old_option;
}


void addfd(int epoll_fd,int fd){
	struct epoll_event event;
	event.data.fd = fd;
	event.events = EPOLLOUT | EPOLLET;
	epoll_ctl(epoll_fd,EPOLL_CTL_ADD,fd,&event);
	setnonblocking(fd);
}

int write_nbytes(int sockfd,const char* buffer,int len){
	int bytes_write = 0;
	mydebug("%s[%d] INFO:write out %d bytes to socket %d\n",__FILE__,__LINE__,len,sockfd);
	//printf("write out %d bytes to socket %d\n",len,sockfd);
	while(1){
		bytes_write = send(sockfd,buffer,len,0);
		if(bytes_write==-1){
			return -1;
		}
		else if(bytes_write==0){
			return -1;
		}
		len = len - bytes_write;
		buffer = buffer + bytes_write;
		if(len<=0){
			return 0;
		}
	}
}

int  read_once(int sockfd,char* buffer,int len){
	int bytes_read = 0;
	memset(buffer,0,len);
	bytes_read = recv(sockfd,buffer,len,0);
	if(bytes_read==-1){
		return -1;
	}
	else if(bytes_read==0){
		return -1;
	}
	else{
		mydebug("%s[%d] INFO:read in %d bytes from socket %d",__FILE__,__LINE__,bytes_read,sockfd);
		//printf("read in %d bytes from socket %d with content:%s\n",bytes_read,sockfd,buffer);
	}
	return 0;
}

int start_conn(int epoll_fd,int num,const char* ip,int port){
	int ret = 0;
	struct sockaddr_in address;
	bzero(&address,sizeof(address));
	address.sin_family = AF_INET;
	inet_pton(AF_INET,ip,&address.sin_addr);
	address.sin_port = htons(port);
	for(int i = 0;i<num;++i){
		usleep(50);
		int sockfd = socket(PF_INET,SOCK_STREAM,0);
		//printf("create 1 socket\n");
		if(sockfd<0){
			continue;
		}
		if(connect(sockfd,(struct sockaddr*)&address,sizeof(address))==0){
			mydebug("%s[%d] INFO:build connection %d\n",__FILE__,__LINE__,sockfd);
			//printf("build connection %d\n",i);
			addfd(epoll_fd,sockfd);
		}
		else{
			mydebug("%s[%d] ERROR:fail connection %d\n",__FILE__,__LINE__,sockfd);
			close(sockfd);
		}

	}

}

void close_conn(int epoll_fd,int sockfd){
	epoll_ctl(epoll_fd,EPOLL_CTL_DEL,sockfd,0);
	close(sockfd);
	start_conn(epoll_fd,1,ip,port);

}


int main(int argc,char* argv[])
{
	if(argc!=4){
		printf("usage:[stress_server] [ip] [port] [connect num]\n");
		return 1;

	}
	signal(SIGPIPE,SIG_IGN);
	char *request = "GET /start HTTP/1.1\r\n\r\n";
	ip = argv[1];
	port = atoi(argv[2]);
	int epoll_fd = epoll_create(128);
	start_conn(epoll_fd,atoi(argv[3]),ip,port);
	struct epoll_event events[10000];
	char buffer[128];
	while(1){
		int fds = epoll_wait(epoll_fd,events,10000,2000);
		for(int i=0;i<fds;i++){
			int sockfd = events[i].data.fd;
			if(events[i].events & EPOLLIN){
				if(read_once(sockfd,buffer,128)==-1){
					close_conn(epoll_fd,sockfd);
				}
				struct epoll_event event;
				event.events = EPOLLOUT | EPOLLET;
				event.data.fd = sockfd;
				epoll_ctl(epoll_fd,EPOLL_CTL_MOD,sockfd,&event);
			}
			else if(events[i].events & EPOLLOUT){
				if(write_nbytes(sockfd,request,strlen(request))==-1){
					close_conn(epoll_fd,sockfd);
				}
				struct epoll_event event;
				event.events = EPOLLIN | EPOLLET;
				event.data.fd = sockfd;
				epoll_ctl(epoll_fd,EPOLL_CTL_MOD,sockfd,&event);
			}
			else if(events[i].events & EPOLLERR){
				close_conn(epoll_fd,sockfd);
			}
		}
	}
	return 0;
}
</span>

在网上看到了一个不错的压力测试工具Webbench,采用多进程的方式连接服务器产生压力。

</pre><pre name="code" class="plain">wget http://blog.zyan.cc/soft/linux/webbench/webbench-1.5.tar.gz
tar zxvf webbench-1.5.tar.gz
cd webbench-1.5
make && make install
webbench -c 500 -t 30 http://127.0.0.1/test.jpg
Webbench - Simple Web Benchmark 1.5
Copyright (c) Radim Kolar 1997-2004, GPL Open Source Software.

Benchmarking: GET http://127.0.0.1/test.jpg
500 clients, running 30 sec.

Speed=3230 pages/min, 11614212 bytes/sec.
Requests: 1615 susceed, 0 failed.





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值