TCP最大连接数调优

news2024/11/25 21:34:43

文章目录

    • 1、单机最大TCP连接数
      • 1.1、如何标识一个TCP连接
      • 1.2、client最大tcp连接数
      • 1.3、server最大tcp连接数
        • 1.3.1、理论连接数
        • 1.3.2、实际连接数
      • 1.4、单台服务器支撑的最大TCP并发连接数
        • 1.4.1、进程限制句柄限制
          • 查看进程句柄数限制
          • 临时修改
          • 重启后失效的修改(不过我在CentOS 6.5下测试,重启后未发现失效)
          • 永久修改
        • 1.4.2、全局限制
    • 2、tcp内核参数调优
      • 2.1、查看`net.ipv4`参数
      • 2.2、推荐配置
      • 2.3、参数解释
        • 2.3.1、 建立连接阶段
        • 2.3.2、 数据传输阶段
        • 2.3.3、 断开连接阶段

1、单机最大TCP连接数

1.1、如何标识一个TCP连接

在确定最大连接数之前,先来看看系统如何标识一个tcp连接。系统用一个4四元组来唯一标识一个TCP连接:

  • local ip
  • local port
  • remote ip
  • remote port

1.2、client最大tcp连接数

client每次发起tcp连接请求时,通常会让系统选取一个空闲的本地端口(local port),该端口是独占的,不能和其他tcp连接共享。在操作系统中,端口号的的数据类型是unsigned short,所以端口号的范围只有0~65535,其中0-1024是预留端口号,不可使用,其他的端口都是可以使用的。也就是说,在链接发起端,受端口号的限制理论上最多可以创建64000左右链接。

那么有没有办法超过这个限制呢,答案是肯定的!

通过TCP标识的四元组可以看到,对于链接发起端,影响链接数的是本地ip和port,端口号受限于65535,已经没办法增加了。那我们可以增加本地ip来达到这个目的。一般情况下,服务器的一个网卡上只绑定了一个ip,对外通信都使用这个ip进行。其实网卡是支持一个绑定多个IP的(必须确保ip是有效的且未使用的)

ifconfig eth0:1 10.0.0.5

以上命令可以在eth0网卡上增加一个ip 10.0.0.5,服务器网卡每增加一个ip,就可以允许在这个ip上再创建65535左右的链接数。

最大的TCP链接数=所有有效ip排列组合的数量*端口数量64000

1.3、server最大tcp连接数

1.3.1、理论连接数

server通常固定在某个本地端口上监听,等待client的连接请求。不考虑地址重用(unix的SO_REUSEADDR选项)的情况下,即使server端有多个ip,本地监听端口也是独占的,因此server端tcp连接4元组中只有remote ip(也就是client ip)和remote port(客户端port)是可变的,因此最大tcp连接为客户端ip数×客户端port数,对IPV4,不考虑ip地址分类等因素,最大tcp连接数约为2的32次方(ip数)×2的16次方(port数),也就是server端单机最大tcp连接数约为2的48次方。

1.3.2、实际连接数

上面给出的是理论上的单机最大连接数,在实际环境中,受到机器资源、操作系统等的限制,特别是sever端,其最大并发tcp连接数远不能达到理论上限。在unix/linux下限制连接数的主要因素是内存和允许的文件描述符个数(每个tcp连接都要占用一定内存,每个socket就是一个文件描述符),另外1024以下的端口通常为保留端口。在默认2.6内核配置下,经过试验,每个socket占用内存在15~20k之间
影响一个socket占用内存的参数包括:

net.core.rmem_max=16777216
net.core.wmem_max=16777216
net.ipv4.tcp_rmem=4096 87380 16777216
net.ipv4.tcp_wmem=4096 65536 16777216
net.ipv4.tcp_mem=
grep skbuff /proc/slabinfo

1.4、单台服务器支撑的最大TCP并发连接数

