从一个netty程序说一说TCP三次握手的总结及参数优化

news2024/11/19 6:09:49

一、背景

TCP连接经历了三次握手,当我们开发一个netty程序,运行在线上环境后,如何对其进行监控,并适时地进行参数调优。

本文以我们生产环境的一个通道程序,看一看三次握手的过程,以及Linux系统关于创建http连接的参数设置情况。

二、流程图

网上有很多关于tcp三次握手的讲解时序图,这里结合了两个队列的出入操作,详情见下:

在这里插入图片描述

在这里插入图片描述

三、linux机器(centos)的参数

优化TCP三次握手涉及到的参数主要有以下几个,另外就是绕开三次握手的策略。

参数默认值建议值备注
/proc/sys/net/ipv4/tcp_syn_retries5SYN报文重传的次数(客户端)
/proc/sys/net/ipv4/tcp_abort_on_overflow00调试的时候,设置为1的时候,accept队列满后,服务端会发送reset报文给客户端
/proc/sys/net/ipv4/tcp_synack_retries2SYN+ACK报文重传的次数
/proc/sys/net/ipv4/tcp_max_syn_backlog262144半连接队列的长度
/proc/sys/net/core/somaxconn128全连接队列的长度

1、SYN报文重传的次数

在这里插入图片描述

2、开关tcp_abort_on_overflow

当accept队列满的时候,如果值设为1,server会返回reset报文给client;默认值是0,服务端会抛弃TCP第三次握手,回到第二次握手----由服务端重新发送SYN+ACK报文给客户端。

这里就会有一个重试发送的次数问题,见下一段。

3、SYN+ACK报文重传的次数

4、半连接队列的长度

tcp_max_syn_backlog的长度一般都远比somaxconn大,这就跟买东西讲价钱一样,真心诚意的往往比问价格的人少之又少。

TCP SYN FLOOD恶意DOS攻击就是建立大量的半连接状态的请求,然后丢弃而不进行第三次握手,真是害人~

半连接syns队列的连接要取出来给全连接队列,而全连接accept队列中的连接,在服务端accept()的时候触发取出。

也就是说,TCP三次握手,到建立连接完成,无论是半连接队列还是全连接队列,都不保留该连接。

5、全连接队列的长度

全连接队列的大小取决于:min(backlog, somaxconn) . backlog是在socket创建的时候传入的,somaxconn是一个os级别的系统参数。

  • nginx默认是511
  • tomcat默认是100
  • netty的默认情况,见下文的源码分析

如何查看全队列的长度

linux机器分析netty端口是8889的tcp连接情况:

在这里插入图片描述

# ss -lnt
State       Recv-Q Send-Q    Local Address:Port    Peer Address:Port
LISTEN      0      128           *:8889             *:*

其中Send-Q 就是指全连接队列的长度为128,Recv-Q则是指在队列中和等待进队列的数量。

如果Recv-Q 大于 Send-Q 的话,则会出现客户端无法和服务端建立连接的异常情况。

调大nginx的backlog

在这里插入图片描述

netty listen()

public static final ChannelOption<Integer> SO_BACKLOG = valueOf("SO_BACKLOG");

ServerBootstrap bootstrap = new ServerBootstrap();
bootstrap.group(bossGroup, workerGroup)
        //注册NioServerSocketChannel
        .channel(NioServerSocketChannel.class)
        // 设置BACKLOG队列大小为1024
        .option(ChannelOption.SO_BACKLOG, 1024);

四、netty的backlog

源码类io.netty.util.NetUtil.SOMAXCONN

netty的backlog值,可以看到,windows操作系统默认是200,否则128。

程序进一步会去读取文件/proc/sys/net/core/somaxconn的内容,把它赋值给SOMAXCONN。

这也就是说,当我们没有在netty listen()中指定队列大小的时候,默认它就取somaxconn的值。

