连接数

更新时间:2023-03-10 10:31:22 阅读: 评论:0

儿童弹钢琴-廷臣

连接数
2023年3月10日发(作者:千湖山)

服务器最⼤TCP连接数及调优汇总

启动线程数:

启动线程数=【任务执⾏时间/(任务执⾏时间-IO等待时间)】*CPU内核数

最佳启动线程数和CPU内核数量成正⽐,和IO阻塞时间成反⽐。如果任务都是CPU计算型任务,那么线程数最多不超过CPU内核数,因为

启动再多线程,CPU也来不及调度;相反如果是任务需要等待磁盘操作,⽹络响应,那么多启动线程有助于提⾼任务并发度,提⾼系统吞吐

能⼒,改善系统性能。

单机最⼤tcp连接数

⽹络编程

在tcp应⽤中,rver事先在某个固定端⼝监听,client主动发起连接,经过三路握⼿后建⽴tcp连接。那么对单机,其最⼤并发tcp连接数是多

少?

如何标识⼀个TCP连接

在确定最⼤连接数之前,先来看看系统如何标识⼀个tcp连接。系统⽤⼀个4四元组来唯⼀标识⼀个TCP连接:{localip,localport,remote

ip,remoteport}。

client最⼤tcp连接数

client每次发起tcp连接请求时,除⾮绑定端⼝,通常会让系统选取⼀个空闲的本地端⼝(localport),该端⼝是独占的,不能和其他tcp连接

共享。tcp端⼝的数据类型是unsignedshort,因此本地端⼝个数最⼤只有65536,端⼝0有特殊含义,不能使⽤,这样可⽤端⼝最多只有

65535,所以在全部作为client端的情况下,最⼤tcp连接数为65535,这些连接可以连到不同的rverip。

rver最⼤tcp连接数

rver通常固定在某个本地端⼝上监听,等待client的连接请求。不考虑地址重⽤(unix的SO_REUSEADDR选项)的情况下,即使rver端

有多个ip,本地监听端⼝也是独占的,因此rver端tcp连接4元组中只有remoteip(也就是clientip)和remoteport(客户端port)是可变

的,因此最⼤tcp连接为客户端ip数×客户端port数,对IPV4,不考虑ip地址分类等因素,最⼤tcp连接数约为2的32次⽅(ip数)×2的16次⽅

(port数),也就是rver端单机最⼤tcp连接数约为2的48次⽅。

实际的tcp连接数

上⾯给出的是理论上的单机最⼤连接数,在实际环境中,受到机器资源、操作系统等的限制,特别是ver端,其最⼤并发tcp连接数远不能

达到理论上限。在unix/linux下限制连接数的主要因素是内存和允许的⽂件描述符个数(每个tcp连接都要占⽤⼀定内存,每个socket就是⼀

个⽂件描述符),另外1024以下的端⼝通常为保留端⼝。在默认2.6内核配置下,经过试验,每个socket占⽤内存在15~20k之间。

影响⼀个socket占⽤内存的参数包括:

rmem_max

wmem_max

tcp_rmem

tcp_wmem

tcp_mem

grepskbuff/proc/slabinfo

对rver端,通过增加内存、修改最⼤⽂件描述符个数等参数,单机最⼤并发TCP连接数超过10万是没问题的,国外UrbanAirship公司在

产品环境中已做到50万并发。在实际应⽤中,对⼤规模⽹络应⽤,还需要考虑C10K问题。

原⽂:

曾⼏何时我们还在寻求⽹络编程中问题的解决⽅案,但是现在从硬件和操作系统⽀持来看单台服务器⽀持上万并发连接已经没有多少挑战性

了。

我们先假设单台服务器最多只能⽀持万级并发连接,其实对绝⼤多数应⽤来说已经远远⾜够了,但是对于⼀些拥有很⼤⽤户基数的互联⽹公

司,往往⾯临的并发连接数是百万,千万,甚⾄腾讯的上亿(注:QQ默认⽤的UDP协议)。虽然现在的集群,分布式技术可以为我们将并

