免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 6308 | 回复: 10
打印 上一主题 下一主题

[C] 大量客户端重新连接 导致服务器端死锁,机器死机 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2011-09-05 11:39 |只看该作者 |倒序浏览
本帖最后由 usbzip 于 2011-09-05 11:54 编辑

tcp服务器端程序,平时连接的客户端有600多个,每隔30秒客户端发送一次数据。
服务器端有个map负责管理客户端ip和编号
使用了epoll模型
使用了线程池 线程池大小是16
epoll接收到socket事件,向线程池中派发任务。
企业adls 带宽2m
两者之间通过tcp通讯


现象
在工作正常的情况下,每分钟大约有5个左右的客户端会重新连接
有时会出现在及短的时间内(几秒内),大量(感觉更像是全部)客户端重新连接的现象,一个多月出现一次,期间服务端程序一直在工作。
16个线程都会对map进行添加和删除操作,程序进入死锁。

问题
这种突发的大量重连像是由什么引起的??  
象这种服务器端的应用如何减少死锁的情况?
谢谢大家

论坛徽章:
0
2 [报告]
发表于 2011-09-05 11:42 |只看该作者
客户端与服务器之间的连接是?

论坛徽章:
0
3 [报告]
发表于 2011-09-05 11:44 |只看该作者
标题写“崩溃”,内容写“死锁”,要崩溃了。。。。

不同的错误现象不同的原因,具体问题具体分析罗

论坛徽章:
0
4 [报告]
发表于 2011-09-05 11:46 |只看该作者
客户端与服务器之间的连接是?
雨过白鹭洲 发表于 2011-09-05 11:42



    tcp通讯

论坛徽章:
0
5 [报告]
发表于 2011-09-05 11:46 |只看该作者
标题写“崩溃”,内容写“死锁”,要崩溃了。。。。

不同的错误现象不同的原因,具体问题具体分析罗
drangon 发表于 2011-09-05 11:44


机器死掉了 只能重启

论坛徽章:
1
天蝎座
日期:2013-12-06 18:23:58
6 [报告]
发表于 2011-09-05 12:05 |只看该作者
回复 1# usbzip


    太笼统了啊!估计还要好好的排查下代码流程

论坛徽章:
0
7 [报告]
发表于 2011-09-05 13:13 |只看该作者
代码
signal(SIGCHLD, SIG_IGN);
  int enums,j,Newfd,listen_index,epollfd,listenq,epollsize,n;
  struct sockaddr_in TheirAddr;
  socklen_t len;
  epollsize = (LGWTCPConf.GetConf()).MaxPollSize;
  listenq = (LGWTCPConf.GetConf()).MaxListenQ;
  ServerInit();

  struct epoll_event ev;
  struct epoll_event events[1000];
  epollfd = epoll_create(epollsize);
  LOG4CPLUS_INFO(log.GetLogInstance(),"epoll create "<< epollfd);
  len = sizeof(struct sockaddr_in);
  ev.events = EPOLLIN | EPOLLET;
  ev.data.fd = LGWTCPSock;
  if (epoll_ctl(epollfd, EPOLL_CTL_ADD, LGWTCPSock, &ev) < 0) {
    LOG4CPLUS_INFO(log.GetLogInstance(),"epoll set insertion error\n");
    return -1;
  }
  LOG4CPLUS_INFO(log.GetLogInstance(),"start main loop \n");
  while(1)
  {
    enums = epoll_wait(epollfd, events, listenq, 20);
    if (enums == -1)
    {
        printf("errno=%d,%s\r\n",errno,strerror(errno));
        if(errno==EINTR)
        {
            continue;
        }
        perror("epoll_wait");
    }
    else if(enums==0)
    {
        continue;
    }
    for (n = 0; n < enums; ++n) {
      listen_index=events[n].data.u32;
      if (events[n].data.fd == LGWTCPSock) {
        do {
            Newfd = accept(LGWTCPSock, (struct sockaddr *) &TheirAddr,&len);
            if (Newfd < 0) {
                break;
            }
            printf("Connect from %s:%d Newfd %d\n", inet_ntoa(TheirAddr.sin_addr),htons(TheirAddr.sin_port),Newfd);
            setnonblocking(Newfd);
            int keepCount = 3;
            int keepInterval = 5;
            int keepIdle = 600;
            int keepAlive = 1;
            setsockopt(Newfd, SOL_SOCKET, SO_KEEPALIVE, (void *)&keepAlive, sizeof(keepAlive));
            setsockopt(Newfd, SOL_TCP, TCP_KEEPIDLE, (void*)&keepIdle, sizeof(keepIdle));
            setsockopt(Newfd, SOL_TCP, TCP_KEEPINTVL, (void *)&keepInterval, sizeof(keepInterval));
            setsockopt(Newfd, SOL_TCP, TCP_KEEPCNT, (void *)&keepCount, sizeof(keepCount));
            ev.events = EPOLLIN | EPOLLET;
            ev.data.fd = Newfd;
            if (epoll_ctl(epollfd, EPOLL_CTL_ADD, Newfd, &ev) < 0) {
              fprintf(stderr, " socket '%d' add epoll error! %s\n",Newfd, strerror(errno));

            }
        }while(Newfd>0);
      }
      else if(events[n].events & EPOLLIN)
      {
        for(j=0;j<MAXTHREAD;j++)
        {
          if(0==s_thread_para[j][0]) break;
        }
        if(j>MAXTHREAD)
        {
          LOG4CPLUS_INFO(log.GetLogInstance(),"thread pool is full!\n");
          close(Newfd);
          continue;
        }
        pthread_mutex_lock(&mutex);
        s_thread_para[j][0]=1;
        s_thread_para[j][1]=events[n].data.fd;
        pthread_mutex_unlock(&mutex);
        pthread_mutex_unlock(s_mutex+j);
      }
    }
  }

