昨天和同事奋战几个小时,解决了一个linger造成的bug。

现象是这样的,这是一个我从原型接手,扩充了各种功能成为可用代码的epoll实现的非阻塞socket server程序,接收大量的短连接,测试发现性能有问题,用gperftools的cpu profiler也没看出问题。就在一些可疑调用的地方前后加时间,耗时较长的就打出来。一开始发现是epoll处理某些fd的时间有时很长,最后发现是close(fd)耗时达一秒。我才想起来,上周为了解决短连接丢数据问题,把原来linger的超时从0改为了1,改回去现象就消失了,最后彻底去掉就解决了。

原来,在linux下,只要开启了linger并设置了非0的超时,那么close时,如果有数据待发送,就会阻塞最多达指定的时间,不管socket是不是阻塞的。看了一下内核代码,也确认是这样处理的,有点出乎意料。

// net/ipv4/tcp.c

void tcp_close(struct sock *sk, long timeout)
{
// ...
sk_stream_wait_close(sk, timeout);
// ...
}
// net/ipv4/af_inet.c

int inet_release(struct socket *sock)
{
struct sock *sk = sock->sk; if (sk) {
long timeout;
// ...
timeout = 0;
if (sock_flag(sk, SOCK_LINGER) &&
!(current->flags & PF_EXITING))
timeout = sk->sk_lingertime;
sock->sk = NULL;
sk->sk_prot->close(sk, timeout);
}
return 0;
}

回想当初是这个错误的原因是,因为manpage里没找到,我查一些文章却说close一个这样的socket时,会返回EWOULDBLOCK,大意了。至于代码当初为什么会开启linger,估计是为了消除TIME_WAIT,但是这种做法是得不偿失的。

查阅MSDN closesocket的文档,发现winsock下的行为不一样,会返回EWOULDBLOCK,这可能就是误导我的文章的说法的出处吧。

结论:对于使用非阻塞socket的程序,linger基本就是个无用且有害的选项,开启并设置0超时会丢数据,设置非0超时又会阻塞,因此千万不要用它。

TCP Linger的坑的更多相关文章

  1. Redis 高可用集群

    Redis 高可用集群 Redis 的集群主从模型是一种高可用的集群架构.本章主要内容有:高可用集群的搭建,Jedis连接集群,新增集群节点,删除集群节点,其他配置补充说明. 高可用集群搭建 集群(c ...

  2. OpenShift应用镜像构建(4) - fabric8-maven-plugin

    适合开发的构建fabric8-maven-plugin 在项目过程中越来越多的出现在开发阶段就需要把部分微服务直接做容器化发布,然后自己的代码还需要和这些发布后的微服务进行调用的开发过程,这个阶段基本 ...

  3. tcp.validnode_checking踩过的坑

    对Oracle 检查ip合法性,就必须在服务器端的sqlnet.ora文件中设置如下参数 TCP.INVITED_NODES=(10.0.0.36,10.0.0.1,10.0.0.35) TCP.EX ...

  4. tcp状态-TIME_WAIT与CLOSE_WAIT带来的坑

    tcp状态: http://www.cnblogs.com/DengGao/p/tcp_state.html 1. tcp连接会占用系统资源(文件描述符), 有时候甚至会导致系统假死(不能发起或者处理 ...

  5. 【服务器踩坑】SSMS链接Ubuntu上的SQL Server 2019 报错 TCP Provider: Error code 0x2746

    昨天在一台Ubuntu18.04.2 上安装了SQL Server 2019 for Linux 服务正常启动了,但是却无法通过命令行工具或者远程Windows机器上的SSMS链接. SSMS错误是 ...

  6. Kafka 0.9+Zookeeper3.4.6集群搭建、配置,新Client API的使用要点,高可用性测试,以及各种坑 (转载)

    Kafka 0.9版本对java client的api做出了较大调整,本文主要总结了Kafka 0.9在集群搭建.高可用性.新API方面的相关过程和细节,以及本人在安装调试过程中踩出的各种坑. 关于K ...

  7. HttpClient在多线程环境下踩坑总结

    问题现场 在多线程环境下使用HttpClient组件对某个HTTP服务发起请求,运行一段时间之后发现客户端主机CPU利用率呈现出下降趋势,而不是一个稳定的状态. 而且,从程序日志中判断有线程处于han ...

  8. 一次flume exec source采集日志到kafka因为单条日志数据非常大同步失败的踩坑带来的思考

    本次遇到的问题描述,日志采集同步时,当单条日志(日志文件中一行日志)超过2M大小,数据无法采集同步到kafka,分析后,共踩到如下几个坑.1.flume采集时,通过shell+EXEC(tail -F ...

  9. TCP随笔

    目录 前言 正文 time_wait和rst fin与连接关闭 nagel和ack延迟算法 滑动窗口与拥塞控制 文末 总结 测试代码 前言 网上已经有大量关于tcp的文章,感觉作为一名技术人员,不写一 ...

随机推荐

  1. id class

    id 选择器可以为标有特定 id 的 HTML 元素指定特定的样式. HTML元素以id属性来设置id选择器,CSS 中 id 选择器以 "#" 来定义. 以下的样式规则应用于元素 ...

  2. IDA6.6调试安卓程序配置教程

    1.把ida 目录下android_server传到设备的 /data/local/tmp/ cmd执行adb shell 进入模拟器命令行 su cd /data/local/tmp/ chmod ...

  3. 让乔布斯立足肩上的C语言之父

    2011年,人们对乔布斯的去世记忆深刻,但这一年还有另一位本应获得同样关注的人物也与世长辞,他就是C语言之父丹尼斯·里奇(Dennis Ritchie). 不过,并非所有人都没能正确认识到里奇所曾作出 ...

  4. 转:精美jQuery插件及源码 前端开发福利

    原文来自于:http://www.html5tricks.com/pretty-jquery-plugin.html jQuery是一个非常不错的javascript框架,很多前端开发者喜欢的原因不仅 ...

  5. 转:开源项目学习方法ABC

    文章来自于 http://yizhaolingyan.net/?p=123#comment-207 学习各种开源项目,已经成为很多朋友不可回避的工作内容了.笔者本人也是如此.在接触并学习了若干个开源项 ...

  6. C语言学习笔记--字符串函数

    字符串函数 需要包含头文件#include<stdio.h> strlen strcmp strcpy strchr strstr strcasestr

  7. CentOS下编译安装Gcc-4.9

    给公司测试服务器搭环境,手工安装gcc-4.9.0颇费功夫,记录如下. 1.安装gcc.g++,系统源默认安装版本为4.4.7: 2.安装依赖包GMP.MPFR.MPC,注意安装顺序: 3.修改动态库 ...

  8. POJ2248 A Knight's Journey(DFS)

    题目链接. 题目大意: 给定一个矩阵,马的初始位置在(0,0),要求给出一个方案,使马走遍所有的点. 列为数字,行为字母,搜索按字典序. 分析: 用 vis[x][y] 标记是否已经访问.因为要搜索所 ...

  9. -_-#【Angular】工具函数

    AngularJS学习笔记 上下文绑定 var f = angular.bind({a: 'xx'}, function() { console.log(this.a) }) f() // 'xx' ...

  10. Javascript语法基础

    Javascript语法基础   一.基本数据类型   JavaScript中支持数字.字符串和布尔值三种基本数据类型: 1.数字 数字型是JavaScript中的基本数据类型.在JavaScript ...