发负载分担在多台服务器上,那我们只需要扩展出数⼗台电脑就可以解决问题,但是我们更希望能更⼤的挖掘单台服务器的资源,先努⼒垂

直扩展,再进⾏⽔平扩展,这样可以有效的节省服务器相关的开⽀(硬件资源,机房,运维,电⼒其实也是⼀笔不⼩的开⽀)。

那么到底⼀台服务器能够⽀持多少TCP并发连接呢?

常识⼀:⽂件句柄限制

在linux下编写⽹络服务器程序的朋友肯定都知道每⼀个tcp连接都要占⼀个⽂件描述符,⼀旦这个⽂件描述符使⽤完了,新的连接到来返回

给我们的错误是“Socket/File:Can'topensomanyfiles”。

这时你需要明⽩操作系统对可以打开的最⼤⽂件数的限制。

进程限制

执⾏ulimit-n输出1024,说明对于⼀个进程⽽⾔最多只能打开1024个⽂件,所以你要采⽤此默认配置最多也就可以并发上千个

TCP连接。

临时修改:ulimit-n1000000,但是这种临时修改只对当前登录⽤户⽬前的使⽤环境有效,系统重启或⽤户退出后就会失效。

重启后失效的修改(不过我在CentOS6.5下测试,重启后未发现失效):编辑/etc/curity/⽂件,修改后内容为

*softnofile1000000

*hardnofile1000000

永久修改:编辑/etc/,在其后添加如下内容

ulimit-SHn1000000

全局限制

执⾏cat/proc/sys/fs/file-nr输出93440592026,分别为:1.已经分配的⽂件句柄数,2.已经分配但没有使⽤的⽂件句柄数,3.最⼤

⽂件句柄数。但在kernel2.6版本中第⼆项的值总为0,这并不是⼀个错误,它实际上意味着已经分配的⽂件描述符⽆⼀浪费的都

已经被使⽤了。

我们可以把这个数值改⼤些,⽤root权限修改/etc/⽂件:

-max=1000000

_conntrack_max=1000000

_conntrack_max=1000000

常识⼆:端⼝号范围限制?

操作系统上端⼝号1024以下是系统保留的,从1024-65535是⽤户使⽤的。由于每个TCP连接都要占⼀个端⼝号,所以我们最多可以有

60000多个并发连接。我想有这种错误思路朋友不在少数吧?(其中我过去就⼀直这么认为)

我们来分析⼀下吧

如何标识⼀个TCP连接:系统⽤⼀个4四元组来唯⼀标识⼀个TCP连接:{localip,localport,remoteip,remoteport}。好吧,我们拿出

《UNIX⽹络编程:卷⼀》第四章中对accept的讲解来看看概念性的东西,第⼆个参数cliaddr代表了客户端的ip地址和端⼝号。⽽我们

作为服务端实际只使⽤了bind时这⼀个端⼝,说明端⼝号65535并不是并发量的限制。

rver最⼤tcp连接数:rver通常固定在某个本地端⼝上监听,等待client的连接请求。不考虑地址重⽤(unix的SO_REUSEADDR选

项)的情况下,即使rver端有多个ip,本地监听端⼝也是独占的,因此rver端tcp连接4元组中只有remoteip(也就是clientip)和

remoteport(客户端port)是可变的,因此最⼤tcp连接为客户端ip数×客户端port数,对IPV4,不考虑ip地址分类等因素,最⼤tcp连接

数约为2的32次⽅(ip数)×2的16次⽅(port数),也就是rver端单机最⼤tcp连接数约为2的48次⽅。

总结

TCP/IP协议规定的,只⽤了2个字节表⽰端⼝号。容易让⼈误解为1个rver只允许连接65535个Client。

typedefstruct_NETWORK_ADDRESS_IP

{

USHORTsin_port;//0~65535

ULONGin_addr;

UCHARsin_zero[8];

}NETWORK_ADDRESS_IP,*PNETWORK_ADDRESS_IP;