所以,我们只要修改系统参数somaxconn即可增大netty的backlog值。

			public static final int SOMAXCONN;

			SOMAXCONN = (Integer)AccessController.doPrivileged(new PrivilegedAction<Integer>() {
            public Integer run() {
                int somaxconn = PlatformDependent.isWindows() ? 200 : 128;
                File file = new File("/proc/sys/net/core/somaxconn");
                BufferedReader in = null;

                try {
                    if (file.exists()) {
                        in = new BufferedReader(new FileReader(file));
                        somaxconn = Integer.parseInt(in.readLine());
                        if (NetUtil.logger.isDebugEnabled()) {
                            NetUtil.logger.debug("{}: {}", file, somaxconn);
                        }
                    } else {
                        Integer tmp = null;
                        if (SystemPropertyUtil.getBoolean("io.netty.net.somaxconn.trySysctl", false)) {
                            tmp = NetUtil.sysctlGetInt("kern.ipc.somaxconn");
                            if (tmp == null) {
                                tmp = NetUtil.sysctlGetInt("kern.ipc.soacceptqueue");
                                if (tmp != null) {
                                    somaxconn = tmp;
                                }
                            } else {
                                somaxconn = tmp;
                            }
                        }

                        if (tmp == null) {
                            NetUtil.logger.debug("Failed to get SOMAXCONN from sysctl and file {}. Default: {}", file, somaxconn);
                        }
                    }
                } catch (Exception var13) {
                    NetUtil.logger.debug("Failed to get SOMAXCONN from sysctl and file {}. Default: {}", new Object[]{file, somaxconn, var13});
                } finally {
                    if (in != null) {
                        try {
                            in.close();
                        } catch (Exception var12) {
                        }
                    }

                }

                return somaxconn;
            }
        });

五、slb监控连接数

在这里插入图片描述

从阿里云SLB的监听可以看出,每秒的连接数以及并发连接数。

六、linux监控

在这里插入图片描述

[root@channel-jvm1 ~]# cat /proc/sys/net/core/somaxconn
128
[root@channel-jvm1 ~]# cat /proc/sys/net/ipv4/tcp_max_syn_backlog
262144
[root@channel-jvm1 ~]# ss -lnt
State       Recv-Q Send-Q     Local Address:Port                                                          Peer Address:Port
LISTEN      0      128                 *:8889                                                                     *:*

LISTEN      0      100                 *:6005                                                                     *:*

在这里插入图片描述

  • 8889是netty的tcp端口
  • 6005是tomcat的http端口

可以看到,这里的全连接队列比较小,为默认值128。因为QPS比较低,见上面的SLB监控,所以还未出现握手异常。

最后说一下,怎么看有无被丢弃的连接。

在这里插入图片描述

[root@channel-jvm1 ~]# netstat -s | grep overflowed
    4236 times the listen queue of a socket overflowed
[root@channel-jvm1 ~]# netstat -s | grep overflowed
    4236 times the listen queue of a socket overflowed
[root@channel-jvm1 ~]# netstat -s | grep overflowed
    4236 times the listen queue of a socket overflowed

4236 times ,表示 accept 队列溢出的次数,注意这个是累计值。可以隔几秒钟执行下,如果这个数字一直在增加的话,说明 accept 连接队列偶尔满了。

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

或者采用如下命令,注意是每隔几秒调用一下。

[root@channel-jvm1 ~]# date;netstat -s | egrep "listen|LISTEN"
Fri May 31 23:56:46 CST 2024
    4236 times the listen queue of a socket overflowed
    8146 SYNs to LISTEN sockets dropped
[root@channel-jvm1 ~]# date;netstat -s | egrep "listen|LISTEN"
Fri May 31 23:57:28 CST 2024
    4236 times the listen queue of a socket overflowed
    8146 SYNs to LISTEN sockets dropped
[root@channel-jvm1 ~]# date;netstat -s | egrep "listen|LISTEN"
Fri May 31 23:57:48 CST 2024
    4236 times the listen queue of a socket overflowed
    8146 SYNs to LISTEN sockets dropped

在这里插入图片描述

七、参考文章

https://mp.weixin.qq.com/s/yH3PzGEFopbpA-jw4MythQ
https://learnku.com/articles/46205
https://cloud.tencent.com/developer/article/1645688

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

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

