最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會(huì)員登陸 & 注冊(cè)

深入講解Linux上TCP的幾個(gè)內(nèi)核參數(shù)調(diào)優(yōu)

2022-11-17 18:19 作者:補(bǔ)給站Linux內(nèi)核  | 我要投稿


Linux作為一個(gè)強(qiáng)大的操作系統(tǒng),提供了一系列內(nèi)核參數(shù)供我們進(jìn)行調(diào)優(yōu)。光TCP的調(diào)優(yōu)參數(shù)就有50多個(gè)。在和線上問(wèn)題斗智斗勇的過(guò)程中,筆者積累了一些在內(nèi)網(wǎng)環(huán)境應(yīng)該進(jìn)行調(diào)優(yōu)的參數(shù)。在此分享出來(lái),希望對(duì)大家有所幫助。

調(diào)優(yōu)清單

好了,在這里先列出調(diào)優(yōu)清單。請(qǐng)記住,這里只是筆者在內(nèi)網(wǎng)進(jìn)行TCP內(nèi)核參數(shù)調(diào)優(yōu)的經(jīng)驗(yàn),僅供參考。同時(shí),筆者還會(huì)在余下的博客里面詳細(xì)解釋了為什么要進(jìn)行這些調(diào)優(yōu)!



tcp_max_syn_backlog,somaxconn,tcp_abort_on_overflow

tcp_max_syn_backlog,somaxconn,tcp_abort_on_overflow這三個(gè)參數(shù)是關(guān)于

內(nèi)核TCP連接緩沖隊(duì)列的設(shè)置。如果應(yīng)用層來(lái)不及將已經(jīng)三次握手建立成功的TCP連接從隊(duì)列中取出,溢出了這個(gè)緩沖隊(duì)列(全連接隊(duì)列)之后就會(huì)丟棄這個(gè)連接。如下圖所示:


從而產(chǎn)生一些詭異的現(xiàn)象,這個(gè)現(xiàn)象詭異之處就在于,是在TCP第三次握手的時(shí)候丟棄連接


就如圖中所示,第二次握手的SYNACK發(fā)送給client端了。所以就會(huì)出現(xiàn)client端認(rèn)為連接成功,而Server端確已經(jīng)丟棄了這個(gè)連接的現(xiàn)象!由于無(wú)法感知到Server已經(jīng)丟棄了連接。

所以如果沒(méi)有心跳的話,只有在發(fā)出第一個(gè)請(qǐng)求后,Server才會(huì)發(fā)送一個(gè)reset端通知這個(gè)連接已經(jīng)被丟棄了,建立連接后第二天再用,也會(huì)報(bào)錯(cuò)!所以我們要調(diào)大Backlog隊(duì)列!

當(dāng)然了,為了盡量避免第一筆調(diào)用失敗問(wèn)題,我們也同時(shí)要設(shè)置

設(shè)置這個(gè)值以后,Server端內(nèi)核就會(huì)在這個(gè)連接被溢出之后發(fā)送一個(gè)reset包給client端。


如果我們的client端是NIO的話,就可以收到一個(gè)socket close的事件以感知到連接被關(guān)閉!


【文章福利】小編推薦自己的Linux內(nèi)核技術(shù)交流群:【891587639】整理了一些個(gè)人覺(jué)得比較好的學(xué)習(xí)書(shū)籍、視頻資料共享在群文件里面,有需要的可以自行添加哦?。。。ê曨l教程、電子書(shū)、實(shí)戰(zhàn)項(xiàng)目及代碼)? ? ?




注意Java默認(rèn)的Backlog是50

這個(gè)TCP Backlog的隊(duì)列大小值是min(tcp_max_syn_backlog,somaxconn,應(yīng)用層設(shè)置的backlog),而Java如果不做額外設(shè)置,Backlog默認(rèn)值僅僅只有50。C語(yǔ)言在使用listen調(diào)用的時(shí)候需要傳進(jìn)Backlog參數(shù)。

tcp_tw_recycle

tcp_tw_recycle這個(gè)參數(shù)一般是用來(lái)抑制TIME_WAIT數(shù)量的,但是它有一個(gè)副作用。即在tcp_timestamps開(kāi)啟(Linux默認(rèn)開(kāi)啟),tcp_tw_recycle會(huì)經(jīng)常導(dǎo)致下面這種現(xiàn)象。


也即,如果你的Server開(kāi)啟了tcp_tw_recycle,那么別人如果通過(guò)NAT之類的調(diào)用你的Server的話,NAT后面的機(jī)器只有一臺(tái)機(jī)器能正常工作,其它情況大概率失敗。具體原因呢由下圖所示:


在tcp_tw_recycle=1同時(shí)tcp_timestamps(默認(rèn)開(kāi)啟的情況下),對(duì)同一個(gè)IP的連接會(huì)做這樣的限制,也即之前后建立的連接的時(shí)間戳必須要大于之前建立連接的最后時(shí)間戳,但是經(jīng)過(guò)NAT的一個(gè)IP后面是不同的機(jī)器,時(shí)間戳相差極大,就會(huì)導(dǎo)致內(nèi)核直接丟棄時(shí)間戳較低的連接的現(xiàn)象。由于這個(gè)參數(shù)導(dǎo)致的問(wèn)題,高版本內(nèi)核已經(jīng)去掉了這個(gè)參數(shù)。如果考慮TIME_WAIT問(wèn)題,可以考慮設(shè)置一下

tcp_syn_retries

這個(gè)參數(shù)值得是client發(fā)送SYN如果server端不回復(fù)的話,重傳SYN的次數(shù)。對(duì)我們的直接影響呢就是connet建立連接時(shí)的超時(shí)時(shí)間。當(dāng)然Java通過(guò)一些C原生系統(tǒng)調(diào)用的組合使得我們可以進(jìn)行超時(shí)時(shí)間的設(shè)置。在Linux里面默認(rèn)設(shè)置是5,下面給出建議值3和默認(rèn)值5之間的超時(shí)時(shí)間。

|tcp_syn_retries|timeout|

|—-| —- |

|1|min(so_sndtimeo,3s)|

|2|min(so_sndtimeo,7s)|

|3|min(so_sndtimeo,15s)|

|4|min(so_sndtimeo,31s)|

|5|min(so_sndtimeo,63s)|

下圖給出了,重傳和超時(shí)情況的對(duì)應(yīng)圖:


當(dāng)然了,不同內(nèi)核版本的超時(shí)時(shí)間可能不一樣,因?yàn)槌跏糝TO在內(nèi)核小版本間都會(huì)有細(xì)微的變化。所以,有時(shí)候在抓包時(shí)候可能會(huì)出現(xiàn)(3,6,12……)這樣的序列。當(dāng)然Java的API有超時(shí)時(shí)間:

所以,對(duì)于Java而言,這個(gè)內(nèi)核參數(shù)的設(shè)置沒(méi)有那么重要。但是,有些代碼可能會(huì)有忘了設(shè)置timeout的情況,例如某個(gè)版本的Kafka就是,所以它在我們一些混沌測(cè)試的情況下,容災(zāi)恢復(fù)的時(shí)間會(huì)達(dá)到一分多鐘,主要時(shí)間就是卡在connect上面-_-!,而這時(shí)我們的tcp_syn_retries設(shè)置的是5,也即超時(shí)時(shí)間63s。減少這個(gè)恢復(fù)時(shí)間的手段就是:

tcp_retries2

tcp_retries2這個(gè)參數(shù)表面意思是在傳輸過(guò)程中tcp的重傳次數(shù)。但在某個(gè)版本之后Linux內(nèi)核僅僅用這個(gè)tcp_retries2來(lái)計(jì)算超時(shí)時(shí)間,在這段時(shí)間的重傳次數(shù)純粹由RTO等環(huán)境因素決定,重傳超時(shí)時(shí)間在5/15下的表現(xiàn)為:

|tcp_retries2|對(duì)端無(wú)響應(yīng)|

| —- | :—- |:—-|

|5|25.6s-51.2s根據(jù)動(dòng)態(tài)rto定|

|15|924.6s-1044.6s根據(jù)動(dòng)態(tài)rto定|

如果我們?cè)趹?yīng)用層設(shè)置的Socket所有ReadTimeout都很小的話(例如3s),這個(gè)內(nèi)核參數(shù)調(diào)整是沒(méi)有必要的。但是,筆者經(jīng)常發(fā)現(xiàn)有的系統(tǒng),因?yàn)橐粌蓚€(gè)慢的接口或者SQL,所以將ReadTimeout設(shè)的很大的情況。


平常這種情況是沒(méi)有問(wèn)題的,因?yàn)槁?qǐng)求頻率很低,不會(huì)對(duì)系統(tǒng)造成什么風(fēng)險(xiǎn)。但是,物理機(jī)突然宕機(jī)時(shí)候的情況就不一樣了,由于ReadTimeOut設(shè)置的過(guò)大,導(dǎo)致所有落到這臺(tái)宕機(jī)的機(jī)器都會(huì)在min(ReadTimeOut,(924.6s-1044.6s)(Linux默認(rèn)tcp_retries2是15))后才能從read系統(tǒng)調(diào)用返回。假設(shè)ReadTimeout設(shè)置了個(gè)5min,系統(tǒng)總線程數(shù)是200,那么只要5min內(nèi)有200個(gè)請(qǐng)求落到宕機(jī)的server就會(huì)使A系統(tǒng)失去響應(yīng)!