(1)其实65535这个数字,只是决定了服务器端最多可以拥有65535个Bind的Socket。也就是说,最多可以开65535个服务器进程,但是你要

知道这个能够连接客户端的数量没有任何关系,Accept过来的Socket是不需要Bind任何IP地址的,也没有端⼝占⽤这⼀说。作为Server端的

Socket本⾝只负责监听和接受连接操作。

(2)TCP协议⾥⾯是⽤[源IP+源Port+⽬的IP+⽬的Port]来区别两个不同连接,所以连⼊和连出是两个不同的概念。连出Connect就不错了,需要

⽣成随机端⼝,这个是有限的连⼊的话,因SOCKET的分配受内存分页限制,⽽连接受限制(WINDOWS)。

(3)所以,千万不要误以为1个rver只允许连接65535个Client。记住,TCP连出受端⼝限制,连⼊仅受内存限制。

例如rver,IP:192.168.16.254,Port:8009

Client1:IP:192.168.16.1,Port:2378

Client2:IP:192.168.16.2,Port:2378

Client1和Client2虽然Port相同,但是IP不同,所以是不同的连接。

(4)想让1个rver并发⾼效得连接⼏万个Client,需要使⽤IOCP“完成端⼝(CompletionPort)”的技术。

上⾯给出的结论都是理论上的单机TCP并发连接数,实际上单机并发连接数肯定要受硬件资源(内存)、⽹络资源(带宽)的限制,⾄少对

我们的需求现在可以做到数⼗万级的并发了,你的呢?

常见设置

1、修改⽤户进程可打开⽂件数限制

在Linux平台上,⽆论编写客户端程序还是服务端程序,在进⾏⾼并发TCP连接处理时,最⾼的并发数量都要受到系统对⽤户单⼀进程同时

可打开⽂件数量的限制(这是因为系统为每个TCP连接都要创建⼀个socket句柄,每个socket句柄同时也是⼀个⽂件句柄)。可使⽤ulimit命令

查看系统允许当前⽤户进程打开的⽂件数限制:

[speng@as4~]$ulimit-n

1024

这表⽰当前⽤户的每个进程最多允许同时打开1024个⽂件,这1024个⽂件中还得除去每个进程必然打开的标准输⼊,标准输出,标准错

误,服务器监听socket,进程间通讯的unix域socket等⽂件,那么剩下的可⽤于客户端socket连接的⽂件数就只有⼤概1024-10=1014个左

右。也就是说缺省情况下,基于Linux的通讯程序最多允许同时1014个TCP并发连接。

对于想⽀持更⾼数量的TCP并发连接的通讯处理程序,就必须修改Linux对当前⽤户的进程同时打开的⽂件数量的软限制(softlimit)和硬限制

(hardlimit)。其中软限制是指Linux在当前系统能够承受的范围内进⼀步限制⽤户同时打开的⽂件数;硬限制则是根据系统硬件资源状况(主要

是系统内存)计算出来的系统最多可同时打开的⽂件数量。通常软限制⼩于或等于硬限制。

修改上述限制的最简单的办法就是使⽤ulimit命令:

[speng@as4~]$ulimit-n

上述命令中,在中指定要设置的单⼀进程允许打开的最⼤⽂件数。如果系统回显类似于“Operationnotpermitted”之类的话,说明上述限制修

改失败,实际上是因为在中指定的数值超过了Linux系统对该⽤户打开⽂件数的软限制或硬限制。因此,就需要修改Linux系统对⽤户的关于

打开⽂件数的软限制和硬限制。

第⼀步,修改/etc/curity/⽂件,在⽂件中添加如下⾏:

...

#Endoffile

spengsoftnofile10240

spenghardnofile10240

rootsoftnofile65535

roothardnofile65535

*softnofile65535

*hardnofile65535

[test@iZwz9e1dh1nweaex8ob5b7Zconfig]$

其中speng指定了要修改哪个⽤户的打开⽂件数限制,可⽤’*'号表⽰修改所有⽤户的限制;soft或hard指定要修改软限制还是硬限制;10240