这段有什么问题么

论坛徽章:
0
8 [报告]
发表于 2011-09-05 13:14 |只看该作者
代码
signal(SIGCHLD, SIG_IGN);
  int enums,j,Newfd,listen_index,epollfd,listenq,epollsize,n;
  struct sockaddr_in TheirAddr;
  socklen_t len;
  epollsize = (LGWTCPConf.GetConf()).MaxPollSize;
  listenq = (LGWTCPConf.GetConf()).MaxListenQ;
  ServerInit();

  struct epoll_event ev;
  struct epoll_event events[1000];
  epollfd = epoll_create(epollsize);
  LOG4CPLUS_INFO(log.GetLogInstance(),"epoll create "<< epollfd);
  len = sizeof(struct sockaddr_in);
  ev.events = EPOLLIN | EPOLLET;
  ev.data.fd = LGWTCPSock;
  if (epoll_ctl(epollfd, EPOLL_CTL_ADD, LGWTCPSock, &ev) < 0) {
    LOG4CPLUS_INFO(log.GetLogInstance(),"epoll set insertion error\n");
    return -1;
  }
  LOG4CPLUS_INFO(log.GetLogInstance(),"start main loop \n");
  while(1)
  {
    enums = epoll_wait(epollfd, events, listenq, 20);
    if (enums == -1)
    {
        printf("errno=%d,%s\r\n",errno,strerror(errno));
        if(errno==EINTR)
        {
            continue;
        }
        perror("epoll_wait");
    }
    else if(enums==0)
    {
        continue;
    }
    for (n = 0; n < enums; ++n) {
      listen_index=events[n].data.u32;
      if (events[n].data.fd == LGWTCPSock) {
        do {
            Newfd = accept(LGWTCPSock, (struct sockaddr *) &TheirAddr,&len);
            if (Newfd < 0) {
                break;
            }
            printf("Connect from %s:%d Newfd %d\n", inet_ntoa(TheirAddr.sin_addr),htons(TheirAddr.sin_port),Newfd);
            setnonblocking(Newfd);
            int keepCount = 3;
            int keepInterval = 5;
            int keepIdle = 600;
            int keepAlive = 1;
            setsockopt(Newfd, SOL_SOCKET, SO_KEEPALIVE, (void *)&keepAlive, sizeof(keepAlive));
            setsockopt(Newfd, SOL_TCP, TCP_KEEPIDLE, (void*)&keepIdle, sizeof(keepIdle));
            setsockopt(Newfd, SOL_TCP, TCP_KEEPINTVL, (void *)&keepInterval, sizeof(keepInterval));
            setsockopt(Newfd, SOL_TCP, TCP_KEEPCNT, (void *)&keepCount, sizeof(keepCount));
            ev.events = EPOLLIN | EPOLLET;
            ev.data.fd = Newfd;
            if (epoll_ctl(epollfd, EPOLL_CTL_ADD, Newfd, &ev) < 0) {
              fprintf(stderr, " socket '%d' add epoll error! %s\n",Newfd, strerror(errno));

            }
        }while(Newfd>0);
      }
      else if(events[n].events & EPOLLIN)
      {
        for(j=0;j<MAXTHREAD;j++)
        {
          if(0==s_thread_para[j][0]) break;
        }
        if(j>MAXTHREAD)
        {
          LOG4CPLUS_INFO(log.GetLogInstance(),"thread pool is full!\n");
          close(Newfd);
          continue;
        }
        pthread_mutex_lock(&mutex);
        s_thread_para[j][0]=1;
        s_thread_para[j][1]=events[n].data.fd;
        pthread_mutex_unlock(&mutex);
        pthread_mutex_unlock(s_mutex+j);
      }
    }
  }

这段有什么问题么

论坛徽章:
0
9 [报告]
发表于 2011-09-05 14:47 |只看该作者
for(j=0;j<MAXTHREAD;j++)
        {
          if(0==s_thread_para[j][0]) break;
        }
        if(j>MAXTHREAD)
        {
          LOG4CPLUS_INFO(log.GetLogInstance(),"thread pool is full!\n");
          close(Newfd);
          continue;
这段纯粹是有问题:
1.你的线程池只能接收MAXTHREAD 个任务吗?这是什么设计?线程池是从任务队列里取数据的。
2. if(j>MAXTHREAD)  close(Newfd); 这个就是你为什么会重置连接的原因。 你的Newfd是什么值,你搞清楚没?还有没有看见你在这个elseif 里赋值给它。
3. 代码是不是不全? 没有见到pthread_mutex_unlock(s_mutex+j); 加锁的地方,死锁是这里发生的?

论坛徽章:
0
10 [报告]
发表于 2011-09-05 15:05 |只看该作者
for(j=0;j<MAXTHREAD;j++)
if(j>MAXTHREAD)

j==MAXTHREAD?
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP