在一次测试执行过程中,发现服务器TCP发送队列较长,执行netstat -s | grep LISTEN,发现有SYNs包被丢弃,但是没有times the listen queue of a socket overflowed,即有可能是半连接队列溢出。

以下转自:http://blog.chinaunix.net/uid-13776576-id-5780567.html

问题描述:
最近遇到了一个syn丢包的情况,当系统磁盘、网络、cpu都无压力的时候,系统莫名其妙出现“sync to listen sockets drop”问题;无论带宽是10M还是8G,都会出现这种这种情况。现象为:输入系统命令:netstat -s | grep LISTEN,会出现 syns to listen sockets dropped; 但是并没有times the listen queue of a socket overflowed;连接队列包括两种,一个是半连接队列(syn queue),一个是全连接队列(accept queue);根据上述描述,accept队列并没有溢出,而syn队报丢失有可能是syn队列溢出的原因,也可能是其他原因;"syns to listen sockets dropped"意思是:收到三次握手的ack包,因为各种原因导致创建socket的过程中被丢弃;
首先我们分析了一下netstat -s里面的数据,发现"passive connections rejected because of time stamp"的值和"syns to listen sockets dropped"相差不大,很多服务器他们的值都是相同的,这个让人感觉sync to listen sockets drop的原因有可能与时间戳有关;

我们检查了一下系统的配置:
or的keepalive设置为512个,总共40个cpu;系统级别的监听队列长度是65535,syn队列是26w;or的每个进程监听队列是20w;
我们的架构是上层是openresty,下层是我们的自研缓存软件;
syns to listen sockets dropped; 是由于在三次握手过程中创建socket失败,但是我们不知道是or或者cache软件作为客户端丢失syn包还是or或者cache软件作为服务器丢失syn包;于是我们做了一系列测试;
发现以下几点:
1. client(用户)访问or层,会导致or层作为服务器端的syn包丢失;
2. or作为客户端,访问cache软件时,or发出的syn包没有丢失;(or和cache软件是同一个机房);
3. cache软件作为服务器,接受到的syn包没有丢失;
4. cache软件作为客户端,发出去的syn包没有丢失(cache软件主要是给其他IDC发送http请求);
于是我们的重点是解决用户给or的syn包丢失的问题;
我们从网上查找原因,查到了最有可能的原因:
:因为2.6内核以上中tcp_timestamps默认是打开的,所以当打开 tcp_tw_recycle时会导致部分通过NAT上网client无法正确连接服务器,故障表现为client发出SYN后无法收到server返回 的SYN+ACK,推荐的解决方法是关闭tcp_tw_recycle,打开tcp_tw_reuse解决TIME-WAIT过多的问题。
我们将/proc/sys/net/ipv4/tcp_tw_recycle修改为0,drop情况就不发生了;
然后查看tw个数:
netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'

下面我们总结一下:
tcp_tw_recycle 设置为 1 会开启系统对 TIME_WAIT 状态的 socket 的快速回收。开启这个功能,系统就会存下 TCP 连接的时间戳,当同一个 IP 地址过来的包的时间戳小于缓存的时间戳,系统就直接丢包,“回收”这个 socket。这个选项同样需要开启 tcp_timestamp 才生效。
开启这个功能是有很大风险的,服务器端会根据同一个 IP 发送过来的包的时间戳来判断是否丢包,而时间戳是根据发包的客户端的系统时间得来的,如果服务端收到的包是同一出口 IP 而系统时间不一样的两个客户端的包,就有可能会丢包,可能出现的情况就是一个局域网内有的客户端能连接服务端,有的不能。具体原因是客户端处于NAT模式下,出口ip可能是同一个ip,不同客户端的发送的时间戳可能乱序,服务器会检查相同ip地址发送来过的包的时间戳是不是小于缓存的时间戳,如果不是,直接丢掉;
有可能drop package的情况:(服务器端tcp_tw_recycle和tcp_timestamp都开启)
1.lvs处于NAT模式(咱们是DR);
2.客户端处于NAT模式;
3.IDC处于NAT模式;有人对国内的节点做了一个可视化分析,发现有2.61%的概率出口存在NAT的这种情况;
在服务器上最好打开tcp_tw_reuse,并且关闭tcp_tw_recycle。
tcp_tw_reuse和tcp_tw_recycle区别:
1. tw_reuse,tw_recycle 必须在客户端和服务端timestamps 开启时才管用(默认打开)
2. tw_reuse 只对客户端起作用,开启后客户端在1s内回收
3. tw_recycle 对客户端和服务器同时起作用,开启后在 3.5*RTO 内回收,RTO 200ms~ 120s 具体时间视网络状况。内网状况比tw_reuse 稍快,公网尤其移动网络大多要比tw_reuse 慢,优点就是能够回收服务端的TIME_WAIT数量;

