(持續更新)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.pswp.cn/web/62710.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/62710.shtml
英文地址,請注明出處:http://en.pswp.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;到同一個進程中的…