系统性能优化-6 TCP 三次握手

系统性能优化-6 TCP 三次握手

TCP 三次握手

image-20250626113832542

客户端优化

客户端发送 SYN 给服务器		此时客户端连接状态:SYN_SENT

如果服务器繁忙或中间网络不畅,客户端会重发 SYN,重试的次数由 tcp_syn_retries 参数控制,默认是 6 次,第 1 次重试发生在 1 秒钟后,接着会以翻倍的方式在第 2、4、8、16、32 秒共做 6 次重试,最后一次重试会等待 64 秒,如果仍然没有返回 ACK,才会终止三次握手。所以,总耗时是 1+2+4+8+16+32+64=127 秒,超过 2 分钟。

因此,对于内网中通讯时,就可以适当调低重试次数,尽快把错误暴露给应用程序。

sysctl net.ipv4.tcp_syn_retries

服务端优化

服务器发送 SYN+ACK 给客户端				    此时服务端连接状态:SYN_RECV
客户端收到 SYN+ACK 发送 ACK+数据 到服务端 	 此时客户端连接状态:Established

服务器收到 SYN 报文后,自动回复 SYN + ACK,并把连接放入半连接队列,当半连接队列已满,就无法再建立新连接了

# 查询服务器因 SYN 半连接队列满而丢弃的新连接,是一个【累计值】
netstat -s | grep "SYNs to LISTEN"# 当发现这个值在一直增加时,可以适当增大半连接队列长度
## 查看当前最大半连接队伍长度
sysctl net.ipv4.tcp_max_syn_backlog
## 通过这个文件修改后 sysctl -p 即可生效
vim /etc/sysctl.conf
net.ipv4.tcp_max_syn_backlog = 1024

不过开启 syncookies 功能就可以在不使用 SYN 队列的情况下成功建立连接。修改 tcp_syncookies 参数即可,其中值为 0 时表示关闭该功能,2 表示无条件开启功能,而 1 则表示仅当 SYN 半连接队列放不下时,再启用它。由于 syncookie 仅用于应对 SYN 泛洪攻击(攻击者恶意构造大量的 SYN 报文发送给服务器,造成 SYN 半连接队列溢出,导致正常客户端的连接无法建立),这种方式建立的连接,许多 TCP 特性都无法使用。所以,应当把 tcp_syncookies 设置为 1,仅在队列满时再启用。

# 开启 syncookies 
vim /etc/sysctl.conf
net.ipv4.tcp_syncookies = 1
sysctl -p

如果服务器发送 syn 和 ack 后一直没有回应,就会重发,修改重发次数的方法是,调整 tcp_synack_retries 参数:

# 查看 syn ack 的重发次数
sysctl net.ipv4.tcp_synack_retries# 默认值, 1,2,4,8,32 最多等待 63 秒
net.ipv4.tcp_synack_retries = 5
服务端收到 ack + 数据,将连接从半连接队列移入已连接队列		服务端连接状态进入Established

服务器收到 ack 后,就会把连接从 SYN 半连接队列 移入到 accept 队列,等待进程调用 accept 函数时把连接取出来。如果进程一直不取,accept 队列就会溢出,最终导致建立好的 TCP 连接被丢弃。可以选择向客户端发送 RST 复位报文,告诉客户端连接已经建立失败。

# 默认为 0 不开启,这样更有利于应对突发流量,因为此时客户端的状态是已连接,就会开始发送报文,只要服务器不回复 ack,就会重发,当服务器不再繁忙,再次接收到的请求报文由于含有 ACK,仍然会触发服务器端成功建立连接。
tcp_abort_on_overflow = 0
# listen 函数的 backlog 参数就可以设置 accept 队列的大小,但是同时受到 linux 系统阈值的限制
# Linux 系统级的队列长度上限
net.core.somaxconn = 128
# 查看各监听端口上的 accept 队列长度
ss -ltn# 查看有多少个连接因为队列溢出而被丢弃
netstat -s | grep "listen queue"