在linux下编写网络服务器程序的朋友肯定都知道每一个tcp连接都要占一个文件描述符,一旦这个文件描述符使用完了,新的连接到来返回给我们的错误是“Socket/File:Can’t open so many files”。

1.4.1、进程限制句柄限制

查看进程句柄数限制
 ulimit -n

输出 1024,说明对于一个进程而言最多只能打开1024个文件,所以你要采用此默认配置最多也就可以并发上千个TCP连接。

临时修改
ulimit -n 1000000

这种临时修改只对当前登录用户目前的使用环境有效,系统重启或用户退出后就会失效。

重启后失效的修改(不过我在CentOS 6.5下测试,重启后未发现失效)

编辑 /etc/security/limits.conf 文件

root soft nofile 1000000
root hard nofile 1000000
* soft nofile 1000000
* hard nofile 1000000
永久修改

编辑/etc/rc.local,在其后添加如下内容

ulimit -SHn 1000000

1.4.2、全局限制

执行 cat /proc/sys/fs/file-nr 输出 9344 0 592026,分别为:1.已经分配的文件句柄数,2.已经分配但没有使用的文件句柄数,3.最大文件句柄数。但在kernel 2.6版本中第二项的值总为0,这并不是一个错误,它实际上意味着已经分配的文件描述符无一浪费的都已经被使用了 。

我们可以把这个数值改大些,用 root 权限修改 /etc/sysctl.conf 文件:

fs.file-max = 1000000
net.ipv4.ip_conntrack_max = 1000000
net.ipv4.netfilter.ip_conntrack_max = 1000000

执行命令生效

sysctl -p

2、tcp内核参数调优

2.1、查看net.ipv4参数

cat /proc/sys/net/ipv4/tcp_rmem

修改则修改文件/ect/sysctl.conf

Linux下查看tcp连接数及状态命令

netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'

2.2、推荐配置

net.ipv4.ip_local_port_range = 1024 65536
net.core.rmem_max=16777216 
net.core.wmem_max=16777216
net.ipv4.tcp_rmem=4096 87380 16777216
net.ipv4.tcp_wmem=4096 65536 16777216
net.ipv4.tcp_fin_timeout = 10
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_timestamps = 0
net.ipv4.tcp_window_scaling = 0
net.ipv4.tcp_sack = 0
net.core.netdev_max_backlog = 30000
net.ipv4.tcp_no_metrics_save=1
net.core.somaxconn = 262144
net.ipv4.tcp_syncookies = 0
net.ipv4.tcp_max_orphans = 262144
net.ipv4.tcp_max_syn_backlog = 262144
net.ipv4.tcp_synack_retries = 2
net.ipv4.tcp_syn_retries = 2

2.3、参数解释

tcp

