在一次测试执行过程中,发现服务器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. vs2017安装过程中下载不动的一种情况

    第一种可能:微软可能有不同的下载地址,某些地址下载速度快,某些慢.这种情况下,禁用连接,再启用.有几率速度飞速上升. 第二种可能:由于总所周知的原因,连接不了Google.但是如果需要下载Androi ...

  2. windows下安装和配置SNMP

    window snmp服务开启及测试 转自:https://blog.csdn.net/qq_33314107/article/details/80031446 一 安装 二 开启服务 Linux下安 ...

  3. oracle——学习之路(oracle内置函数)

    oracle与很多内置函数,主要分为单行函数与集合函数. 首先要提一下dual表,它oracle的一个表,没有什么实质的东西,不能删除它,否则会造成Oracle无法启动等问题,他有很大用处,可以利用它 ...

  4. Spring IOC的底层实现原理

     PS:模块之间的相互依赖叫做耦合 传统方式的开发 UserService us=new UserService(); || v 面向接口编程 UserService us=new UserServi ...

  5. hashmap 为什么初始化容量是2的幂次方

    个人理解 做下记录,不正确的地方望不吝赐教 这是hashmap初始化容量时候 对容量大小做的处理,保证初始化容量为最近的2的幂次方(JDK1.8) static final int tableSize ...

  6. SpringBoot起飞系列-自定义starter(十)

    一.前言 到现在,我们可以看出来,如果我们想用一些功能,基本上都是通过添加spring-boot-starter的方式来使用的,因为各种各样的功能都被封装成了starter,然后把相关服务注入到容器中 ...

  7. 两个链表的第一个公共结点——牛客offer

    题目描述: 输入两个链表,找出它们的第一个公共结点. 题目分析: 只是数据域相同不是公共节点.公共结点代表该节点在两个链表中的数据域和指针域都是相同的,这意味着从该公共节点开始,后面的结点都是两个链表 ...

  8. how to Simply Singleton Navigate the deceptively simple Singleton pattern---reference

    http://www.javaworld.com/article/2073352/core-java/simply-singleton.html JAVA DESIGN PATTERNS By Dav ...

  9. 深入理解计算机系统 第十二章 并发编程 part1 第二遍

    三种构造并发程序的方法及其优缺点 1.进程 用这种方法,每个逻辑控制流都是一个进程,由内核来调度和维护.因为进程有独立的虚拟地址空间,想要和其他流通信,控制流必须使用某种显式的进程间通信机制. 优点: ...

  10. javascript——加强for循环 和Java中的加强for循环的区别

    javascript中获得的是下标      in var id=[4,5,6]; for (var index in id) { console.log(id[index]); } Java中获得的 ...