如果持续不断地有连接因为 accept 队列溢出被丢弃,就应该调大 backlog 以及 somaxconn 参数。

调查显示:三次握手消耗的时间,在 HTTP 请求完成的时间占比在 10% 到 30% 之间。因此,Google 提出了 TCP fast open 方案(简称TFO),客户端可以在首个 SYN 报文中就携带请求,这节省了 1 个 RTT 的时间

TFO 通讯分为两个阶段,第一阶段为首次建立连接,这时走正常的三次握手,但在客户端的 SYN 报文会明确地告诉服务器它想使用 TFO 功能,这样服务器会把客户端 IP 地址用只有自己知道的密钥加密(比如 AES 加密算法),作为 Cookie 携带在返回的 SYN+ACK 报文中,客户端收到后会将 Cookie 缓存在本地。

之后,如果客户端再次向服务器建立连接,就可以在第一个 SYN 报文中携带请求数据,同时还要附带缓存的 Cookie。很显然,这种通讯方式下不能再采用经典的“先 connect 再 write 请求”这种编程方法,而要改用 sendto 或者 sendmsg 函数才能实现。

服务器收到后,会用自己的密钥验证 Cookie 是否合法,验证通过后连接才算建立成功,再把请求交给进程处理,同时给客户端返回 SYN+ACK。虽然客户端收到后还会返回 ACK,但服务器不等收到 ACK 就可以发送 HTTP 响应了,这就减少了握手带来的 1 个 RTT 的时间消耗。

image-20250626133725986

# 该功能需要客户端和服务端同时支持,第 1 个比特位为 1 时,表示作为客户端时支持 TFO;第 2 个比特位为 1 时,表示作为服务器时支持 TFO,因此该值为3时(0x11),表示完全支持 TFO
sysctl net.ipv4.tcp_fastopen

为了确保安全及用户 IP 会变(如 DHCP ),Cookie 值会隔一段时间变化一次。

