最近,该项目遇到了一个问题。操作和维护反馈的健康检查 - 我去检查了。最终发现该问题与半连接的大小和完整的连接队列有关,因此我计划研究它。
(本文涉及的Linux内核源代码主要是v3.10)
该项目通过Websocket提供服务。每次有异常时,都会发生一些现象:
可以看出,当时,同时构建了大量客户,该项目的健康检查机制是确定该服务是否通过TCP健康,以确定服务是否健康。
与并发的Jian连接有关的参数是第一个考虑半连接和完整连接队列的参数,因此请登录到容器以检查两个队列是否溢出。
可以看出,半连接和完整的连接队列已经溢出,因此可以先推断出这两个队列的大小可以通过扩大完整连接队列的大小来解决这两个队列的大小。
那么,半/完整连接队列到底是什么?
在三个时间TCP握手中,Linux内核将通过这两个队列缓存并维护连接过程的状态。
半连接队列,也称为syn队列。当服务器从客户端接收请求时,它将将连接存储到半连接的队列并回复客户端。
完整的连接队列,也称为接受队列。当服务器收到答复时,完成三个握手后,连接将从半连接的队列中删除,放入完整的连接队列,并等待申请过程取走连接。
相应的过程如下:
它主要受两个参数的影响。
在Linux内核源代码中,在Net/core/request_socket.c中的方法中分配了半连接队列的空间。队列大小计算逻辑如下:
队列大小受两个参数的影响:
队列尺寸将获得两者的最小值,并且必须大于或等于8,并且进行结果结果。计算roundup_pow_of_two。简单的理解是将其放在2的倍数上。
如果将栗子设置为128,并且配置为64,则将计算过程简化如下:
在net/ipv4/tcp_ipv4.c的tcp_v4_conn_request()方法中,半连接队列有两个主要方案:
完整连接队列的大小分配在net/socket.c中,计算逻辑如下:
队列大小受两个参数的影响:
完整连接队列的大小将设置为较小的值。
完整连接的判断相对简单,判断是在Net/ipv4/tcp_ipv4.c中做出的:
也就是说,当您完成三个握手并获得有效时,如果您发现完整的连接队列已满,它将被丢弃。
有很多方法可以判断,例如...主要引入。您可以通过参数查看所有网络统计信息。
Netstat如何计算此信息?
在查看了Netstat的源代码后,也从中读取了它。
数据来自内核计数。相关定义在内核源代码的Net/ipv4/proc.c中。当发现内核充满半/完整连接队列时,相应的数字将为+1,对应于。
现在,两个队列溢出,然后查看队列的大小。
如前所述,半/完整连接队列的大小与几个参数有关,并且端口被传递。
让我们看一下系统参数:
您可以看到在系统参数配置中,将半/完整连接队列的大小配置为4096,这对于我们的服务并不小。
然后查看代码的传递,服务是由前端节点实现的连接层。侦听没有通行证的参数,默认情况下,源代码将设置为511。
此时,
半连接队列大小= randup_pow_of_two(min(4096,511))= 512
完整连接队列尺寸=最小(4096,511)= 511
插座中两个队列的实际尺寸很小。
最后,我们将参数设置为与系统一致的4096,并且队列溢出没有问题。
当两个队列都没有溢出时,统计数据将没有这两个结果。如果您想进一步确认,也可以判断。
如果您了解一半/完整连接和基本溢出判断的方法,那么这种类型的问题的定位更好地解决,首先查看半/完整连接队列是否溢出,然后通过系统参数和监视参数。两个队列的实际大小合理。
但是,实际上,在遇到连接队列的溢出时判断并不容易。本文通过一个简单的在线问题介绍了一半/完整连接队列的概念。
如果您想了解更多/完整的连接队列,则可以期待实际的战斗和周围的知识文章,并继续更新?