2.3.1、 建立连接阶段

  • net.ipv4.tcp_syn_retries
    控制三次握手第一步客户端发送syn得不到服务端响应时重传syn的次数,如果是内网环境,中间链路少,网络稳定,服务端无响应很可能是服务端应用出了问题,重传多次的意义不大,还会加大服务端压力,可以调低重传次数,让客户端尽快去尝试连接其他服务端。

  • net.ipv4.tcp_syncookies
    开启SYN Cookies,默认开启,建议保持默认值,可以提升SYN Flood攻击的防护能力。

  • net.ipv4.tcp_synack_retries
    控制三次握手第二步服务端发送syn+ack得不到客户端响应时重传syn+ack的次数,如果是内网环境,中间链路少,网络稳定,客户端无响应很可能是客户端出了问题,重传多次的意义不大,可以调低重传次数。

  • net.ipv4.tcp_max_syn_backlog
    控制半连接队列大小,所谓半连接是指还没有完成TCP三次握手的连接。服务端收到了客户端的SYN包后,就会把这个连接放到半连接队列中,然后再向客户端发送SYN+ACK,为了应对新建连接数暴增的场景,建议调大,半连接队列溢出观察方法:netstat -s | grep “SYNs to LISTEN”

  • net.core.somaxconn
    全连接队列=min(somaxconn,backlog),所谓全连接,是指服务端已经收到客户端三次握手第三步的ACK,然后就会把这个连接放到全连接队列中,全连接队列中的连接还需要被 accept()系统调用取走,服务端应用才可以开始处理客户端的请求,建议适当调大,全连接队列溢出观察方法:netstat -s | grep “listen queue”

  • net.ipv4.tcp_abort_on_overflow
    当全连接队列满了之后,新的连接就会被丢弃掉。服务端在丢弃新连接时,默认行为是直接丢弃不去通知客户端,有的时候需要发送reset来通知客户端,这样客户端就不会再次重试,至于是否需要给客户端发送reset,是由tcp_abort_on_overflow参数控制,默认为0,即不发送reset给客户端,如非特殊需求,建议保持默认值。

  • net.ipv4.tcp_timestamps

    0关闭,1关闭

    tcp_timestamps的本质是记录数据包的发送时间。基本的步骤如下

    1. 发送方在发送数据时,将一个timestamp(表示发送时间)放在包里面
    2. 接收方在收到数据包后,在对应的ACK包中将收到的timestamp返回给发送方(echo back)
    3. 发送发收到ACK包后,用当前时刻now - ACK包中的timestamp就能得到准确的RTT。当然实际运用中要考虑到RTT的波动,因此有了后续的(Round-Trip Time Measurement)RTTM机制

2.3.2、 数据传输阶段

  • net.ipv4.tcp_wmem
    tcp发送缓冲区大小,包含min、default、max三个值,内核会控制发送缓冲区在min-max之间动态调整,可根据实际业务场景和服务器配置适当调大,如果设置了socket的SO_SNDBUF,动态调整功能失效,一般不建议设置。
  • net.core.wmem_max
    socket发送缓冲区的最大值,需要设置net.core.wmem_max的值大于等于 net.ipv4.tcp_wmem的max值。
  • net.ipv4.tcp_mem
    系统中所有tcp连接最多可消耗的内存,有三个值,当TCP总内存小于第1个值时,不需要内核进行自动调节,在第1和第2个值之间时,内核开始调节缓冲区的大小,大于第3个值时,内核不再为TCP分配新内存,此时无法新建连接,需要注意的是,三个值的单位都是内存页,也就是4KB。
  • net.ipv4.tcp_rmem
    tcp接收缓冲区大小,包含min、default、max三个值,内核会控制接收缓冲区在min-max之间动态调整,可根据实际业务场景和服务器配置适当调大,如果设置了socket的 SO_RECVBUF或者关闭了net.ipv4.tcp_moderate_rcvbuf,动态调整功能失效。
  • net.core.rmem_max
    socket接收缓冲区的最大值,需要设置net.core.rmem_max的值大于等于net.ipv4.tcp_rmem 的max值。
  • net.ipv4.tcp_moderate_rcvbuf
    接收缓冲区动态调整功能,默认打开,建议保持默认配置。
  • net.ipv4.tcp_window_scaling
    扩充滑动窗口,tcp头部中,窗口字段只有2个字节,最多只能达到2的16次方,即65535字节大小的窗口,打开此开关可以扩充窗口大小,默认打开,建议保持默认配置。
  • net.ipv4.tcp_keepalive_probes
    keepalive探测失败后通知应用前的重试次数,建议适当调低。
  • net.ipv4.tcp_keepalive_intvl
    keepalive探测包的发送间隔时间,建议适当调低。
  • net.ipv4.tcp_keepalive_time
    最后一次数据包到keepalive探测包的间隔时间,建议适当调低。
  • net.ipv4.tcp_available_congestion_control
    查看内核支持的拥塞控制算法。
  • net.ipv4.tcp_congestion_control
    配置拥塞控制算法,默认cubic,内核4.9版本后支持BBR,弱网络条件下建议配置成BBR。

