昨天和同事奋战几个小时,解决了一个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. JavaScript奇技淫巧44招

    JavaScript是一个绝冠全球的编程语言,可用于Web开发.移动应用开发(PhoneGap.Appcelerator).服务器端开发(Node.js和Wakanda)等等.JavaScript还是 ...

  2. Eclipse 将Java项目转为Dynamic web project

    1.打开项目根目次下的.project 在<buildSpec>节点下是否存在 <buildCommand> <name>org.eclipse.wst.commo ...

  3. bzoj1188: [HNOI2007]分裂游戏

    Description 聪聪和睿睿最近迷上了一款叫做分裂的游戏. 该游戏的规则试: 共有 n 个瓶子, 标号为 0,1,2.....n-1, 第 i 个瓶子中装有 p[i]颗巧克力豆,两个人轮流取豆子 ...

  4. 《30天自制操作系统》读书笔记(2)hello, world

    让系统跑起来 要写一个操作系统,我们首先要有一个储存系统的介质,原版书似乎是06年出版的,可惜那时候没有电脑,没想到作者用的还是软盘,现在的电脑谁有软驱?不得已我使用一张128M的SD卡来代替,而事实 ...

  5. 使用Struts1完成用户登录功能

    1.Struts框架 框架(framework):就是一系列代码和开发模式的整合,使用框架后,所有开发人员都会按照框架提供的规范进行开发,使代码更容易维护和扩展. 使用框架的优点: 1)   易于维护 ...

  6. 其实,SSL也不是配通了就什么都不管的~~

    其中太多的中间人攻击需要去加强加固~~ 测试过A级是必须的!! https://www.ssllabs.com/ssltest/ 这网址两年前,我写过的哈

  7. GitHub上最火的开源项目SlidingMenu导入出错的终极解决方案

    SlidingMenu 开源项目下载地址 : https://github.com/jfeinstein10/slidingmenu Actionbarsherlock 开源项目下载地址 :http: ...

  8. Codec plugins ? multiline

    Codec plugins ? multiline multiline codec 会折叠多行消息,合并它们到一个事件 这个codec 原始的目的是允许 连接多行信息从文件到一个单独的事件. 比如, ...

  9. Macro Substitution

    看<C程序设计语言>(英文版)学到的两个用法. 两个很简单的宏用法. #的用法: if, however, a parameter name is preceded by a # in t ...

  10. C# .NET开发Oracle数据库应用程序

    .NET Framework访问Oracle数据库至少有两种方式,一种是利用微软提供的ADO.NET,另一种是利用Oracle提供的ODP.NET. 安装VS的时候会附带ADO.NET,安装Oracl ...