相关文章

翻译《The Old New Thing》- What a drag: Dragging a virtual file (IStream edition)

What a drag: Dragging a virtual file (IStream edition) - The Old New Thing (microsoft.com)https://devblogs.microsoft.com/oldnewthing/20080319-00/?p23073 Raymond Chen 2008年03月19日 拖拽虚拟文件&#xff08;IStream 版本&#xff09; 上一次&#xff0c;我们看…

Spring Cloud | 客户端 “负载均衡器“ : Ribbon

目录: 1. 什么是 "负载均衡" ? ( 通过 "负载均衡" 可以将 "用户请求" "分发" 到 不同的服务器&#xff0c;以此来提高 "性能" 和 "可靠性" )2. "负载均衡" 的 分类 &#xff1f;3. 认识 Ribbon :3.1 R…

Vitis HLS 学习笔记--控制驱动与数据驱动混合编程

目录 1. 简介 2. 示例分析 2.1 代码分析 2.2 控制驱动TLP的关键特征 2.3 数据驱动TLP的关键特征 3. 总结 1. 简介 在 HLS 硬件加速领域&#xff0c;Vitis HLS 提供了强大的抽象并行编程模型。这些模型包括控制驱动和数据驱动的任务级并行性&#xff08;TLP&#xff09;&…

【网络安全的神秘世界】MySQL

&#x1f31d;博客主页&#xff1a;泥菩萨 &#x1f496;专栏&#xff1a;Linux探索之旅 | 网络安全的神秘世界 | 专接本 MySQL MySQL 教程 | 菜鸟教程 (runoob.com) 什么是数据库 数据库&#xff08;Database&#xff09;是按照数据结构来组织、存储和管理数据的仓库 在do…

Mac OS 用户开启 80 端口

开启端口 sudo vim /etc/pf.conf # 开放对应端口 pass out proto tcp from any to any port 8080 # 刷新配置文件 sudo pfctl -f /etc/pf.conf sudo pfctl -e获取本机ip地址 ifconfig en0 | grep inet | grep -v inet6 | awk {print $2}访问指定端口

Pytorch反向传播算法(Back Propagation)

一&#xff1a;revise 我们在最开始提出一个线性模型。 x为我们的输入&#xff0c;w为权重。相乘的结果是我们对y的预测值。 那我们在训练时就是对这个权重w进行更新&#xff0c;就需要用到上一章提到的梯度下降算法&#xff0c;不断更新w。但是此时注意不是用y的预测值对w进…

go解析yaml

go解析yaml文件关键就是结构体的创建 初学go tag字段要和yaml文件中的key对应起来&#xff0c;每个层级都要创建对应的结构体&#xff0c;有点烦 package configimport ("gopkg.in/yaml.v3""os" )type Config struct {MysqlConfig MysqlConfig yaml:&q…

生成树协议STP(Spanning Tree Protocol)

为了提高网络可靠性&#xff0c;交换网络中通常会使用冗余链路。然而&#xff0c;冗余链路会给交换网络带来环路风险&#xff0c;并导致广播风暴以及MAC地址表不稳定等问题&#xff0c;进而会影响到用户的通信质量。生成树协议STP&#xff08;Spanning Tree Protocol&#xff0…

段码屏|液晶显示模块|超低功耗LCD驱动芯片

1 简介 PC164S32 是一款支持 128 点 (32 4)显示 的多功能 LCD 控制器芯片&#xff0c;内部存储器RAM数据直接映射到 LCD 显示。可软件配置特性使其适用于包括 LCD 模块和显示子系统在内的多种 LCD 应用。主控制器与 PC164S32接口仅需3 或 4 条线。内置的省电模式极大的降低了功…

第 11 章 排序

第 11 章 排序 Abstract 排序犹如一把将混乱变为秩序的魔法钥匙&#xff0c;使我们能以更高效的方式理解与处理数据。 无论是简单的升序&#xff0c;还是复杂的分类排列&#xff0c;排序都向我们展示了数据的和谐美感。 本章内容 11.1 排序算法11.2 选择排序11.3 冒…

ThinkPHP5发送邮件如何配置?有哪些技巧?

ThinkPHP5发送邮件的性能怎么优化&#xff1f;批量发信的方法&#xff1f; 邮件发送功能是许多应用程序的关键组成部分&#xff0c;尤其是在用户注册、密码重置和通知等功能中尤为重要。AokSend将详细介绍如何在thinkphp5中配置和使用邮件发送功能&#xff0c;并确保你可以轻松…

C语言王国——杨氏矩阵

目录 1. 引言 2. 了解杨氏矩阵 3. 思路分析 4. 代码 5. 总结 1. 引言 最近在做二维数组的训练的时候发现了一个很有意思的题&#xff1a; 一看这不是杨氏矩阵嘛&#xff0c;接下来就由姜糖我带大家了解一下这个著名的矩阵。 2. 了解杨氏矩阵 通过查阅百度得知&#xff1a; …

HNU-深度学习-电商多模态图文检索

前言 主要是跟着baseline搭了一遍&#xff0c;没有想到很好的优化。 有官方教程&#xff0c;但是有点谬误&#xff0c;所以就想着自己记录一下我的完成过程。 github项目地址&#xff1a; https://github.com/OFA-Sys/Chinese-CLIP 官方文档&#xff1a; 电商多模态图文检…

可用于嵌入式的解释器调研对比,及lua解释器介绍

嵌入式不一定只能用C! ---------------------------------------------------------------------------------------手动分割线-------------------------------------------------------------------------------- 本文章参考了以下文章&#xff1a; 这里是引用 ------------…

游戏逆向工具分析及解决方案

游戏逆向&#xff0c;是指通过各类工具对游戏进行反编译及源码分析&#xff0c;尝试分析游戏的实现逻辑的过程。这个过程需要使用解密、反编译、解压缩等技术&#xff0c;目的是还原或分析出游戏的代码逻辑及资源。 游戏逆向工具可以按照不同功能进行划分&#xff0c;如&#…

sh发送邮件如何通过配置SMTP服务器来实现?

sh发送邮件的操作方法&#xff1f;如何使用Shell脚本自动发信&#xff1f; 在Shell脚本中实现邮件发送功能是一项常见需求&#xff0c;特别是在自动化任务执行或系统监控中。AokSend将介绍如何通过配置SMTP服务器来实现sh发送邮件的方法和注意事项。 sh发送邮件&#xff1a;安…

【经典排序算法】堆排序(精简版)

什么是堆排序&#xff1a; 堆排序(Heapsort)是指利用堆&#xff08;完全二叉树&#xff09;这种数据结构所设计的一种排序算法&#xff0c;它是选择排序的一种。需要注意的是排升序要建大堆&#xff0c;排降序建小堆。 堆排序排序的特性总结&#xff1a; 1. 堆排序使用堆来选数…

VSCode插件Data Previewer

此插件支持直接在vscode 里对csv&#xff0c;xlsx等数据做可视化、统计探索 1. 安装 2. 使用效果 2.1. yaml文件 2.2. xml文件 2.3. csv文件 可以对文件进行各种分析&#xff0c;如此多的选项 散点图 线图 参考文献 GitHub - RandomFractals/vscode-data-preview: Data Pre…

分析和设计算法

目录 前言 循环不变式 n位二进制整数相加问题 RAM模型 使用RAM模型分析 代码的最坏情况和平均情况分析 插入排序最坏情况分析 插入排序平均情况分析 设计算法 分治法 总结 前言 循环迭代&#xff0c;分析算法和设计算法作为算法中的三个重要的角色&#xff0c;下面…

【网络安全的神秘世界】docker搭建pikachu靶场

&#x1f31d;博客主页&#xff1a;泥菩萨 &#x1f496;专栏&#xff1a;Linux探索之旅 | 网络安全的神秘世界 | 专接本 docker搭建pikachu靶场 通过docker安装pikachu 访问docker官网查找pikachu&#xff1a; https://hub.docker.com/search?qapache 复制命令后&#xff…