Linux性能優(yōu)化7

網(wǎng)絡(luò)優(yōu)化并發(fā)模型

從IO的角度

第一種是最常用的 I/O 多路復(fù)用技術(shù) epoll顶岸,主要用來取代 select 和 poll。這其實是解決 C10K 問題的關(guān)鍵辖佣,也是目前很多網(wǎng)絡(luò)應(yīng)用默認(rèn)使用的機(jī)制卷谈。
reactor

第二種是使用異步 I/O(Asynchronous I/O,AIO)世蔗。AIO 允許應(yīng)用程序同時發(fā)起很多 I/O 操作,而不用等待這些操作完成顶滩。等到 I/O 完成后寸爆,系統(tǒng)會用事件通知的方式,告訴應(yīng)用程序結(jié)果救氯。不過歌憨,AIO 的使用比較復(fù)雜,你需要小心處理很多邊緣情況务嫡。
CGI應(yīng)該是這種模式
proactor

從進(jìn)程并發(fā)模型

第一種,主進(jìn)程 + 多個 worker 子進(jìn)程准谚。其中,主進(jìn)程負(fù)責(zé)管理網(wǎng)絡(luò)連接樊破,而子進(jìn)程負(fù)責(zé)實際的業(yè)務(wù)處理唆铐。這也是最常用的一種模型。

第二種顺少,監(jiān)聽到相同端口的多進(jìn)程模型王浴。在這種模型下,所有進(jìn)程都會監(jiān)聽相同接口氓辣,并且開啟 SO_REUSEPORT 選項,由內(nèi)核負(fù)責(zé)筛婉,把請求負(fù)載均衡到這些監(jiān)聽進(jìn)程中去。
CGI用的是這種方式
nginx呢入蛆?

應(yīng)用層的網(wǎng)絡(luò)協(xié)議優(yōu)

  1. 使用長連接取代短連接硕勿,可以顯著降低 TCP 建立連接的成本。在每秒請求次數(shù)較多時扼褪,這樣做的效果非常明顯粱栖。
    http1.1默認(rèn)支持,1.0以下需要手動設(shè)置keepalive
  2. 使用內(nèi)存等方式闹究,來緩存不常變化的數(shù)據(jù),可以降低網(wǎng)絡(luò) I/O 次數(shù),同時加快應(yīng)用程序的響應(yīng)速度吉嫩。
    client cache
  3. 使用 DNS 緩存嗅定、預(yù)取、HTTPDNS 等方式忙迁,減少 DNS 解析的延遲智什,也可以提升網(wǎng)絡(luò) I/O 的整體速度。

套接字

套接字可以屏蔽掉 Linux 內(nèi)核中不同協(xié)議的差異荠锭,為應(yīng)用程序提供統(tǒng)一的訪問接口晨川。每個套接字共虑,都有一個讀寫緩沖區(qū)。

  • 讀緩沖區(qū)妈拌,緩存了遠(yuǎn)端發(fā)過來的數(shù)據(jù)尘分。如果讀緩沖區(qū)已滿,就不能再接收新的數(shù)據(jù)培愁。
  • 寫緩沖區(qū),緩存了要發(fā)出去的數(shù)據(jù)谍咆。如果寫緩沖區(qū)已滿私股,應(yīng)用程序的寫操作就會被阻塞」┖浚【臟頁大量出現(xiàn)?】
    調(diào)整這些緩沖區(qū)的大胁槠骸:
  1. 增大每個套接字的緩沖區(qū)大小 net.core.optmem_max偿曙;
  2. 增大套接字接收緩沖區(qū)大小 net.core.rmem_max 和發(fā)送緩沖區(qū)大小 net.core.wmem_max;
  3. 增大 TCP 接收緩沖區(qū)大小 net.ipv4.tcp_rmem 和發(fā)送緩沖區(qū)大小 net.ipv4.tcp_wmem望忆。


    image.png

    tcp_rmem 和 tcp_wmem 的三個數(shù)值分別是 min启摄,default,max傅是,系統(tǒng)會根據(jù)這些設(shè)置蕾羊,自動調(diào)整 TCP 接收 / 發(fā)送緩沖區(qū)的大小。udp_mem 的三個數(shù)值分別是 min书闸,pressure利凑,max,系統(tǒng)會根據(jù)這些設(shè)置哀澈,自動調(diào)整 UDP 發(fā)送緩沖區(qū)的大小日丹。

