作为一个DAU上百万或千万的站点,不仅仅需要做好网站应用程序、数据库的优化,还应从TCP/IP协议层去进行相关的优化;

在我的工作中,曾使用到了以下的几种基本的优化方式:

增大最大连接数

在Linux系统里,所有的网络连接都是通过文件描述符(file descriptor)来实现的,因此一个进程所能打开的文件描述符数量决定了这个进程所能创建的最大连接数;

由于Linux系统对进程的文件描述符数量限制是1024;对于大规模的分布式站点来说,这样的连接数限制是远远不够的,建议适当增大该值:

首先在Linux中查询文件描述符数量限制:

ulimit -n

默认情况下会显示1024,然后编辑 /etc/security/limits.conf 文件,加入下面两句:

* soft nofile 10000
* hard nofile 10000

重启系统之后,再使用ulimit -n查看得到的结果就是10000了。

减少TCP断开连接时的TIME_WAIT时间

在TCP断开连接的四次挥手结束阶段,连接断开的发起方会进入到TIME_WAIT状态。

在你的Linux服务器上执行如下命令:

netstat -n | grep 'tcp'

在输出的最后一列你会可能看到值为TIME_WAIT的行,这代表该TCP连接已经进入了TIME_WAIT状态,进入到该状态的连接是不会释放的,默认情况下需要等待2MSL的时间(1MSL大致等于TTL衰减为0的时间,在RFC793中规定为2分钟)。因此在断开连接之后的2个2分钟时间段内,连接会一直保持为TIME_WAIT并持有文件句柄不释放,在大型站点中会导致服务器连接很快背耗尽,实际上对于现在的网速,等待2MSL(4分钟)的时间过长,建议将该时间设置为30秒即可:

  • 编辑 /etc/sysctl.conf 文件,添加下面的行:

    net.ipv4.tcp_fin_timeout = 30
    net.ipv4.tcp_tw_recycle = 1
    net.ipv4.tcp_tw_reuse = 1
  • 执行 sudo /sbin/sysctl -p 命令,使修改立即生效。

禁用延迟确认

在TCP协议中,延迟确认(Delayed ACK)是一把双刃剑;在绝大多数情况下,延迟确认在服务器收到数据包之后,不需要对每个数据包理解响应ACK,而是将多个数据包的ACK响应合并为一个,从而提高了网络传输的性能并降低了网络的负载,然而在某些条件下,也会带来负面影响;

影响主要有两方面:

  • TCP协议在在RFC 896中引入了Nagle算法,该算法主要用于解决在TCP传输过程中的小包问题(small-packet problem),大概意思是发送方在发送少量的数据时,并非立刻发送,而是在需要发送的数据量累计到一定阈值(MSS:Maximum Segment Size)时才开始发送;维基百科给了一个形象的解释:

    if there is new data to send then
    if the window size ≥ MSS and available data is ≥ MSS then
    send complete MSS segment now
    else
    if there is unconfirmed data still in the pipe then
    enqueue data in the buffer until an acknowledge is received
    else
    send data immediately
    end if
    end if
    end if

    注意上述中的“an acknowledge is received”,也就是说如果一个发送方正在使用Nagle算法来发送小规模数据,这些数据可能迟迟不会被发送出去,直到接收方响应了一个ACK,而接收方因为延迟确认的缘故,只会在延迟确认超时时间达到之后才会发送ACK给发送方;从而导致了发送数据的时间被拉长。

  • 在丢包严重的网络环境中,延迟确认会使得传输的性能变得更为低下;
    例如发送方需要发送序列号为1、2、3、4、5、6、7、8、9的九个包到接收方,如果1、2、3三个包都发送成功了,第4、5、6、7四个包发送失败,接收方在收到第8个包时,返回一个ACK seq=4的包给发送方,发送方重发第4个包,但接收方由于延迟确认的原因不会在收到第4个包时立即发送ACK seq=5的包,而是要等到延迟确认超时之后才响应,接下来发送方会重发第5个包,接收方又要等到延迟确认超时之后再响应ACK seq=6......以此类推,这会使得原本不太好的网络传输雪上加霜。

正如上面所述,延迟确认是一把双刃剑,在大多数环境下具有促进作用,因此关闭与否识情况而定,在某些情况下可以适当减小延迟确认超时时间。

启用SACK

上面谈到延迟确认带来的两方面影响中,在第二个方面里提到了丢包之后发送方需要等到接收方响应ACK之后,才会重发丢失的包;如接收到ACK 4时才重发第4个包,而后接收到ACK 5时重发第5个包,接收到ACK 6时重发第6个包......,如果丢包数量较大时,这个步骤会显得格外的绵长。

SACK(Selective Acknowledgment)解决了这个问题,它使得接收方在收到第8个包之后响应的ACK seq=4这个包里,会把它已经收到的包序列号也写入(这里是8,代表第8个包已经收到);接收方在收到这个ACK包之后,就可以知道第1、2、3、8四个包发送成功,从而推断出需要重发第4、5、6、7这四个包。

SACK是双方面的,需要发送方和接收方同时启用才能生效。

使用QUIC协议

TCP作为一个面向连接的安全可靠的传输协议,它也有很多天然的缺陷,例如上面谈到的失败重发问题,以及其他诸如建立/断开连接需要三次握手四次挥手的问题、发送包时的队头阻塞问题,因此传输的性能并不够好;Google提出了基于UDP协议的上层QUIC协议;它在建立/断开连接时无需三次握手四次挥手,它采用RAID5算法缓解了TCP协议中丢包时的失败重传问题。

