Skip to content

Latest commit

 

History

History
93 lines (69 loc) · 3.33 KB

卡住问题解决.md

File metadata and controls

93 lines (69 loc) · 3.33 KB

解决webbench运行时卡住的问题

问题描述:

使用webbench进行压力测试的时候,在baidu上一般来说正常。在自己的webserver上测试,有时会卡住而没有返回值。在修改为长连接的时候尤其会发生。

如下图

Untitled

必须要ctrl+c终止。

github上也有这样的问题

长连接问题 · Issue #31 · linyacool/WebServer

解决思路:

找到可能被卡住的地方

测试时修改了部分源码进行打印,看每次1000个子进程中被阻塞了的进程数判断。

1:代码健壮性增加:从while (s = Socket(host, port) == -1){}; 修改为

while (!timerexpired == 0 && (s = Socket(host, port)) == -1){}; 避免反复创建socket一直失败陷入死循环而不理会时钟到期的回调函数早就把timerexpired 置为1,通知进程该结束了。

测试,没有明显好转。

2:修改socket函数,增加将创建的套接字使用fcntl设置fd为 O_NONBLOCK 非阻塞的代码。可以避免在read的时候阻塞,而服务器已经结束发送,从而无限等待下去。接着要对应修改前面的代码,当read返回-1,但是errno为EAGAIN的时候,不能计入fail,可能只是服务器响应慢了一点而以,设计为让他睡一下下,再继续。

if (i < 0 && errno == EAGAIN)
{
    usleep(200);
    continue;
}

测试,略有好转。

3:在测试时使用top查看,发现存在大量僵尸进程,卡住的时候僵尸进程还是很多。找到问题,有很多子进程是exit关闭的,父进程在fscanf,无法处理。导致clien—没有执行,无法跳出这个while循环。那么解决办法也就很明显了,给父进程也设置一个计时器与回调函数,到时间了就跳出这个循环,而不是使用while(1)死循环。

//测试时有时候webbench卡住,就应该是在这个while1循环里卡住的。
      while (1)
      {
/*
fscanf 函数原型为 int fscanf(FILE * stream, const char * format, [argument...]); 
其功能为根据数据格式(format),从输入流(stream)中读入数据,
存储到argument中,遇到空格和换行时结束。
*/
         pid = fscanf(f, "%d %d %d", &i, &j, &k);
         if (pid < 2)
         {
            fprintf(stderr, "Some of our childrens died.\n");
            break;
         }
         speed += i;
         failed += j;
         bytes += k;
         /* fprintf(stderr,"*Knock* %d %d read=%d\n",speed,failed,pid); */
         if (--clients == 0)
            break;
      }

增加代码

static void father_alarm_handler(__attribute__((unused)) int signal)
{
    time_up_hard = 1;
}

...
struct sigaction sa_father;
/* setup alarm signal handler */
sa_father.sa_handler = father_alarm_handler;
sa_father.sa_flags = 0;
if (sigaction(SIGALRM, &sa_father, NULL))
    exit(3);

alarm(benchtime + 5); // after benchtime,then exit
...
while (!time_up_hard)
        {
            pid = fscanf(f, "%d %d %d", &i, &j, &k);
...

测试,可以按时跳出。显示有很多的failed。(自己的玩具webserver还是不够好)

以上的修改增加了webbench的健壮性。但是需要注意的是,即使在改装webbench前,使用baidu测试并不会出现问题,说明自己的webserver还是有待完善。