则指定了想要修改的新的限制值,即最⼤打开⽂件数(请注意软限制值要⼩于或等于硬限制)。修改完后保存⽂件。

第⼆步,修改/etc/pam.d/login⽂件,在⽂件中添加如下⾏:

ssionrequired/lib/curity/pam_

这是告诉Linux在⽤户完成系统登录后,应该调⽤pam_模块来设置系统对该⽤户可使⽤的各种资源数量的最⼤限制(包括⽤户可打开

的最⼤⽂件数限制),⽽pam_模块就会从/etc/curity/⽂件中读取配置来设置这些限制值。修改完后保存此⽂件。

第三步,查看Linux系统级的最⼤打开⽂件数限制,使⽤如下命令:

[speng@as4~]$cat/proc/sys/fs/file-max

12158

这表明这台Linux系统最多允许同时打开(即包含所有⽤户打开⽂件数总和)12158个⽂件,是Linux系统级硬限制,所有⽤户级的打开⽂件数

限制都不应超过这个数值。通常这个系统级硬限制是Linux系统在启动时根据系统硬件资源状况计算出来的最佳的最⼤同时打开⽂件数限

制,如果没有特殊需要,不应该修改此限制,除⾮想为⽤户级打开⽂件数限制设置超过此限制的值。修改此硬限制的⽅法是修改/etc/

脚本,在脚本中添加如下⾏:

echo22158>/proc/sys/fs/file-max

这是让Linux在启动完成后强⾏将系统级打开⽂件数硬限制设置为22158。修改完后保存此⽂件。

完成上述步骤后重启系统,⼀般情况下就可以将Linux系统对指定⽤户的单⼀进程允许同时打开的最⼤⽂件数限制设为指定的数值。如果重

启后⽤ulimit-n命令查看⽤户可打开⽂件数限制仍然低于上述步骤中设置的最⼤值,这可能是因为在⽤户登录脚本/etc/profile中使⽤ulimit-n

命令已经将⽤户可同时打开的⽂件数做了限制。由于通过ulimit-n修改系统对⽤户可同时打开⽂件的最⼤数限制时,新修改的值只能⼩于或等

于上次ulimit-n设置的值,因此想⽤此命令增⼤这个限制值是不可能的。所以,如果有上述问题存在,就只能去打开/etc/profile脚本⽂件,在

⽂件中查找是否使⽤了ulimit-n限制了⽤户可同时打开的最⼤⽂件数量,如果找到,则删除这⾏命令,或者将其设置的值改为合适的值,然后

保存⽂件,⽤户退出并重新登录系统即可。

通过上述步骤,就为⽀持⾼并发TCP连接处理的通讯处理程序解除关于打开⽂件数量⽅⾯的系统限制。

2、修改⽹络内核对TCP连接的有关限制(参考对⽐下篇⽂章“优化内核参数”)

在Linux上编写⽀持⾼并发TCP连接的客户端通讯处理程序时,有时会发现尽管已经解除了系统对⽤户同时打开⽂件数的限制,但仍会出现

并发TCP连接数增加到⼀定数量时,再也⽆法成功建⽴新的TCP连接的现象。出现这种现在的原因有多种。

第⼀种原因可能是因为Linux⽹络内核对本地端⼝号范围有限制。此时,进⼀步分析为什么⽆法建⽴TCP连接,会发现问题出在connect()调

⽤返回失败,查看系统错误提⽰消息是“Can’tassignrequestedaddress”。同时,如果在此时⽤tcpdump⼯具监视⽹络,会发现根本没有

TCP连接时客户端发SYN包的⽹络流量。这些情况说明问题在于本地Linux系统内核中有限制。其实,问题的根本原因在于Linux内核的

TCP/IP协议实现模块对系统中所有的客户端TCP连接对应的本地端⼝号的范围进⾏了限制(例如,内核限制本地端⼝号的范围为1024~32768

之间)。当系统中某⼀时刻同时存在太多的TCP客户端连接时,由于每个TCP客户端连接都要占⽤⼀个唯⼀的本地端⼝号(此端⼝号在系统的

本地端⼝号范围限制中),如果现有的TCP客户端连接已将所有的本地端⼝号占满,则此时就⽆法为新的TCP客户端连接分配⼀个本地端⼝