套接字接口還提供了一些配置選項,用來修改網(wǎng)絡(luò)連接的行為:

  • 為 TCP 連接設(shè)置 TCP_NODELAY 后哲虾,就可以禁用 Nagle 算法束凑;
  • 為 TCP 連接開啟 TCP_CORK 后,可以讓小包聚合成大包后再發(fā)送(注意會阻塞小包的發(fā)送)汪诉;kafka
  • 使用 SO_SNDBUF 和 SO_RCVBUF 谈秫,可以分別調(diào)整套接字發(fā)送緩沖區(qū)和接收緩沖區(qū)的大小鱼鼓。

傳輸層網(wǎng)絡(luò)性能優(yōu)化

1.高qps場景

在請求數(shù)比較大的場景下,你可能會看到大量處于 TIME_WAIT 狀態(tài)的連接迄本,它們會占用大量內(nèi)存和端口資源嘉赎。這時,我們可以優(yōu)化與 TIME_WAIT 狀態(tài)相關(guān)的內(nèi)核選項公条,比如采取下面幾種措施。

  1. 增大處于 TIME_WAIT 狀態(tài)的連接數(shù)量 net.ipv4.tcp_max_tw_buckets 寥袭,并增大連接跟蹤表的大小 net.netfilter.nf_conntrack_max抓韩。
  2. 減小 net.ipv4.tcp_fin_timeout 和 net.netfilter.nf_conntrack_tcp_timeout_time_wait 谒拴,讓系統(tǒng)盡快釋放它們所占用的資源涉波。
  3. 開啟端口復(fù)用 net.ipv4.tcp_tw_reuse。這樣啤覆,被 TIME_WAIT 狀態(tài)占用的端口窗声,還能用到新建的連接中。
  4. 增大本地端口的范圍 net.ipv4.ip_local_port_range 笨觅。這樣就可以支持更多連接,提高整體的并發(fā)能力见剩。
  5. 增加最大文件描述符的數(shù)量。你可以使用 fs.nr_open 和 fs.file-max 固翰,分別增大進(jìn)程和系統(tǒng)的最大文件描述符數(shù);或在應(yīng)用程序的 systemd 配置文件中疗琉,配置 LimitNOFILE 歉铝,設(shè)置應(yīng)用程序的最大文件描述符數(shù)。

2.SYN 狀態(tài)相關(guān)的內(nèi)核選項

為了緩解 SYN FLOOD 等送火,利用 TCP 協(xié)議特點進(jìn)行攻擊而引發(fā)的性能問題先匪,你可以考慮優(yōu)化與 SYN 狀態(tài)相關(guān)的內(nèi)核選項,比如采取下面幾種措施坚俗。

  1. 增大 TCP 半連接的最大數(shù)量 net.ipv4.tcp_max_syn_backlog 岸裙,或者開啟 TCP SYN Cookies net.ipv4.tcp_syncookies ,來繞開半連接數(shù)量限制的問題(注意恩闻,這兩個選項不可同時使用)剧董。
  2. 減少 SYN_RECV 狀態(tài)的連接重傳 SYN+ACK 包的次數(shù) net.ipv4.tcp_synack_retries。

3.長連接