2.3.3、 断开连接阶段

  • net.ipv4.tcp_fin_timeout
    是从Fin_WAIT_2到TIME_WAIT的超时时间,长时间收不到对端FIN包,大概率是对端机器有问题,不能及时调用close()关闭连接,建议调低,避免等待时间太长,资源开销过大。
  • net.ipv4.tcp_max_tw_buckets
    系统TIME_WAIT连接的最大数量,根据实际业务需要调整,超过最大值后dmesg会有报错TCP: time wait bucket table overflow。
  • net.ipv4.tcp_tw_reuse
    允许TIME_WAIT状态的连接占用的端口用到新建连接中,客户端可开启。
  • net.ipv4.tcp_tw_recycle
    开启后,TIME_WAIT状态的连接无需等待2MSL时间就可用于新建连接,在NAT环境下,开启tcp_tw_recycle参数会触发PAWS机制导致丢包,建议不开启,事实上,内核在4.1版本后就把这个参数删除了。

参考博客

TCP单机最大连接数优化

Linux系统TCP内核参数优化总结

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/114285.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

IIC 通信协议 (二)

目录 引言 子模块设计 思路 单字节 IIC 发送模块 思路 Verilog 源码 多字节发送控制模块 思路 Verilog 源码 仿真 思路 test bench 仿真结果 参考声明 引言 本篇博文承接前文,继续做 IIC 通信协议 FPGA实现相关的内容。用Verilog 编写一个 IIC 通信控…

【折腾服务器 1】妖板 Intel N5105 + i226 主板安装 ESXi 7.0 教程

Catch Up 今年年初,开始搭建个人服务器,用的是一台 Dell 7010 SFF 主机,在上面部署了一些应用,例如:Calibre ,Blogs ,Minecraft Server 等。使用的是 frp 做的网络代理,有一台服务器…

cubeIDE开发, UART的CubeMX及HAL库实现原理及底层分析