号了,因此系统会在这种情况下在connect()调⽤中返回失败,并将错误提⽰消息设为“Can’tassignrequestedaddress”。有关这些控制逻辑

可以查看Linux内核源代码,以linux2.6内核为例,可以查看tcp_ipv4.c⽂件中如下函数:

staticinttcp_v4_hash_connect(structsock*sk)

请注意上述函数中对变量sysctl_local_port_range的访问控制。变量sysctl_local_port_range的初始化则是在tcp.c⽂件中的如下函数中设置:

void__inittcp_init(void)

内核编译时默认设置的本地端⼝号范围可能太⼩,因此需要修改此本地端⼝范围限制。

第⼀步,修改/etc/⽂件,在⽂件中添加如下⾏:

_local_port_range=102465000

这表明将系统对本地端⼝范围限制设置为1024~65000之间。请注意,本地端⼝范围的最⼩值必须⼤于或等于1024;⽽端⼝范围的最⼤值则

应⼩于或等于65535。修改完后保存此⽂件。

第⼆步,执⾏sysctl命令:

[speng@as4~]$sysctl-p

如果系统没有错误提⽰,就表明新的本地端⼝范围设置成功。如果按上述端⼝范围进⾏设置,则理论上单独⼀个进程最多可以同时建⽴

60000多个TCP客户端连接。

第⼆种⽆法建⽴TCP连接的原因可能是因为Linux⽹络内核的IP_TABLE防⽕墙对最⼤跟踪的TCP连接数有限制。此时程序会表现为在

connect()调⽤中阻塞,如同死机,如果⽤tcpdump⼯具监视⽹络,也会发现根本没有TCP连接时客户端发SYN包的⽹络流量。由于

IP_TABLE防⽕墙在内核中会对每个TCP连接的状态进⾏跟踪,跟踪信息将会放在位于内核内存中的conntrackdataba中,这个数据库的⼤

⼩有限,当系统中存在过多的TCP连接时,数据库容量不⾜,IP_TABLE⽆法为新的TCP连接建⽴跟踪信息,于是表现为在connect()调⽤中

阻塞。此时就必须修改内核对最⼤跟踪的TCP连接数的限制,⽅法同修改内核对本地端⼝号范围的限制是类似的:

第⼀步,修改/etc/⽂件,在⽂件中添加如下⾏:

_conntrack_max=10240

这表明将系统对最⼤跟踪的TCP连接数限制设置为10240。请注意,此限制值要尽量⼩,以节省对内核内存的占⽤。

第⼆步,执⾏sysctl命令:

[speng@as4~]$sysctl-p

如果系统没有错误提⽰,就表明系统对新的最⼤跟踪的TCP连接数限制修改成功。如果按上述参数进⾏设置,则理论上单独⼀个进程最多可

以同时建⽴10000多个TCP客户端连接。

3、使⽤⽀持⾼并发⽹络I/O的编程技术

在Linux上编写⾼并发TCP连接应⽤程序时,必须使⽤合适的⽹络I/O技术和I/O事件分派机制。

可⽤的I/O技术有同步I/O,⾮阻塞式同步I/O(也称反应式I/O),以及异步I/O。《》

在⾼TCP并发的情形下,如果使⽤同步I/O,这会严重阻塞程序的运转,除⾮为每个TCP连接的I/O创建⼀个线程。但是,过多的线程⼜会因

系统对线程的调度造成巨⼤开销。因此,在⾼TCP并发的情形下使⽤同步I/O是不可取的,这时可以考虑使⽤⾮阻塞式同步I/O或异步I/O。⾮

阻塞式同步I/O的技术包括使⽤lect(),poll(),epoll等机制。异步I/O的技术就是使⽤AIO。

