(持续更新)linux网络编程中需要注意的内核参数与网络机制

目录

零、基本说明

一、内核参数

二、相关机制

1、GRO

(1)适用场景

(2)优缺点

(3)相关操作

2、Nagle 算法

(1)基本规则

(2)优缺点

(3)相关操作

3、Socket IO 复用 


零、基本说明

        本篇博客会持续更新网络编程中经常遇到的内核参数调整和相关网络功能优化机制,一切以提高服务器性能为目的。具体参数调整,根据业务需求来。

        若读者在日常工作中遇到了相关的问题,也可以提出来一起讨论学习。

一、内核参数

        由于默认的 Linux 内核参数考虑的是最通用的场景,这明显不符合用于支持高并发访问的网络服务器的定义,所以需要修改 Linux 内核参数,使得网络服务器拥有更高的性能。

        在优化内核时,可以做的事情很多,不过,我们通常会根据业务特点来进行调整,下面是只针对最通用的、使 TCP 服务器支持更多并发请求的网络参数做简单说明。

# 设置系统全局可以打开的最大文件描述符数量,ulimit -a 可以查看用户级文件描述符数量的限制
fs.file-max = 6815744  # 允许重用处于 TIME_WAIT 状态的套接字,用于处理高并发连接(系统中总会存在大量的 TIME_WAIT 状态的连接)。
net.ipv4.tcp_tw_reuse = 1# 设置 TCP 连接在没有数据传输时保持活动状态的时间(秒),设置小些可以快速清理掉无效连接
net.ipv4.tcp_keepalive_time = 600# 设置 TCP 连接在关闭时等待 FIN 包(FIN-WAIT-2)确认的时间(秒)。
net.ipv4.tcp_fin_timeout = 30# 设置 TIME_WAIT 状态的套接字最大数量。如果超过这个数字,TIMEWAIT 套接字将立刻被清除并打印警告信息。该参数默认为 180000,过多的 TIME WAIT套接字会使 Web 服务器变慢。
net.ipv4.tcp_max_tw_buckets = 5000# 设置本地端口范围,控制服务器在发起连接时所使用的临时源端口的范围
net.ipv4.ip_local_port_range = 1024     61000# 设置 TCP 接收缓冲区的大小(字节),分别为最小值、默认值和最大值。
net.ipv4.tcp_rmem = 4096        32768   262142
# 设置 TCP 发送缓冲区的大小(字节),分别为最小值、默认值和最大值。
net.ipv4.tcp_wmem = 4096        32768   262142# 设置网络设备的最大积压队列长度。当网卡接收数据包的速度大于内核处理的速度时,会有一个队列保存这些数据包。这个参数表示该队列的最大值。
net.core.netdev_max_backlog = 8096'''
注意:滑动窗口的大小与套接字缓存区会在一定程度上影响并发连接的数目。每个 TCP 连接都会为维护 TCP 滑动窗口而消耗内存,这个窗口会根据服务器的处理速度收缩或扩张。以 Nginx 为例,参数 wmem_max 的设置,需要平衡物理内存的总大小和Nginx 并发处理的最大连接数量(由 nginx.conf 中的 worker processes 和 worker connections 参数决定)而确定。当然如果仅仅为了提高并发量使服务器不出现 Out Of Memory 问题而去降低滑动窗口大小,那么并不合适,因为滑动窗口过小会影响大数据量的传输速度。rmem_default、wmem_default、rmem_max、wmem_max这4 个参数的设置需要根据我们的业务特性以及实际的硬件成本来综合考虑。
'''
# 设置默认的接收缓冲区大小(字节)。
net.core.rmem_default = 262144
# 设置默认的发送缓冲区大小(字节)。
net.core.wmem_default = 262144
# 设置接收缓冲区的最大值(字节)。
net.core.rmem_max = 2097152
# 设置发送缓冲区的最大值(字节)。
net.core.wmem_max = 2097152# 该参数与性能无关,启用 TCP SYN Cookies,用于防止 SYN 泛洪攻击。
net.ipv4.tcp_syncookies = 1# 设置 TCP SYN 请求队列的最大长度,将其设置得大一些,当服务器繁忙来不及 accept 新连接的情况时,Linux 不至于丢失客户端发起的连接请求
net.ipv4.tcp_max_syn_backlog = 1024

二、相关机制

1、GRO

  GRO 是一种全球单播(Unicast)数据包接收优化技术。它允许多个数据包在一次中断中被处理,从而减少 CPU 的利用率和提高数据传输效率。当网络接口接收到多个数据包时,GRO 会将这些数据包聚合在一起,然后一次性触发一个中断来处理这些数据包。这样,就减少了中断的次数,提高了系统的整体性能。

(1)适用场景

  GRO 适用于高流量、低延迟的网络环境,如数据中心、云计算平台等。在这些环境中,GRO 可以显著减少 CPU 的负载,提高网络吞吐量。

(2)优缺点

        优点:可提高网络性能,通过减少中断次数,GRO 可以显著提高网络吞吐量和降低 CPU 的利用率。同时由于减少了中断次数,还降低了系统的能耗。

        缺点:某些情况下,GRO 可能会导致数据包的处理延迟增加,因为它需要等待更多的数据包到达后才能触发中断。在一些对实时性要求较高的应用中,可能需要关闭GRO以确保数据的及时处理。

        在配置 GRO 功能时,需要根据具体的应用场景和需求进行权衡。如果系统对实时性要求较高,或者网络流量较小,那么关闭GRO 可能是一个更好的选择。反之,如果系统需要处理大量的网络流量,并且对延迟的要求不是特别高,那么开启GRO 将有助于提高系统的整体性能。

(3)相关操作

# 关闭网卡 ens33 的 gro 功能
ethtool -K ens33 gro off
# 开启网卡 ens33 的 gro 功能
ethtool -K ens33 gro on

2、Nagle 算法

  Nagle 算法是 TCP/IP 协议中的一种优化机制,主要目的是减少网络中小数据包的数量,从而降低网络拥塞,提高网络带宽的利用率。

(1)基本规则

        在任意时刻,最多只能有一个未被确认的小段。小段为小于 MSS(最大分段大小)的数据块,未被确认是指数据发出去后未收到对端的 ACK。

        如果要发送的数据量达到了 MSS,则立即发送;

        如果数据量小于 MSS 但之前所有发出去的包都已经收到了确认(ACK),也立即发送;

        如果数据量小于 MSS 并且还有未被确认的包,则将数据缓存起来,当收到之前未被确认包的 ACK 或缓存的数据达到 MSS 时再将缓存的数据发送出去。

(2)优缺点

优点

  • 减少了网络中的小包数量,降低了网络负载;
  • 减少了网络拥塞的可能性、提高了网络带宽的利用率;
  • 多个小包合成一个大包发送,减少了协议头的开销;

缺点

  • 增加了发送延迟,特别是对于需要快速响应的应用(如远程终端操作);
  • 很可能导致TCP粘包问题,使接收方应用难以分辨消息边界。

        在Linux系统中,Nagle 算法默认是启用的。对于大多数应用,默认启用Nagle算法是有益的。在实现应用层协议时,需要考虑Nagle算法可能带来的影响,特别是在处理小数据包时。对于需要低延迟的应用(如在线游戏、远程桌面等),可能需要禁用Nagle算法。

(3)相关操作

        在Linux系统中,Nagle 算法默认是启用的。使用 TCP_NODELAY 选项可以禁止 Nagle 算法。此时,应用程序向内核递交的每个数据包都会立即发送出去。

适用 Nagle 时需要注意

  • Nagle 算法与 TCP 的 Delayed ACK 机制确认结合使用时,可能会导致性能问题。Delayed ACK 会推迟发送 ACK,而 Nagle 算法又在等待 ACK,这可能会导致不必要的延迟。
  • Nagle 算法和 CORK 算法非常类似,但是它们的着眼点不一样。Nagle 算法主要避免网络因为太多的小包而拥塞,而 CORK 算法则是为了提高网络的利用率。

        下面 Demo 创建了一个 TCP 客户端,使用 C 语言创建一个 TCP 套接字,连接到服务器,并禁用 Nagle 算法以减少延迟。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <netinet/tcp.h>int main() {int sockfd;struct sockaddr_in server_addr;char *message = "Hello, Server!";int flag = 1;// 创建套接字if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {perror("socket creation failed");exit(EXIT_FAILURE);}// 设置服务器地址server_addr.sin_family = AF_INET;server_addr.sin_port = htons(8090);inet_pton(AF_INET, "127.0.0.1", &server_addr.sin_addr);// 连接服务器if (connect(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {perror("connection failed");close(sockfd);exit(EXIT_FAILURE);}// 禁用 Nagle 算法if (setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, &flag, sizeof(flag)) < 0) {perror("setsockopt failed");close(sockfd);exit(EXIT_FAILURE);}// 发送数据send(sockfd, message, strlen(message), 0);printf("Message sent\n");// 关闭套接字close(sockfd);return 0;
}

3、Socket IO 复用 

       Socket IO 复用是网络编程中用于处理多个客户端连接的技术。其目的是在单线程或少量线程下,通过高效的机制来管理和响应多个并发的 I/O 请求,从而避免因频繁创建和销毁线程所带来的资源消耗和性能瓶颈。

        主要的技术有 select、poll 和 epoll,其中需要特别关注 epoll(Nginx 在 linux 下就是基于 epoll 实现高并发网络连接)。epoll 基于事件驱动,通过红黑树高效管理文件描述符,避免了不必要的遍历,使得时间复杂度降低到 O(1)。此外,epoll 还支持边缘触发和水平触发两种模式,提供了更高的灵活性和性能。

        具体参考如下连接:

Linux下的三种 IO 复用_linux的io复用-CSDN博客icon-default.png?t=O83Ahttps://blog.csdn.net/qq_37437983/article/details/144174475?spm=1001.2014.3001.5501

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

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

相关文章

DevExpress WPF中文教程:Grid - 如何移动和调整列大小?(一)

DevExpress WPF拥有120个控件和库&#xff0c;将帮助您交付满足甚至超出企业需求的高性能业务应用程序。通过DevExpress WPF能创建有着强大互动功能的XAML基础应用程序&#xff0c;这些应用程序专注于当代客户的需求和构建未来新一代支持触摸的解决方案。 无论是Office办公软件…

Matlab笔记---clear、clc、clear all应用

在MATLAB中&#xff0c;clear、clc 和 clear all 是三个常用的命令&#xff0c;它们各自有不同的作用&#xff1a; clc&#xff1a; clc 命令用于清除MATLAB命令窗口中的所有输出。它不会删除任何变量、函数或文件&#xff0c;只是清除屏幕上的显示内容&#xff0c;让你可以更…

铭记一次项目重大事故

在程序的世界里&#xff0c;bug 就像隐藏在暗处的小怪兽&#xff0c;时不时跳出来捣乱。而职业生涯中&#xff0c;总有那么一个或几个 bug 让我们刻骨铭心。它或许让项目差点夭折&#xff0c;或许让你熬了无数个通宵&#xff0c;或许有着离奇的出现方式和曲折的解决过程。无论是…

Qt 一个简单的QChart 绘图

Qt 一个简单的QChart 绘图 先上程序运行结果图&#xff1a; “sample9_1QChart.h” 文件代码如下&#xff1a; #pragma once#include <QtWidgets/QMainWindow> #include "ui_sample9_1QChart.h"#include <QtCharts> //必须这么设置 QT_CHARTS_USE_NAME…

分布式事物XA、BASE、TCC、SAGA、AT

分布式事务——Seata 一、Seata的架构&#xff1a; 1、什么是Seata&#xff1a; 它是一款分布式事务解决方案。官网查看&#xff1a;Seata 2.执行过程 在分布式事务中&#xff0c;会有一个入口方法去调用各个微服务&#xff0c;每一个微服务都有一个分支事务&#xff0c;因…

MySQL为什么使用B+树来作索引

我来详细解释一下B树的结构和特点。 graph TDA[根节点 40|70] --> B[20|30]A --> C[50|60]A --> D[80|90]B --> E[10|15]B --> F[25|28]B --> G[35|38]C --> H[45|48]C --> I[55|58]C --> J[65|68]D --> K[75|78]D --> L[85|88]D --> M[9…

python 下载 b站视频 和音频

video_bvid&#xff1a; import os import requests import json import re from bs4 import BeautifulSoup import subprocess # from detail_video import video_bvid# video_bvid 是一个从外部得到的单个视频ID video_bvid BV1cx421Q7veclass BilibiliVideoAudio:def __in…

2024年06月中国电子学会青少年软件编程(Python)等级考试试卷(五级)答案 + 解析

青少年软件编程(python)等级考试试卷(五级) 一、单选题(共25题,共50分) range()函数的基本用法是什么?( ) A. 生成一个等差数列 B. 生成一个随机数列 C. 生成一个递增数列 D. 生成一个递减数列 正确答案:A 答案解析:range() 函数用于生成一个等差数列,其中起始值、…

以太网链路详情

文章目录 1、交换机1、常见的概念1、冲突域2、广播域3、以太网卡1、以太网卡帧 4、mac地址1、mac地址表示2、mac地址分类3、mac地址转换为二进制 2、交换机的工作原理1、mac地址表2、交换机三种数据帧处理行为3、为什么会泛洪4、转发5、丢弃 3、mac表怎么获得4、同网段数据通信…

Shell编程 脚本的运行方式与注释

目录 shell脚本的运行方式 1. 路径运行 2.bash或sh加脚本运行 ​编辑 3.source在加脚本路径运行 shell脚本注释 单行注释 多行注释 shell脚本的运行方式 我们在/usr/etc/demo01目录下新建了一个脚本 a.sh &#xff0c;脚本内容是要求输出数字1&#xff0c;怎么运行呢 1…

获取淘宝商品评论数据的API应用:市场调研|产品更新|用户数据

下面是一段我用item_review&#xff08;获取商品评论数据&#xff09;抓来的商品评论数据&#xff1a; "items": {"total_results": 375,"totalpage": 38,"page_size": 10,"page": "1","item": [{&quo…

智算网络中Scale-out和Scale-up网络的技术原理

智算网络中Scale-out网络和Scale-up网络的本质区别是什么&#xff1f; 一、什么是智算中心的Scale-out网络和Scale-up网络 数据中心网络总体上可分为两大类&#xff1a;通算网络和智算网络。通算网络主要用于支持传统的计算任务和应用&#xff0c;如企业的IT系统、网站托管、电…

HCIA笔记7--OSPF协议入门

文章目录 0. 路由分类1. OSPF介绍1.1 概念1.2 报文类型 2. 邻接关系的建立2.1 邻居关系的建立2.2 邻接关系的形成2.3 ospf状态机 3. DR与BDR3.1 为什么要有DR和BDR&#xff1f;3.2 DR和BDR的选举原则 4. ospf的配置4.1 内部优先级 5. 问题5.1 三层环路如何解决&#xff1f; Ref…

C05S06-Nginx的内置变量和代理

一、常见内置变量 内置变量说明$uri请求的URL&#xff0c;不包括主机和参数$request_uri请求的URL&#xff0c;包括主机和参数$host请求的主机名$http_user_agent客户端信息&#xff0c;浏览器和操作系统$remote_addr客户端IP地址$remote_port客户端端口$server_addr服务端IP地…

mysql排序问题

mysql 建数据库时&#xff0c;需要指定 字符集 和 排序规则 建表时&#xff0c;也可以指定 也可以指定具体的字段 安照下面的sql顺序执行插入&#xff0c;它们的排序是什么样的&#xff1f; INSERT into test_sort (uid,create_time) VALUE (d,now()) INSERT into test_sort (u…

JAVA 图形界面编程 AWT篇(1)

前言 为了应对JAVA课设&#xff0c;小编走上了java的图形界面编程的道路&#xff0c;通过博客分享自己的学习历程&#xff0c;并进行笔记的记录。 AWT&#xff08;Abstract Window Toolkit&#xff09;介绍 AWT&#xff08;抽象窗口工具包&#xff09;是 Java 最早的图形用户界…

vulhub复现CVE-2021-44228log4j漏洞

目录 一&#xff1a;漏洞概述 二&#xff1a;漏洞原理 三&#xff1a;漏洞利用 lookup功能&#xff1a; JNDI解析器&#xff1a; ldap服务&#xff1a; RMI&#xff1a; 四&#xff1a;漏洞复现 4.1靶场 4.2dnslog测试 4.3部署jndi-injection-exploit 4.4打开监听端口 4.5触发请…

ip地址获取失败啥意思?ip地址获取失败怎么回事

在日常的网络使用中&#xff0c;我们时常依赖于稳定的IP地址来确保数据的顺畅传输和设备的正常识别。然而&#xff0c;有时我们会遇到“IP地址获取失败”的困扰&#xff0c;这不仅阻碍了我们的网络访问&#xff0c;还可能带来一系列的网络连接问题。那么&#xff0c;IP地址获取…

如何在 Android 项目中实现跨库传值

背景介绍 在一个复杂的 Android 项目中&#xff0c;我们通常会有多个库&#xff08;lib&#xff09;&#xff0c;而主应用程序&#xff08;app&#xff09;依赖所有这些库。目前遇到的问题是&#xff0c;在这些库中&#xff0c;libAd 需要获取 libVip 的 VIP 等级状态&#xf…

非常规使用client-go踩坑记

0x01 背景 编程者总有想偷懒的倾向。至少我的初衷时&#xff0c;尽量复用现有的代码。但有时也会变得弄巧成拙。 这不&#xff0c;最近需要在一个Go服务里添加一个CRD的缓存等待。熟悉k8s的同学都知道&#xff0c;向 kube-apiserver 提交一个更新&#xff0c;到同一个进程中的…