一、UART通信协议 UART通用异步收发器(Universal Asynchronous Receiver and Transmitter)是STM32 上常用的串行通信外设,可以灵活地与外部设备进行全双工数据交换,需要注意区别: 【1】USART-通用同步异步收发器(Universal Synchronous Async…

<Linux线程互斥与死锁>——《Linux》

目录 1. Linux线程互斥 进程线程间的互斥相关背景概念 互斥量mutex 互斥量的接口 初始化互斥量 销毁互斥量 互斥量加锁和解锁 互斥量实现原理探究 可重入VS线程安全 概念 常见的线程不安全的情况 常见的线程安全的情况 常见不可重入的情况 常见可重入的情况 可重…

K. Lonely Numbers(线性筛 + 差分)

Problem - 1423K - Codeforces 在数字世界中,如果两个不同的数字有很多共同点,而且每个数字都有独特的好处,那么它们就是朋友。 更确切地说,如果gcd(a,b), agcd(a,b), bgcd(a,b)能组成一个三角形的边,那么两个不同的数…

六、应用层(四)电子邮件

目录 4.1 电子邮件系统的组成结构 4.2 简单邮件传输协议(SMTP) 4.3 电子邮件格式 4.4 多用途网际邮件扩充(MIME) 4.5 邮局协议(POP3)和因特网报文存取协议(IMAP) 4.6 基…

小黑下午第一场面试被鸽,一切遇见随缘,继续第二场的leetcode之旅:654. 最大二叉树

小黑代码 # Definition for a binary tree node. # class TreeNode: # def __init__(self, val0, leftNone, rightNone): # self.val val # self.left left # self.right right class Solution:def constructMaximumBinaryTree(self, nums: Li…

SAP UI5 应用里 FlexBox 控件的设计原理

sap.m.FlexBox 控件为 flexible box layout 构建容器。VBox 控件为垂直的框布局(vertical flexible box layout)构建容器。 VBox 是一种使用的控件,因为它只是一个定制化的 FlexBox 控件。 VBox 包含 items 聚合,从 FlexBox 继承而来。 HBox 控件为水平…

字符串函数

注意:MySQL中,字符串的位置是从1开始的。 ASCII(S) 返回字符串S中的第一个字符的ASCII码值. 与第一个字符后面的其他字符无关。 SELECTASCII(Abcdfsf) FROM DUAL;CHAR_LENGTH(s) 返回字符串s的字符数。作用与CHARACTER_LENGTH(s)相同。 SELECTCHAR_LEN…

生信基础知识

1.生物数据库分类 (1)核酸数据库(2)蛋白质数据库(3)专用数据库 核酸数据库分为一级核酸数据库和二级核酸数据库 蛋白质数据库分为一级蛋白质数据库和二级蛋白质数据库 一级蛋白质数据库又分为蛋白质序列…

【Redis】应用问题解决

一、缓存击穿 1、什么叫缓存击穿 系统中某个查询次数很多的热点key,在某个时刻过期,而此时又正好有大量并发请求查询这个key,但是缓存的重建还没有完成,这样,就会有大量请求涌向后端数据库,使得其压力骤增…

爱了,阿里P9开源分享内部Java核心开发手册(2022版)覆盖P5到P8

这个世界唯一不变的就是变化, IT圈子不外如是。计算机领域一直在改变,从基础框架到计算设备,还有几乎每天都涌现出的新技术。因此,作为一名程序开发人员,我们要通过不断的学习来提高自己的技能。 所以持续学习的脚步自…

基于C++11实现的阻塞队列(BlockQueue)

思路: 生产者消费者模型如图,多个生产者线程和多个消费者线程共享同一固定大小的缓冲区,它们的生产和消费符合以下规则: 生产者不会在缓冲区满的时候继续向缓冲区放入数据,而消费者也不会在缓冲区空的时候&#xff0c…

AQS源码解读

retrantlock: A、B、C3个线程,假设A线程lock()时候拿到了锁,state被A设置成了1。 static final class NonfairSync extends Sync {private static final long serialVersionUID 7316153563782823691L;/*** Performs lock. Try immediate b…

喜欢写笔记的博主为什么要使用猿如意?

🔥🔥🔥猿如意🔥🔥🔥 喜欢写笔记的博主为什么要使用猿如意? markdown笔记 测 评 分 享 猿如意实战测评猿如意传送门什么是猿如意?猿如意使用感受markdown笔记实战测评总结猿如意传…

数据结构---红包分配算法

红包分配算法错误解法二倍均值法JAVA实现线段切割法确定每一条子线段的长度JAVA实现问题如下: 所有人抢到的金额之和要等于红包金额,不能多也不能少。每个人至少抢到1分钱。要保证红包拆分的金额尽可能分布均衡,不要出现两极分化太严重的情况…

【C函数】函数详解

函数前言一、函数是什么二、C语言中函数的分类(一)库函数1.printf类2.strcpy类3.math类4.概念5.小知识6.总结(二)自定义函数1.概念2.函数的组成3.例子1(求出两个数中的最大值)4.例子2(交换两个整…

mac释放“其他”内存空间的解决方法

官方解释Mac设备储存空间中的“其他”数据包含这不可移除的移动资源,例如,Siri 语音、字体、词典、不可移除的日志和缓存、聚焦索引以及系统数据如钥匙串和 CloudKit 数据库、系统无法删除缓存的文件等之外,还包含了一些无法识别的文件。当“…

ROS2 基础概念 节点

ROS2 基础概念 节点1. Nodes2. 重映射3. 环境设置3.1. ROS_DOMAIN_ID3.2. ROS_LOCALHOST_ONLY1. Nodes 每个节点应负责单个模块用途(例如,一个节点用于控制车轮电机,一个用于控制激光测距仪等) 可以通过话题、服务、操作或参数向…

C++-----模板

举个例子,如果要你交换两个数值,你会怎么做呢? ————你肯定会说,那就写一个Swap交换函数吧! 没错!Swap函数确实可以实现交换,但如果我想让你同时进行不能类型的数值呢,比如floa…