从I/O事件分派机制来看,使⽤lect()是不合适的,因为它所⽀持的并发连接数有限(通常在1024个以内)。如果考虑性能,poll()也是不合适

的,尽管它可以⽀持的较⾼的TCP并发数,但是由于其采⽤“轮询”机制,当并发数较⾼时,其运⾏效率相当低,并可能存在I/O事件分派不

均,导致部分TCP连接上的I/O出现“饥饿”现象。⽽如果使⽤epoll或AIO,则没有上述问题(早期Linux内核的AIO技术实现是通过在内核中为每

个I/O请求创建⼀个线程来实现的,这种实现机制在⾼并发TCP连接的情形下使⽤其实也有严重的性能问题。但在最新的Linux内核中,AIO

的实现已经得到改进)。

综上所述,在开发⽀持⾼并发TCP连接的Linux应⽤程序时,应尽量使⽤epoll或AIO技术来实现并发的TCP连接上的I/O控制,这将为提升程

序对⾼并发TCP连接的⽀持提供有效的I/O保证。

内核参数的优化

/etc/是⽤来控制linux⽹络的配置⽂件,对于依赖⽹络的程序(如web服务器和cache服务器)⾮常重要,RHEL默认提供的最好调

整。

推荐配置(把原/etc/内容清掉,把下⾯内容复制进去):

_local_port_range=102465536

_max=16777216

_max=16777216

_rmem=47216

_wmem=47216

_fin_timeout=10

_tw_recycle=1

_timestamps=0

_window_scaling=0

_sack=0

_max_backlog=30000

_no_metrics_save=1

onn=262144

_syncookies=0

_max_orphans=262144

_max_syn_backlog=262144

_synack_retries=2

_syn_retries=2

这个配置参考于cache服务器varnish的推荐配置和SunOne服务器系统优化的推荐配置。

不过varnish推荐的配置是有问题的,实际运⾏表明“_fin_timeout=3”的配置会导致页⾯经常打不开;并且当⽹友使⽤的是IE6浏

览器时,访问⽹站⼀段时间后,所有⽹页都会打不开,重启浏览器后正常。可能是国外的⽹速快吧,我们国情决定需要调

整“_fin_timeout=10”,在10s的情况下,⼀切正常(实际运⾏结论)。

修改完毕后,执⾏:

/sbin/sysctl-p/etc/

/sbin/=1

命令⽣效。为了保险起见,也可以reboot系统。

调整⽂件数:

linux系统优化完⽹络必须调⾼系统允许打开的⽂件数才能⽀持⼤的并发,默认1024是远远不够的。

执⾏命令:

Shell代码

echoulimit-HSn65536>>/etc/

echoulimit-HSn65536>>/root/.bash_profile

ulimit-HSn65536

备注:

对mysql⽤户可同时打开⽂件数设置为10240个;

将Linux系统可同时打开⽂件数设置为1000000个(⼀定要⼤于对⽤户的同时打开⽂件数限制);

将Linux系统对最⼤追踪的TCP连接数限制为20000个(但是,建议设置为10240;因为对mysql⽤户的同时打开⽂件数已经限制在10240

个;且较⼩的值可以节省内存);

将linux系统端⼝范围配置为1024~30000(可以⽀持60000个以上连接,不建议修改;默认已经⽀持20000个以上连接);

综合上述四点,TCP连接数限制在10140个。

这10240个⽂件中还得除去每个进程必然打开的标准输⼊,标准输出,标准错误,服务器监听socket,进程间通讯的unix域socket等⽂件。

因此,当需要对TCP连接数进⾏调整时只需要调整ulimit参数。

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

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

本文发布于:2023-03-10 10:31:22,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/zhishi/a/1678415482134715.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

本文word下载地址:连接数.doc

本文 PDF 下载地址:连接数.pdf

下一篇:返回列表
标签:连接数
相关文章
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2022 Comsenz Inc.Powered by © 实用文体写作网旗下知识大全大全栏目是一个全百科类宝库! 优秀范文|法律文书|专利查询|