Chinaunix首页 | 论坛 | 博客
  • 博客访问: 67521
  • 博文数量: 8
  • 博客积分: 1416
  • 博客等级: 上尉
  • 技术积分: 90
  • 用 户 组: 普通用户
  • 注册时间: 2009-10-21 22:35
个人简介

The best or nothing!

文章分类

全部博文(8)

文章存档

2020年(1)

2015年(3)

2011年(3)

2010年(1)

分类: 网络与安全

2015-07-02 16:18:29

       LoadRunner压力测试SSLVPN服务器, 服务进程重启了. 用netstat -anp | grep tcp | wc -l查看, TCP连接有几万个之多! 使用
netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'查看, 基本都是CLOSE_WAIT状态的TCP连接. 出现CLOSE_WAIT状态的TCP连接, 根本原因是服务器被动断开TCP连接时, 没有执行close(socketfd)操作. 刚开始我希望通过关闭fd来解决问题, 但是由于服务器的代码实现很垃圾, 基本处于不可维护状态, 在异常处理(主要是检查recv()的返回值, 如果是0, 则表明peer断开连接了, 我们可以执行close操作)时, 也不能直接关闭fd, 因为其他地方可能还在使用这个socket. 
      最后, 决定使用keepalive来限制CLOSE_WAIT状态的TCP个数, 在创建socket时, 作以下设置:
   

点击(此处)折叠或打开

  1.  opt = 1;
  2.     opt_len = sizeof(opt);
  3.     ret = setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, &opt, opt_len);
  4.     if (ret < 0)
  5.     {
  6.         ERR("set SO_KEEPALIVE option failed\n");
  7.         return ;
  8.     }
  9.     opt = 5;
  10.     ret = setsockopt(sockfd, SOL_TCP, TCP_KEEPCNT, &opt, opt_len);
  11.     if (ret < 0)
  12.     {
  13.         ERR("set TCP_KEEPCNT option failed\n");
  14.         return ;
  15.     }
  16.     opt = 60;
  17.     ret = setsockopt(sockfd, SOL_TCP, TCP_KEEPIDLE, &opt, opt_len);
  18.     if (ret < 0)
  19.     {
  20.         ERR("set TCP_KEEPIDLE option failed\n");
  21.         return ;
  22.     }
  23.     opt = 10;
  24.     ret = setsockopt(sockfd, SOL_TCP, TCP_KEEPINTVL, &opt, opt_len);
  25.     if (ret < 0)
  26.     {
  27.         ERR("set TCP_KEEPINTVL option failed\n");
  28.         return ;
  29.     }
    这样, 每个TCP连接的IDLE时间是1min, 然后每过10s发送一次keepalive, 总共发5次. 这样一个TCP连接最多在IDLE状态2分钟左右.





阅读(3205) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~