[TCP Fast Open --TFO ](https://www.cnblogs.com/codestack/p/18112952)

总结一下文中出现的配置项:

  • net.ipv4.tcp_syn_retries 客户端等待服务端回复 syn+ack 时的最大重试次数,默认为6,分别在 1 + 2 + 4 + 8 + 16 + 32 秒时重试,最后一次重试等待 64 秒,总耗时 127 秒
  • net.ipv4.tcp_max_syn_backlog 服务端最大的 SYN 半连接队列长度,默认 1024,如果设置的过小,会导致无法建立新连接,netstat -s | grep "SYNs to LISTEN" 指令可以获得由于半连接队列已满而引发的 SYN 丢弃个数
  • net.ipv4.tcp_syncookies 服务端在半连接队列满的情况下依然可以建立连接,0 表示关闭该功能,2 表示无条件开启功能,而 1 则表示仅当 SYN 半连接队列放不下时,再启用。这种方式建立的连接,许多 TCP 特性都无法使用,应当设置为 1
  • net.ipv4.tcp_synack_retries 服务端等待客户端回复针对 syn+ack 的 ack 的重试次数,默认为 5,最后一次重试后等待 32 秒,总耗时 63 秒。
  • net.ipv4.tcp_abort_on_overflow 当 accept 全连接队列已满,是否立即中止连接向客户端发送 RST 复位报文,默认为 0 不开启,可以更有利于应对突发流量(该连接会暂存在半连接队列,等客户端重发 ack 后续还是可以再建立连接),只有非常肯定 accept 队列会长期溢出时,才能设置为 1 以尽快通知客户端。
  • net.core.somaxconn Linux 系统级的队列长度上限,与 listen 函数的 backlog 参数配合可以调整 accept 队列的长度
  • net.ipv4.tcp_fastopen TFO 技术,第 1 个 bit 位表示作为客户端是否支持,第 2 个 bit 位表示作为服务端是否支持。

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

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

相关文章

WPF 实现自定义弹窗输入功能

1.前端实现 <Grid><Grid.RowDefinitions><RowDefinition Height"60" /><RowDefinition Height"*" /></Grid.RowDefinitions><BorderGrid.Row"0"BorderBrush"WhiteSmoke"BorderThickness"0.1&qu…

WPF中Converter基础用法

IValueConverter 1.创建一个类集成接口IValueConverter,并实现 2在xaml中引入 举例 性别用int来表示&#xff0c;1为男&#xff0c;2为女 核心代码 创建GenderConverter继承IValueConverter public class GenderConverter : IValueConverter {//model->view转换public…

Postgresql的json充当字典应用

一般我们会将一些系统参数放到参数表中&#xff0c;有些参数的值是json结构&#xff0c;那么如何在查询时引用这些参数&#xff1f;&#xff1f; 比如我在业务表的的xxx_type,或xxx_status记录的是key,又想在查询的时候显示其描述。 先定义字典 如下图如何应用 Postgresql对j…

Dify全面升级:打造极致智能应用开发体验,携手奇墨科技共拓AI新生态

智能应用开发平台Dify以六大核心功能升级与深度性能优化&#xff0c;重新定义AI开发效率与体验。本次更新不仅响应了开发者社区的迫切需求&#xff0c;更通过与云计算领域先锋奇墨科技的战略合作&#xff0c;为企业提供了从开发到部署的全链路智能化解决方案。 .技术领先&#…

关于uniapp开发阻止事件冒泡问题

背景。uniapp开发微信小程序。在使用两个组件拼接嵌套使用后&#xff0c;发现问题&#xff0c;会误操作跳转到更多页面。下图中两个事件若不使用stop修饰符&#xff0c;会相互影响。若点击uni-list-item会串行触发uni-card的handledoctorlist方法。 产生上面问题原因是组件之间…

箭头函数和普通函数的区别?

箭头函数&#xff08;Arrow Functions&#xff09;和普通函数&#xff08;传统函数&#xff09;在 JavaScript 中有显著的区别&#xff0c;主要体现在语法、this 的绑定、构造函数行为、参数处理等方面。以下是详细对比&#xff1a; 1. 语法差异 普通函数&#xff1a; functio…

Linux系统日志与守护进程开发实战指南

Linux系统日志与守护进程开发实战指南 系统日志与守护进程 ├── 系统日志syslog │ ├── 日志路径: /var/log/syslog │ └── 核心API │ ├── openlog │ ├── syslog │ └── closelog └── 守护进程daemon└── 创建步骤├── um…

Vue.js 过滤器详解

Vue.js 过滤器详解 下面我将详细讲解Vue.js中过滤器的语法和使用注意事项&#xff0c;并提供一个完整的演示页面。 过滤器基本概念 在Vue.js中&#xff0c;过滤器&#xff08;Filters&#xff09; 是用于文本格式化的功能&#xff0c;可以在双花括号插值和v-bind表达式中使用…

【iOS】iOS崩溃总结

【iOS】iOS崩溃总结 一、前言 之前写了一篇博文《【Flutter】程序报错导致的灰屏总结》&#xff0c;浏览量、收藏率和点赞量还挺高&#xff0c;还被收录了&#xff0c;就想着总结一下iOS崩溃&#xff0c;这个也是在iOS面试中经常被问到的。 在 iOS 开发过程中&#xff0c;导致…

机器学习:特征向量与数据维数概念

特征向量与数据维数概念 一、特征向量与维数的定义 特征向量与特征类别 在机器学习和数据处理中&#xff0c;每个样本通常由多个特征&#xff08;Feature&#xff09; 描述。例如&#xff0c;一张图片的特征可能包括颜色、形状、纹理等&#xff1b;一个客户的特征可能包括年龄…

开发基于Jeston Orin Nx 开发版 16G的实现

一、基本配置 1.配置参数 密码&#xff1a;yahboom Ubuntu 20.04版本、python3.8、CUDA11.4、cuDNN8.6、TensorRT8.5、Jetpack5.1.1、Opencv4.5.4版本 终端输入命令&#xff1a;sudo jtop 其中Jetpack是英伟达提供的专门供它自己的嵌入式计算机平台使用的人工智能包。 终…

【技术分享】XR技术体系浅析:VR、AR与MR的区别、联系与应用实践

XR技术体系浅析&#xff1a;VR、AR与MR的区别、联系与应用实践 作者&#xff1a;EQ 雪梨蛋花汤 本文是技术分享文档&#xff0c;浅析VR&#xff08;虚拟现实&#xff09;、AR&#xff08;增强现实&#xff09;、MR&#xff08;混合现实&#xff09;的定义、特性、技术演进路线&…

R语言入门课| 05 一文掌握R语言常见数据类型

视频教程 大家可以先做一做R语言基础小测验&#xff0c;看看自己是否需要跟我们5.5h入门R语言的课程。 先上教程视频&#xff0c;B站同步播出&#xff1a; https://www.bilibili.com/video/BV1miNVeWEkw 完整视频回放和答疑服务可见&#xff1a;5.5h入门R语言 本节课程视频…

vRDMA 发布,助力云上 VPC 内高性能通信

资料来源&#xff1a;火山引擎-开发者社区 近日&#xff0c;火山引擎基于部分云服务器实例规格邀测发布 vRDMA 特性&#xff0c;提供云上 VPC 内大规模 RDMA 加速能力&#xff0c;可兼容传统 HPC 应用、AI 应用以及传统 TCP/IP 应用&#xff0c;降低大众化场景的适配门槛&#…

Win10安装dify

一、win10虚拟化设置&#xff0c;控制面板中开启如下三个服务 二、检查确认wls服务开启 设置自动启动并启动 确认服务开启 bcdedit 是否为auto&#xff0c;如果不是&#xff0c;设置为auto bcdedit /set hypervisorlaunchtype autocpu是否为虚拟化 更新wsl wsl --update二 …

【ai学习笔记】GitLab

CI/CD&#xff08;持续集成/持续交付&#xff09;是现代软件开发中的关键实践&#xff0c;通过自动化工具可以大幅提升开发效率和软件质量。下面为你介绍CI/CD的核心概念、常用工具以及示例配置&#xff1a; 1. CI/CD 核心概念 持续集成&#xff08;CI&#xff09;&#xff1…

Solidity 从 0 到 1 |Web3 开发入门免费共学营

开启你的 Web3 开发之旅&#xff0c;从 Sonic 开始&#xff01; 想进入区块链开发的世界&#xff0c;却不知道从哪里开始&#xff1f;选择对的语言和平台&#xff0c;才能事半功倍。 Solidity 是 Web3 中最主流、最通用的智能合约开发语言&#xff0c;被广泛应用于以太坊及其…

【unitrix】 4.4 类型级整数比较系统(cmp.rs)

一、源码 这段代码实现了一个类型级别的整数比较系统&#xff0c;允许在编译时进行整数比较操作。它定义了一套类型来表示比较结果&#xff0c;并为不同类型的整数实现了比较逻辑。 use core::cmp::Ordering; use core::default::Default; use crate::sealed::Sealed; use cr…

2025年渗透测试面试题总结-2025年HW(护网面试) 14(题目+回答)

安全领域各种资源&#xff0c;学习文档&#xff0c;以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各种好玩的项目及好用的工具&#xff0c;欢迎关注。 目录 1. SQL注入原理 &#x1f4a5; 2. XXE攻击&#xff08;XML外部实体注入&#xff09; &#x1f9e9; 3. SQ…

Android开发根据滑动距离标题栏进行渐变

Android开发根据滑动距离标题栏进行渐变 假设滑动控件是NestedScrollView。 先监听NestedScrollView的滑动距离&#xff1a; nslv_preview_me.setOnScrollChangeListener(object :NestedScrollView.OnScrollChangeListener{override fun onScrollChange(v: NestedScrollView…