在長連接的場景中尉剩,通常使用 Keepalive 來檢測 TCP 連接的狀態(tài)毅臊,以便對端連接斷開后,可以自動回收皂林。但是宠蚂,系統(tǒng)默認(rèn)的 Keepalive 探測間隔和重試次數(shù),一般都無法滿足應(yīng)用程序的性能要求著隆。所以,這時候你需要優(yōu)化與 Keepalive 相關(guān)的內(nèi)核選項美浦,比如:

  1. 縮短最后一次數(shù)據(jù)包到 Keepalive 探測包的間隔時間 net.ipv4.tcp_keepalive_time浦辨;
  2. 縮短發(fā)送 Keepalive 探測包的間隔時間 net.ipv4.tcp_keepalive_intvl;
  3. 減少 Keepalive 探測失敗后币厕,一直到通知應(yīng)用程序前的重試次數(shù) net.ipv4.tcp_keepalive_probes芽腾。


    image.png

內(nèi)核線程

Linux 在啟動過程中,有三個特殊的進(jìn)程阴绢,也就是 PID 號最小的三個進(jìn)程艰躺。

  • 0 號進(jìn)程為 idle 進(jìn)程,這也是系統(tǒng)創(chuàng)建的第一個進(jìn)程左电,它在初始化 1 號和 2 號進(jìn)程后页响,演變?yōu)榭臻e任務(wù)。當(dāng) CPU 上沒有其他任務(wù)執(zhí)行時,就會運(yùn)行它陪腌。
  • 1 號進(jìn)程為 init 進(jìn)程烟瞧,通常是 systemd 進(jìn)程,在用戶態(tài)運(yùn)行强岸,用來管理其他用戶態(tài)進(jìn)程砾赔。
  • 2 號進(jìn)程為 kthreadd 進(jìn)程青灼,在內(nèi)核態(tài)運(yùn)行妓盲,用來管理內(nèi)核線程悯衬。
    要查找內(nèi)核線程,我們只需要從 2 號進(jìn)程開始筋粗,查找它的子孫進(jìn)程即可。比如丽已,你可以使用 ps 命令暇唾,來查找 kthreadd 的子進(jìn)程:
$ ps -f --ppid 2 -p 2
UID         PID   PPID  C STIME TTY          TIME CMD
root          2      0  0 12:02 ?        00:00:01 [kthreadd]
root          9      2  0 12:02 ?        00:00:21 [ksoftirqd/0]
root         10      2  0 12:02 ?        00:11:47 [rcu_sched]
root         11      2  0 12:02 ?        00:00:18 [migration/0]
...
root      11094      2  0 14:20 ?        00:00:00 [kworker/1:0-eve]
root      11647      2  0 14:27 ?        00:00:00 [kworker/0:2-cgr]

更簡單的:

$ ps -ef | grep "\[.*\]"
root         2     0  0 08:14 ?        00:00:00 [kthreadd]
root         3     2  0 08:14 ?        00:00:00 [rcu_gp]
root         4     2  0 08:14 ?        00:00:00 [rcu_par_gp]
...

常見內(nèi)核線程

  • kswapd0:用于內(nèi)存回收策州。在 Swap 變高 案例中,我曾介紹過它的工作原理旁仿。
  • kworker:用于執(zhí)行內(nèi)核工作隊列孽糖,分為綁定 CPU (名稱格式為 kworker/CPU86330)和未綁定 CPU(名稱格式為 kworker/uPOOL86330)兩類。
  • migration:在負(fù)載均衡過程中尘奏,把進(jìn)程遷移到 CPU 上病蛉。每個 CPU 都有一個 migration 內(nèi)核線程。
  • jbd2/sda1-8:jbd 是 Journaling Block Device 的縮寫俗孝,用來為文件系統(tǒng)提供日志功能魄健,以保證數(shù)據(jù)的完整性;名稱中的 sda1-8革骨,表示磁盤分區(qū)名稱和設(shè)備號。每個使用了 ext4 文件系統(tǒng)的磁盤分區(qū)卤橄,都會有一個 jbd2 內(nèi)核線程臂外。
  • pdflush:用于將內(nèi)存中的臟頁(被修改過,但還未寫入磁盤的文件頁)寫入磁盤(已經(jīng)在 3.10 中合并入了 kworker 中)嚎货。
    pstack無法觀察內(nèi)核線程蔫浆。
    perf可以