现在Google的Chrome浏览器、Microsoft的Edge浏览器都支持Quic协议,同时即将到来的HTTP/3也是建立在QUIC协议之上(RFC 9000)。

很多流行的Web服务器如腾讯的Caddy内置了对QUIC协议的支持,Nginx也推出了官方支持QUIC和HTTP/3的预览版Nginx-quic。

大型站点TCP/IP协议优化的更多相关文章

  1. TCP/IP协议(一)网络基础知识

    参考书籍为<图解tcp/ip>-第五版.这篇随笔,主要内容还是TCP/IP所必备的基础知识,包括计算机与网络发展的历史及标准化过程(简述).OSI参考模型.网络概念的本质.网络构建的设备等 ...

  2. TCP/IP协议原理与应用笔记18:构成子网和超网

    1. 引言: (1)类别IP编址(Classful IP)的缺陷 • 固定的3种IP网络规模      C类地址:少于255台主机的网络      B类地址:介于255~65535台主机的网络     ...

  3. TCP/IP协议原理学习笔记

    昨天学习了杨宁老师的TCP/IP协议原理第一讲和第二讲,主要介绍了OSI模型,整理如下: OSI是open system innerconnection的简称,即开放式系统互联参考模型,它把网络协议从 ...

  4. TCP/IP协议原理与应用笔记10:TCP/IP协议族

    1. 协议族视图如下:(这里我们列举重要的,并不是所有的) (1)网络接入层(数据链路层 和 物理层): 通过接入的物理网络的 功能 和 覆盖范围 进行分析划分为: •LANs :局域网(Local ...

  5. ISO/OSI网络体系结构和TCP/IP协议模型

    1. ISO/OSI的参考模型共有7层,由低层至高层分别为:物理层.数据链路层.网络层.传输层.会话层.表示层.     应用层.各层功能分别为: (1)物理层          提供建立.维护和拆除 ...

  6. TCP/IP协议头部结构体(网摘小结)(转)

    源:TCP/IP协议头部结构体(网摘小结) TCP/IP协议头部结构体(转) 网络协议结构体定义 // i386 is little_endian. #ifndef LITTLE_ENDIAN #de ...

  7. 网络基础二 tcp/ip协议簇 端口 三次握手 四次挥手 11种状态集

    第1章 概念介绍 1.1 VLAN 1.1.1 什么是VLAN VLAN(Virtual LAN),翻译成中文是“虚拟局域网”.LAN可以是由少数几台家用计算机构成的网络,也可以是数以百计的计算机构成 ...

  8. 从网卡发送数据再谈TCP/IP协议—网络传输速度计算-网卡构造

    在<在深谈TCP/IP三步握手&四步挥手原理及衍生问题—长文解剖IP>里面提到 单个TCP包每次打包1448字节的数据进行发送(以太网Ethernet最大的数据帧是1518字节,以 ...

  9. 转:TCP/IP协议(一)网络基础知识

    转载:http://www.cnblogs.com/imyalost/p/6086808.html 参考书籍为<图解tcp/ip>-第五版.这篇随笔,主要内容还是TCP/IP所必备的基础知 ...

随机推荐

  1. MH/T4029.3 IFPL报文解析

    MH/T4029.3是民航业用来规定飞行计划相关数据交互的规范,今天我们先来解析下其中I类的IFPL报文. 我们先来看看IFPL报文长啥样. ZCZC -TITLE IFPL -FILTIM 0109 ...

  2. Asp.NetCore3.1开源项目升级为.Net6.0

    概述 自从.Net6.0出来后,一直想之前开发的项目升级.Net6.0,有时想想毕竟中间还跨了个5.0版本,升级起来不知道坑大不大,最近抽时间对升级的方案做了些研究,然后将代码升级为.Net6.0.本 ...

  3. uni-app + Cloudbase——uni-app 项目中如何使用腾讯云开发后端服务

    1 基本介绍 uni-app 是一个基于 Vue.js 的跨端开发框架,一套代码可以发布到 App.小程序.Web 等不同平台 腾讯云开发平台 Cloudbase 提供的 @cloudbase/js- ...

  4. .net 程序通过 crontab 无法启动,手动执行脚本可以启动

    一.问题描述 .net 网关程序需要设置定时重启,按照日常操作先把正在运行的 PID kill 掉后,再执行启动服务. 把脚本放到 crontab 计划任务上,可以把服务 PID kill 掉,但无法 ...

  5. centos7使用docker安装es(elasticsearch)

    1.安装docker依赖(已安装可以不用安装) yum install -y docker 2.搜索镜像 docker search elasticsearch 如果出现以下报错 Cannot con ...

  6. cmake之譬判断cmake的版本

    note 有时候,可能使用的cmake语法 与cmake的版本有关系, 比如modern cmake. 这时候我们可以在 CMAKELISTS.TXT中 判断 cmakeLists.txt 代码 if ...

  7. cmake之Visual studio无法显示头文件

    本文演示cmake版本:3.18 1. 问题 使用cmake创建的Visual Studio 项目都没有显示头文件, 比如: 可以清楚的看见,项目lib_pipe没有显示头文件 2. 配置CMakeL ...

  8. 【LeetCode】345. Reverse Vowels of a String 解题报告(Java & Python & C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 使用栈 双指针 日期 [LeetCode] 题目地址 ...

  9. 【LeetCode】421. Maximum XOR of Two Numbers in an Array 解题报告(Python & C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 解题方法 依次遍历每一位 前缀树 日期 题目地址:https://lee ...

  10. POJ 1986:Distance Queries

    Distance Queries Time Limit: 2000MS   Memory Limit: 30000K Total Submissions: 18139   Accepted: 6248 ...