但如果將tcp_retries2設(shè)置為5,那么超時(shí)返回時(shí)間即為min(ReadTimeOut 5min,25.6-51.2s),也就是30s左右,極大的緩解了這一情況。

但是針對(duì)這種現(xiàn)象,最好要做資源上的隔離,例如線程上的隔離或者機(jī)器級(jí)的隔離。


golang的goroutine調(diào)度模型就可以很好的解決線程資源不夠的問(wèn)題,但缺點(diǎn)是goroutine里面不能有阻塞的系統(tǒng)調(diào)用,不然也會(huì)和上面一樣,但僅僅對(duì)于系統(tǒng)之間互相調(diào)用而言,都是非阻塞IO,所以golang做微服務(wù)還是非常Nice的。當(dāng)然了我大Java用純IO事件觸發(fā)編寫(xiě)代碼也不會(huì)有問(wèn)題,就是對(duì)心智負(fù)擔(dān)太高-_-!

物理機(jī)突然宕機(jī)和進(jìn)程宕不一樣

值得注意的是,物理機(jī)宕機(jī)和進(jìn)程宕但內(nèi)核還存在表現(xiàn)完全不一樣。


僅僅進(jìn)程宕而內(nèi)核存活,那么內(nèi)核會(huì)立馬發(fā)送reset給對(duì)端,從而不會(huì)卡住A系統(tǒng)的線程資源。

tcp_slow_start_after_idle

還有一個(gè)可能需要調(diào)整的參數(shù)是tcp_slow_start_after_idle,Linux默認(rèn)是1,即開(kāi)啟狀態(tài)。開(kāi)啟這個(gè)參數(shù)后,我們的TCP擁塞窗口會(huì)在一個(gè)RTO時(shí)間空閑之后重置為初始擁塞窗口(CWND)大小,這無(wú)疑大幅的減少了長(zhǎng)連接的優(yōu)勢(shì)。對(duì)應(yīng)Linux源碼為:

關(guān)閉這個(gè)參數(shù)后,無(wú)疑會(huì)提高某些請(qǐng)求的傳輸速度(在帶寬夠的情況下)。

當(dāng)然了,Linux啟用這個(gè)參數(shù)也是有理由的,如果我們的網(wǎng)絡(luò)情況是時(shí)刻在變化的,例如拿個(gè)手機(jī)到處移動(dòng),那么將擁塞窗口重置確實(shí)是個(gè)不錯(cuò)的選項(xiàng)。但是就我們內(nèi)網(wǎng)系統(tǒng)間調(diào)用而言,是不太必要的了。

初始CWND大小

毫無(wú)疑問(wèn),新建連接之后的初始TCP擁塞窗口大小也直接影響到我們的請(qǐng)求速率。在Linux2.6.32源碼中,其初始擁塞窗口是(2-4個(gè))mss大小,對(duì)應(yīng)于內(nèi)網(wǎng)估計(jì)也就是(2.8-5.6K)(MTU 1500),這個(gè)大小對(duì)于某些大請(qǐng)求可能有點(diǎn)捉襟見(jiàn)肘。

在Linux 2.6.39以上或者某些RedHat維護(hù)的小版本中已經(jīng)把CWND

增大到RFC 6928所規(guī)定的的10段,也就是在內(nèi)網(wǎng)里面估計(jì)14K左右(MTU 1500)。

總結(jié)

Linux提供了一大堆內(nèi)參參數(shù)供我們進(jìn)行調(diào)優(yōu),其默認(rèn)設(shè)置的參數(shù)在很多情況下并不是最佳實(shí)踐,所以我們需要潛心研究,找到最適合當(dāng)前環(huán)境的組合。


原文作者:無(wú)毀的湖光



深入講解Linux上TCP的幾個(gè)內(nèi)核參數(shù)調(diào)優(yōu)的評(píng)論 (共 條)

分享到微博請(qǐng)遵守國(guó)家法律
平利县| 宁陕县| 丹江口市| 台中市| 花莲市| 汾阳市| 平遥县| 卢湾区| 玛多县| 大理市| 邵东县| 福鼎市| 武清区| 大姚县| 闵行区| 托克逊县| 汉源县| 安福县| 大同县| 陈巴尔虎旗| 保靖县| 南康市| 绥棱县| 邵东县| 老河口市| 自治县| 辽阳县| 乐山市| 芦溪县| 渝北区| 广州市| 新蔡县| 晴隆县| 肃南| 漳浦县| 博爱县| 阆中市| 同仁县| 玛纳斯县| 新乐市| 泸水县|