# 采樣30s后退出
$ perf record -a -g -p 9 -- sleep 30
image.png

內(nèi)核的調(diào)用非常復(fù)雜瓦盛,上圖來看大概是這么幾個過程。

  • net_rx_action 和 netif_receive_skb挠唆,表明這是接收網(wǎng)絡(luò)包(rx 表示 receive)嘱吗。
  • br_handle_frame ,表明網(wǎng)絡(luò)包經(jīng)過了網(wǎng)橋(br 表示 bridge)俄讹。
  • br_nf_pre_routing 绕德,表明在網(wǎng)橋上執(zhí)行了 netfilter 的 PREROUTING(nf 表示 netfilter)耻蛇。而我們已經(jīng)知道 PREROUTING 主要用來執(zhí)行 DNAT,所以可以猜測這里有 DNAT 發(fā)生城丧。
  • br_pass_frame_up亡哄,表明網(wǎng)橋處理后布疙,再交給橋接的其他橋接網(wǎng)卡進(jìn)一步處理愿卸。比如截型,在新的網(wǎng)卡上接收網(wǎng)絡(luò)包宦焦、執(zhí)行 netfilter 過濾規(guī)則等等。
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末酝豪,一起剝皮案震驚了整個濱河市精堕,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌瘫证,老刑警劉巖庄撮,帶你破解...
    沈念sama閱讀 212,029評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件重窟,死亡現(xiàn)場離奇詭異,居然都是意外死亡扭仁,警方通過查閱死者的電腦和手機(jī)厅翔,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,395評論 3 385
  • 文/潘曉璐 我一進(jìn)店門刀闷,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人甸昏,你說我怎么就攤上這事施蜜。” “怎么了缸沃?”我有些...
    開封第一講書人閱讀 157,570評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長检盼。 經(jīng)常有香客問我翘单,道長,這世上最難降的妖魔是什么东羹? 我笑而不...
    開封第一講書人閱讀 56,535評論 1 284
  • 正文 為了忘掉前任属提,我火速辦了婚禮美尸,結(jié)果婚禮上冤议,老公的妹妹穿的比我還像新娘。我一直安慰自己师坎,他們只是感情好恕酸,可當(dāng)我...
    茶點故事閱讀 65,650評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著胯陋,像睡著了一般蕊温。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上遏乔,一...
    開封第一講書人閱讀 49,850評論 1 290
  • 那天义矛,我揣著相機(jī)與錄音,去河邊找鬼盟萨。 笑死凉翻,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的制轰。 我是一名探鬼主播,決...
    沈念sama閱讀 39,006評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼胞谭,長吁一口氣:“原來是場噩夢啊……” “哼垃杖!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起丈屹,我...
    開封第一講書人閱讀 37,747評論 0 268
  • 序言:老撾萬榮一對情侶失蹤缩滨,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體脉漏,經(jīng)...
    沈念sama閱讀 44,207評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,536評論 2 327
  • 正文 我和宋清朗相戀三年袖牙,在試婚紗的時候發(fā)現(xiàn)自己被綠了侧巨。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,683評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡鞭达,死狀恐怖司忱,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情畴蹭,我是刑警寧澤坦仍,帶...
    沈念sama閱讀 34,342評論 4 330
  • 正文 年R本政府宣布,位于F島的核電站叨襟,受9級特大地震影響繁扎,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜糊闽,卻給世界環(huán)境...
    茶點故事閱讀 39,964評論 3 315
  • 文/蒙蒙 一梳玫、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧右犹,春花似錦提澎、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,772評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至掂墓,卻和暖如春谦纱,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背梆暮。 一陣腳步聲響...
    開封第一講書人閱讀 32,004評論 1 266
  • 我被黑心中介騙來泰國打工服协, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人啦粹。 一個月前我還...
    沈念sama閱讀 46,401評論 2 360
  • 正文 我出身青樓偿荷,卻偏偏與公主長得像,于是被迫代替她去往敵國和親唠椭。 傳聞我的和親對象是個殘疾皇子跳纳,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,566評論 2 349