服务器syns to listen sockets drop导致创建socket失败的更多相关文章

  1. Windows Server 2016 服务器总是有暴力破解密码导致的审核失败

    最近看了一下公司服务器的日志,在安全里,总是有审核失败,特别烦人,尝试密码特别弱智,总是用Administrator做用户名,不停的变换密码,真的烦,用户里面根本就没有Administrator,早就 ...

  2. Linux SVN服务器的搭建配置及分支的创建与合并

    第一步:通过yum命令安装svnserve,命令如下: >yum -y install subversion 若需查看svn安装位置,可以用以下命令: >rpm -ql subversio ...

  3. Spring session(redis存储方式)监听导致创建大量redisMessageListenerContailner-X线程

    待解决的问题 Spring session(redis存储方式)监听导致创建大量redisMessageListenerContailner-X线程 解决办法 为spring session添加spr ...

  4. idea创建springboot工程,总出现响应超时问题,或者无法连接http://start.spring.io导致创建失败

    问题描述如下: idea创建springboot工程,总出现响应超时问题,或者无法连接http://start.spring.io导致创建失败 从我出现此类问题几次的解决方案 依照解决效率分为一下三种 ...

  5. C# Socket系列二 简单的创建 socket 通信

    看了系列一 我们开启了对socket tcp的监听状态,那么这一章我们来讲解怎么创建socket的通信代码 我新建一个类 TSocketBase public abstract class TSock ...

  6. SQLServer 2012异常问题(一)--故障转移群集+镜像环境导致作业执行失败

    原文:SQLServer 2012异常问题(一)--故障转移群集+镜像环境导致作业执行失败 先感谢一下我的同事们最先发现此问题,鸣谢:向飞.志刚.海云 最近在生产环境发现一个诡异的问题: 环境:WIN ...

  7. PHP创建socket服务

    PHP可以创建socket服务. 先熟悉几个php网络方面的函数,操作手册地址  http://php.net/manual/zh/ref.sockets.php 简单介绍下socket,它表示套接字 ...

  8. c# 创建socket连接辅助类

    using AD.SocketForm.Model; using NLog; using System; using System.Net; using System.Net.Sockets; nam ...

  9. c++ 创建 socket server

    下面一段代码是创建socket server的代码片段: 需要引用的库包括: #include <sys/types.h> #include <sys/socket.h> #i ...

随机推荐

  1. ZOJ Problem Set - 1003

    1.翻译参考 http://www.cnblogs.com/woodfish1988/archive/2006/11/10/556926.html 2.代码参考 http://www.cnblogs. ...

  2. Git centos 安装

    Git 安装 Centos 下安装 Git,默认在 CentOS 下,我们可以通过 yum 的方式来安装 Git root@ci‐node1 ~]# yum install git –y root@c ...

  3. Laravel从模型中图片的相对路径获取绝对路径

    在模型product.php中增加以下方法.数据库图片字段为image.存储的图片相对路径 public function getImageUrlAttribute() { // 如果 image 字 ...

  4. c语言中int long float double 等类型所占字节及输出表示(转)

    16位编译器 char :1个字节 char*(即指针变量): 2个字节 short int : 2个字节 int: 2个字节 unsigned int : 2个字节 float: 4个字节 doub ...

  5. hype-v上centos7部署高可用kubernetes集群实践

    概述 在上一篇中已经实践了 非高可用的bubernetes集群的实践 普通的k8s集群当work node 故障时是高可用的,但是master node故障时将会发生灾难,因为k8s api serv ...

  6. 使用Enablebuffering多次读取Asp Net Core 请求体

    使用Enablebuffering多次读取Asp Net Core 请求体 1 .Net Core 2.X时代 使用EnableRewind倒带 public IActionResult Index( ...

  7. 使用.netcore部署window服务完成过程(使用nssm,Topshelf)

    一,新建.netcore控制台应用程序.本文使用.netcore2.2版本,结构如下 二,negut引用Topshelf.Log4Net,Topshelf 三,代码如下:1>Program.cs ...

  8. 7 java 笔记

    1 方法是类或者对象行为特征的抽象,方法是类或对象最重要的组成部分 2 java里面方法的参数传递方式只有一种:值传递 值传递:就是将实际参数值的复制品传入方法内,而参数本身不会受到任何影响.(这是j ...

  9. Flutter-动画-原理篇

    一.动画关键类的源码分析 1.Animation Animation没有做什么与动画有关的事情,它只是记录了动画的“状态”.当前的“值”和一些注册回调接口的方法. abstract class Ani ...

  10. mybatis批量更新表setting parameters 错误

    mybatis中想用 foreach标签 批量update set表 下面是mapper.xml <update id="updateMonitorById" paramet ...