本帖最后由 『』 于 2020-11-24 00:34 编辑
很多有经验的同事在AD做服务器负载配置的时候,总是会要求在设备上配置多个地址。目的是为了避免65535个端口被占满导致连接不足。但是为什么这么说呢?这种说法对不对呢?我想我有必要单独发一篇文章来好好说一下这个问题。
其实要想把这个问题搞清楚,关键在于要把TCP连接的两端里的角色分清楚。AD在服务器负载的过程中既是服务器又是客户端。如果不将客户端和服务器端两种角色拆开来理解,无法详细的说明清楚这个问题。
所以本文分别从客户端、服务端两块来展开。
客户端
现在先单独来说客户端,当一台机器作为客户端的时候,究竟能支持多少个TCP连接?可以通过check下设备端口数量的配置查看。
sysctl -a | grep ip_local_port_range
可以看到设备的返回值为
net.ipv4.ip_local_port_range = 32768 60999
通过上述内核参数可以看到内核开放了28231个端口可以供TCP连接使用。这个时候我们似乎可以初步得出一个相结论,当AD作为客户端建立连接的时候,最大连接数量是受内核参数net.ipv4.ip_local_port_range限制, 而ip_local_port_range参数的最大理论范围是0-65535
如果此时以为这个结论是说是最终结论的话,就被带了沟里去。这个参数的详细可以查看相关文献指的是单个ip的可用客户端ip地址,所以最正确的结论是:“对于有1个ip的客户端来说,受限于ip_local_port_range参数,也受限于65535。但单客户端可以配置多个ip,有几个ip,最大理论值就翻几倍,这个就是为什么要配置多个地址的由来
服务端
我们现在在来回头考虑服务器端。对于服务器来说,最大支持的并发连接是多少呢?就有人就开始糊涂了:“服务器端理论也是端口限制吗?”。好,假设如果受影响的话,那我们的http器只监听了一个80端口。那只能接受一个TCP连接喽?这明显是太荒唐了。
好,我们再看另外一个靠谱一点的答案。那就是一条TCP连接是由一个4元组组成的【5元组的协议已确定所以剩余4元】。对于AD的一个虚拟服务来说ip和端口是往往都是固定的。tcp连接4元组中只有客户端ip和客户端port是可变的。那是不是可建立的最大的连接数是2的32次方(全部ip数)×2的16次方(全部port数)。两百万亿这样大的一个数字呢吗?确实理论上是这样的但是理想和实际总是会有差距的,因为Linux每维护一条TCP连接都要花费资源。处理连接请求,保活数据的收发时需要消耗CPU,维持TCP连接需要消耗内存。当前要考虑最大连接个数,所以我们先不考虑数据的收发。那么TCP在静止未出现新建和断开的状态下,就不怎么消耗CPU了,主要消耗内存而内存是有上限的。按照一般观点一条TCP连接如果不发送数据的话消耗内存是3.3K左右,当然这个数值也取决于设备的优化情况而定。如果有数据收发还需要为每条TCP连接分配缓存区,假设你只保持连接不发送数据,那么你服务器可以建立的连接最大数量 = 你的内存/每条连接的内存消耗。 但是这个场景下我们考虑的前提是在一个进程保持所有的服务器端连接。而在实际中会为TCP连接创建多个线程。每个线程也需要一定的内存开销。
所以我们可以得出结论
AD作为TCP连接的客户端:每一个ip可建立的TCP连接理论受限于ip_local_port_range参数,也受限于65535。所以我们可以通过配置多ip的方式来加大自己的建立连接的能力。这个配置在设备上使用snat地址池的方式进行实现。
AD作为TCP连接的服务器:每一个监听的端口能维护的TCP连接数虽然理论值很大,但这个数字没有实际意义。最大并发数取决你的内存大小及系统优化情况。
|