昆山住房和城乡建设部网站网络营销公司如何建立
2026/4/18 14:27:31 网站建设 项目流程
昆山住房和城乡建设部网站,网络营销公司如何建立,延安免费做网站公司,最新重大新闻如何优化TCP? 根据小林进行总结#xff0c;详细内容可看这里 TCP三次握手性能提升 三次握手的过程在一个 HTTP 请求的平均时间占比 10% 以上#xff0c;在网络状态不佳、高并发或者遭遇 SYN 攻击等场景中#xff0c;如果不能有效正确的调节三次握手中的参数#xff0c;就…如何优化TCP?根据小林进行总结详细内容可看这里TCP三次握手性能提升三次握手的过程在一个 HTTP 请求的平均时间占比 10% 以上在网络状态不佳、高并发或者遭遇 SYN 攻击等场景中如果不能有效正确的调节三次握手中的参数就会对性能产生很多的影响。客户端优化SYN_SENT状态的优化根据网络的稳定性和目标服务器的繁忙程度修改 SYN 的重传次数调整客户端的三次握手时间上限。比如内网中通讯时就可以适当调低重试次数尽快把错误暴露给应用程序。(在内网环境中网络延迟通常很低毫秒级服务器响应很快。如果63秒后才报错会严重影响用户体验)服务端优化调整半连接队列的大小如果遭遇SYN攻击,设置在SYN队列满后开启syncookie功能,保证正常的连接成功建立如果accept 队列溢出系统默认丢弃 ACK如果可以把 tcp_abort_on_overflow 设置为 1 表示用 RST 通知客户端连接建立失败。如果 accpet 队列溢出严重可以通过 listen 函数的 backlog 参数和 somaxconn 系统参数提高队列大小accept 队列长度取决于 min(backlog, somaxconn)。backlog: 表示应用进程期望的队列长度somaxconn:系统全局允许的单个监听端口的最大Accept队列长度绕过三次握手三次握手建立连接造成的后果就是HTTP 请求必须在一个 RTT从客户端到服务器一个往返的时间后才能发送。TCP Fast Open 功能的工作方式在客户端首次建立连接时的过程客户端发送 SYN 报文该报文包含 Fast Open 选项且该选项的 Cookie 为空这表明客户端请求 Fast Open Cookie支持 TCP Fast Open 的服务器生成 Cookie并将其置于 SYN-ACK 数据包中的 Fast Open 选项以发回客户端客户端收到 SYN-ACK 后本地缓存 Fast Open 选项中的 Cookie。所以第一次发起 HTTP GET 请求的时候还是需要正常的三次握手流程。之后如果客户端再次向服务器建立连接时的过程客户端发送 SYN 报文该报文包含数据以及此前记录的Cookie对于非 TFO 的普通 TCP 握手过程SYN 报文中不包含数据支持 TCP Fast Open 的服务器会对收到 Cookie 进行校验如果Cookie 有效服务器将在 SYN-ACK 报文中对 SYN 和数据进行确认服务器随后将数据递送至相应的应用程序如果Cookie 无效服务器将丢弃 SYN 报文中包含的数据且其随后发出的 SYN-ACK 报文将只确认 SYN 的对应序列号如果服务器接受了 SYN 报文中的数据服务器可在握手完成之前发送数据这就减少了握手带来的 1 个 RTT 的时间消耗客户端将发送 ACK 确认服务器发回的 SYN 以及数据但如果客户端在初始的 SYN 报文中发送的数据没有被确认则客户端将重新发送数据此后的 TCP 连接的数据传输过程和非 TFO 的正常情况一致。所以之后发起 HTTP GET 请求的时候可以绕过三次握手这就减少了握手带来的 1 个 RTT 的时间消耗。注意客户端在请求并存储了 Fast Open Cookie 之后可以不断重复 TCP Fast Open 直至服务器认为 Cookie 无效通常为过期。TCP Fast Open 功能需要客户端和服务端同时支持才有效果TCP四次挥手性能优化通常先关闭连接的一方称为主动方后关闭连接的一方称为被动方。主动方的优化调用close函数和shutdown函数的区别调用了 close 函数意味着完全断开连接完全断开不仅指无法传输数据而且也不能发送数据。 此时调用了 close 函数的一方的连接叫做孤儿连接.使用 close 函数关闭连接是不优雅的。于是就出现了一种优雅关闭连接的shutdown 函数它可以控制只关闭一个方向的连接关闭连接的读这个方向如果接收缓冲区有已接收的数据则将会被丢弃并且后续再收到新的数据会对数据进行 ACK然后悄悄地丢弃。也就是说对端还是会接收到 ACK在这种情况下根本不知道数据已经被丢弃了。关闭连接的写这个方向这就是常被称为半关闭的连接。如果发送缓冲区还有未发送的数据将被立即发送出去并发送一个 FIN 报文给对端关闭套接字的读和写两个方向FIN_WAIT1状态的优化主动方发送 FIN 报文后连接就处于 FIN_WAIT1 状态正常情况下如果能及时收到被动方的 ACK则会很快变为 FIN_WAIT2 状态。但是当迟迟收不到对方返回的 ACK 时连接就会一直处于 FIN_WAIT1 状态。此时内核会定时重发 FIN 报文其中重发次数由 tcp_orphan_retries 参数控制。如果FIN_WAIT1 状态连接很多我们就需要考虑降低 tcp_orphan_retries 的值当重传次数超过 tcp_orphan_retries 时连接就会直接关闭掉。对于普遍正常情况时调低 tcp_orphan_retries 就已经可以了。如果遇到恶意攻击FIN 报文根本无法发送出去这由 TCP 两个特性导致的首先TCP 必须保证报文是有序发送的FIN 报文也不例外当发送缓冲区还有数据没有发送时FIN 报文也不能提前发送。 其次TCP 有流量控制功能当接收方接收窗口为 0 时发送方就不能再发送数据。所以当攻击者下载大文件时就可以通过接收窗口设为 0 这就会使得 FIN 报文都无法发送出去那么连接会一直处于 FIN_WAIT1 状态。解决这种问题的方法是调整 tcp_max_orphans 参数它定义了「孤儿连接」的最大数量当进程调用了 close 函数关闭连接此时连接就会是孤儿连接因为它无法再发送和接收数据。Linux 系统为了防止孤儿连接过多导致系统资源长时间被占用就提供了 tcp_max_orphans 参数。如果孤儿连接数量大于它新增的孤儿连接将不再走四次挥手而是直接发送 RST 复位报文强制关闭。FIN_WAIT2状态的优化当主动方收到 ACK 报文后会处于 FIN_WAIT2 状态就表示主动方的发送通道已经关闭接下来将等待对方发送 FIN 报文关闭对方的发送通道。这时如果连接是用 shutdown 函数关闭的连接可以一直处于 FIN_WAIT2 状态因为它可能还可以发送或接收数据。但对于 close 函数关闭的孤儿连接由于无法再发送和接收数据所以这个状态不可以持续太久而 tcp_fin_timeout 控制了这个状态下连接的持续时长默认值是 60 秒TIME_WAIT状态优化方式一Linux 提供了 tcp_max_tw_buckets 参数当 TIME_WAIT 的连接数量超过该参数时新关闭的连接就不再经历 TIME_WAIT 而直接关闭。当服务器的并发连接增多时相应地同时处于 TIME_WAIT 状态的连接数量也会变多此时就应当调大 tcp_max_tw_buckets 参数减少不同连接间数据错乱的概率。tcp_max_tw_buckets 也不是越大越好毕竟系统资源是有限的。方式二有一种方式可以在建立新连接时复用处于 TIME_WAIT 状态的连接那就是打开 tcp_tw_reuse 参数。但是需要注意该参数是只用于客户端建立连接的发起方因为是在调用 connect() 时起作用的而对于服务端被动连接方是没有用的。tcp_tw_reuse 从协议角度理解是安全可控的可以复用处于 TIME_WAIT 的端口为新的连接所用。什么是协议角度理解的安全可控呢主要有两点只适用于连接发起方也就是 C/S 模型中的客户端对应的 TIME_WAIT 状态的连接创建时间超过1 秒才可以被复用。使用这个选项还有一个前提需要打开对 TCP 时间戳的支持(对方也要打开)由于引入了时间戳它能带来了些好处我们在前面提到的 2MSLTIME_WAIT状态的持续时间 问题就不复存在了因为重复的数据包会因为时间戳过期被自然丢弃 同时它还可以防止序列号绕回也是因为重复的数据包会由于时间戳过期被自然丢弃方式三我们可以在程序中设置 socket 选项来设置调用 close 关闭连接行为。如果 l_onoff 为非 0 且 l_linger 值为 0那么调用 close 后会立该发送一个 RST 标志给对端该 TCP 连接将跳过四次挥手也就跳过了 TIME_WAIT 状态直接关闭。这种方式只推荐在客户端使用服务端千万不要使用。因为服务端一调用 close就发送 RST 报文的话客户端就总是看到 TCP 连接错误 “connnection reset by peer”。被动方的优化被动关闭的连接方应对非常简单它在回复 ACK 后就进入了 CLOSE_WAIT 状态等待进程调用 close 函数关闭连接。因此出现大量 CLOSE_WAIT 状态的连接时应当从应用程序中找问题。因为可能因为应用程序出现了 Bugread 函数返回 0 时没有调用 close 函数。当被动方发送 FIN 报文后连接就进入 LAST_ACK 状态在未等到 ACK 时会在 tcp_orphan_retries 参数的控制下重发 FIN 报文。如果连接双方同时关闭连接会怎么样由于 TCP 是双全工的协议所以是会出现两方同时关闭连接的现象也就是同时发送了 FIN 报文。此时上面介绍的优化策略仍然适用。两方发送 FIN 报文时都认为自己是主动方所以都进入了 FIN_WAIT1 状态FIN 报文的重发次数仍由 tcp_orphan_retries 参数控制。接下来双方在等待 ACK 报文的过程中都等来了 FIN 报文。这是一种新情况所以连接会进入一种叫做 CLOSING 的新状态它替代了 FIN_WAIT2 状态。接着双方内核回复 ACK 确认对方发送通道的关闭后进入 TIME_WAIT 状态等待 2MSL 的时间后连接自动关闭。TCP传输数据的性能提升TCP 连接是由内核维护的内核会为每个连接建立内存缓冲区如果连接的内存配置过小就无法充分使用网络带宽(单位时间内网络链路能传输的最大数据量)TCP 传输效率就会降低如果连接的内存配置过大很容易把服务器资源耗尽这样就会导致新连接无法建立因为网络的传输能力是有限的当发送方依据发送窗口发送超过网络处理能力的报文时路由器会直接丢弃这些报文。因此缓冲区的内存并不是越大越好。TCP 可靠性是通过 ACK 确认报文实现的又依赖滑动窗口提升了发送速度也兼顾了接收方的处理能力。可是默认的滑动窗口最大值只有 64 KB不满足当今的高速网络的要求要想提升发送速度必须提升滑动窗口的上限在 Linux 下是通过设置 tcp_window_scaling 为 1 做到的此时最大值可高达 1GB。滑动窗口定义了网络中飞行报文的最大字节数当它超过带宽时延积时网络过载就会发生丢包。而当它小于带宽时延积时就无法充分利用网络带宽。因此滑动窗口的设置必须参考带宽时延积。带宽时延积BDP RTT * 带宽 比如最大带宽是 100 MB/s网络时延RTT是 10ms 时意味着客户端到服务端的网络一共可以存放 100MB/s * 0.01s 1MB 的字节。)内核缓冲区决定了滑动窗口的上限缓冲区可分为发送缓冲区 tcp_wmem 和接收缓冲区 tcp_rmem。Linux 会对缓冲区动态调节我们应该把缓冲区的上限设置为带宽时延积。发送缓冲区是自行调节的当发送方发送的数据被确认后并且没有新的数据要发送就会把发送缓冲区的内存释放掉发送缓冲区的调节功能是自动开启的而接收缓冲区需要把 tcp_moderate_rcvbuf 设置为 1 来开启。接收缓冲区可以根据系统空闲内存的大小来调节接收窗口如果系统的空闲内存很多就可以自动把缓冲区增大一些这样传给对方的接收窗口也会变大因而提升发送方发送的传输数据数量反之如果系统的内存很紧张就会减少缓冲区这虽然会降低传输效率可以保证更多的并发连接正常工作但需要注意的是如果程序中的 socket 设置 SO_SNDBUF 和 SO_RCVBUF则会关闭缓冲区的动态整功能所以不建议在程序设置它俩而是交给内核自动调整比较好。在高并发服务器中为了兼顾网速与大量的并发连接我们应当保证缓冲区的动态调整的最大值达到带宽时延积而最小值保持默认的 4K 不变即可。而对于内存紧张的服务而言调低默认值是提高并发的有效手段。有效配置这些参数后既能够最大程度地保持并发性也能让资源充裕时连接传输速度达到最大值。补充“如果 accept 队列满了那么 server 扔掉 client 发过来的 ack”也就是说该TCP连接还是位于半连接队列中没有丢弃吗当 accept 队列满了后续新进来的syn包都会被丢失我文章的突发流量例子是那个连接进来的时候 accept 队列还没满但是在第三次握手的时候accept 队列突然满了就会导致 ack 被丢弃就一直处于半连接队列。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询