自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Linux 網(wǎng)絡(luò)性能的 15 個(gè)優(yōu)化建議

系統(tǒng) Linux
今天我們一起來(lái)了解下Linux 網(wǎng)絡(luò)性能的 15 個(gè)優(yōu)化建議都有哪些。

建議1:盡量減少不必要的網(wǎng)絡(luò) IO

我要給出的第一個(gè)建議就是不必要用網(wǎng)絡(luò) IO 的盡量不用。

是的,網(wǎng)絡(luò)在現(xiàn)代的互聯(lián)網(wǎng)世界里承載了很重要的角色。用戶通過(guò)網(wǎng)絡(luò)請(qǐng)求線上服務(wù)、服務(wù)器通過(guò)網(wǎng)絡(luò)讀取數(shù)據(jù)庫(kù)中數(shù)據(jù),通過(guò)網(wǎng)絡(luò)構(gòu)建能力無(wú)比強(qiáng)大分布式系統(tǒng)。網(wǎng)絡(luò)很好,能降低模塊的開(kāi)發(fā)難度,也能用它搭建出更強(qiáng)大的系統(tǒng)。但是這不是你濫用它的理由!

原因是即使是本機(jī)網(wǎng)絡(luò) IO 開(kāi)銷仍然是很大的。先說(shuō)發(fā)送一個(gè)網(wǎng)絡(luò)包,首先得從用戶態(tài)切換到內(nèi)核態(tài),花費(fèi)一次系統(tǒng)調(diào)用的開(kāi)銷。進(jìn)入到內(nèi)核以后,又得經(jīng)過(guò)冗長(zhǎng)的協(xié)議棧,這會(huì)花費(fèi)不少的 CPU 周期,最后進(jìn)入環(huán)回設(shè)備的“驅(qū)動(dòng)程序”。接收端呢,軟中斷花費(fèi)不少的 CPU 周期又得經(jīng)過(guò)接收協(xié)議棧的處理,最后喚醒或者通知用戶進(jìn)程來(lái)處理。當(dāng)服務(wù)端處理完以后,還得把結(jié)果再發(fā)過(guò)來(lái)。又得來(lái)這么一遍,最后你的進(jìn)程才能收到結(jié)果。你說(shuō)麻煩不麻煩。另外還有個(gè)問(wèn)題就是多個(gè)進(jìn)程協(xié)作來(lái)完成一項(xiàng)工作就必然會(huì)引入更多的進(jìn)程上下文切換開(kāi)銷,這些開(kāi)銷從開(kāi)發(fā)視角來(lái)看,做的其實(shí)都是無(wú)用功。

上面我們還分析的只是本機(jī)網(wǎng)絡(luò) IO,如果是跨機(jī)器的還得會(huì)有雙方網(wǎng)卡的 DMA 拷貝過(guò)程,以及兩端之間的網(wǎng)絡(luò) RTT 耗時(shí)延遲。所以,網(wǎng)絡(luò)雖好,但也不能隨意濫用!

建議2:盡量合并網(wǎng)絡(luò)請(qǐng)求

在可能的情況下,盡可能地把多次的網(wǎng)絡(luò)請(qǐng)求合并到一次,這樣既節(jié)約了雙端的 CPU 開(kāi)銷,也能降低多次 RTT 導(dǎo)致的耗時(shí)。

我們舉個(gè)實(shí)踐中的例子可能更好理解。假如有一個(gè) redis,里面存了每一個(gè) App 的信息(應(yīng)用名、包名、版本、截圖等等)。你現(xiàn)在需要根據(jù)用戶安裝應(yīng)用列表來(lái)查詢數(shù)據(jù)庫(kù)中有哪些應(yīng)用比用戶的版本更新,如果有則提醒用戶更新。

那么最好不要寫(xiě)出如下的代碼:

<?php 
for(安裝列表 as 包名){
redis->get(包名)
...
}

上面這段代碼功能上實(shí)現(xiàn)上沒(méi)問(wèn)題,問(wèn)題在于性能。據(jù)我們統(tǒng)計(jì)現(xiàn)代用戶平均安裝 App 的數(shù)量在 60 個(gè)左右。那這段代碼在運(yùn)行的時(shí)候,每當(dāng)用戶來(lái)請(qǐng)求一次,你的服務(wù)器就需要和 redis 進(jìn)行 60 次網(wǎng)絡(luò)請(qǐng)求??偤臅r(shí)最少是 60 個(gè) RTT 起。更好的方法是應(yīng)該使用 redis 中提供的批量獲取命令,如 hmget、pipeline等,經(jīng)過(guò)一次網(wǎng)絡(luò) IO 就獲取到所有想要的數(shù)據(jù),如圖。

Linux 網(wǎng)絡(luò)性能的 15 個(gè)優(yōu)化建議

建議3:調(diào)用者與被調(diào)用機(jī)器盡可能部署的近一些

在前面的章節(jié)中我們看到在握手一切正常的情況下, TCP 握手的時(shí)間基本取決于兩臺(tái)機(jī)器之間的 RTT 耗時(shí)。雖然我們沒(méi)辦法徹底去掉這個(gè)耗時(shí),但是我們卻有辦法把 RTT 降低,那就是把客戶端和服務(wù)器放得足夠的近一些。盡量把每個(gè)機(jī)房?jī)?nèi)部的數(shù)據(jù)請(qǐng)求都在本地機(jī)房解決,減少跨地網(wǎng)絡(luò)傳輸。

舉例,假如你的服務(wù)是部署在北京機(jī)房的,你調(diào)用的 mysql、redis最好都位于北京機(jī)房?jī)?nèi)部。盡量不要跨過(guò)千里萬(wàn)里跑到廣東機(jī)房去請(qǐng)求數(shù)據(jù),即使你有專線,耗時(shí)也會(huì)大大增加!在機(jī)房?jī)?nèi)部的服務(wù)器之間的 RTT 延遲大概只有零點(diǎn)幾毫秒,同地區(qū)的不同機(jī)房之間大約是 1 ms 多一些。但如果從北京跨到廣東的話,延遲將是 30 - 40 ms 左右,幾十倍的上漲!

建議4:內(nèi)網(wǎng)調(diào)用不要用外網(wǎng)域名

假如說(shuō)你所在負(fù)責(zé)的服務(wù)需要調(diào)用兄弟部門(mén)的一個(gè)搜索接口,假設(shè)接口是:"http://www.sogou.com/wq?key=開(kāi)發(fā)內(nèi)功修煉"。

那既然是兄弟部門(mén),那很可能這個(gè)接口和你的服務(wù)是部署在一個(gè)機(jī)房的。即使沒(méi)有部署在一個(gè)機(jī)房,一般也是有專線可達(dá)的。所以不要直接請(qǐng)求 www.sogou.com, 而是應(yīng)該使用該服務(wù)在公司對(duì)應(yīng)的內(nèi)網(wǎng)域名。在我們公司內(nèi)部,每一個(gè)外網(wǎng)服務(wù)都會(huì)配置一個(gè)對(duì)應(yīng)的內(nèi)網(wǎng)域名,我相信你們公司也有。

為什么要這么做,原因有以下幾點(diǎn)

1)外網(wǎng)接口慢。本來(lái)內(nèi)網(wǎng)可能過(guò)個(gè)交換機(jī)就能達(dá)到兄弟部門(mén)的機(jī)器,非得上外網(wǎng)兜一圈再回來(lái),時(shí)間上肯定會(huì)慢。

2)帶寬成本高。在互聯(lián)網(wǎng)服務(wù)里,除了機(jī)器以外,另外一塊很大的成本就是 IDC 機(jī)房的出入口帶寬成本。兩臺(tái)機(jī)器在內(nèi)網(wǎng)不管如何通信都不涉及到帶寬的計(jì)算。但是一旦你去外網(wǎng)兜了一圈回來(lái),行了,一進(jìn)一出全部要繳帶寬費(fèi),你說(shuō)虧不虧??!

3)NAT 單點(diǎn)瓶頸。一般的服務(wù)器都沒(méi)有外網(wǎng) IP,所以要想請(qǐng)求外網(wǎng)的資源,必須要經(jīng)過(guò) NAT 服務(wù)器。但是一個(gè)公司的機(jī)房里幾千臺(tái)服務(wù)器中,承擔(dān) NAT 角色的可能就那么幾臺(tái)。它很容易成為瓶頸。我們的業(yè)務(wù)就遇到過(guò)好幾次 NAT 故障導(dǎo)致外網(wǎng)請(qǐng)求失敗的情形。NAT 機(jī)器掛了,你的服務(wù)可能也就掛了,故障率大大增加。

建議5:調(diào)整網(wǎng)卡 RingBuffer 大小

在 Linux 的整個(gè)網(wǎng)絡(luò)棧中,RingBuffer 起到一個(gè)任務(wù)的收發(fā)中轉(zhuǎn)站的角色。對(duì)于接收過(guò)程來(lái)講,網(wǎng)卡負(fù)責(zé)往 RingBuffer 中寫(xiě)入收到的數(shù)據(jù)幀,ksoftirqd 內(nèi)核線程負(fù)責(zé)從中取走處理。只要 ksoftirqd 線程工作的足夠快,RingBuffer 這個(gè)中轉(zhuǎn)站就不會(huì)出現(xiàn)問(wèn)題。

但是我們?cè)O(shè)想一下,假如某一時(shí)刻,瞬間來(lái)了特別多的包,而 ksoftirqd 處理不過(guò)來(lái)了,會(huì)發(fā)生什么?這時(shí) RingBuffer 可能瞬間就被填滿了,后面再來(lái)的包網(wǎng)卡直接就會(huì)丟棄,不做任何處理!

Linux 網(wǎng)絡(luò)性能的 15 個(gè)優(yōu)化建議

通過(guò) ethtool 就可以加大 RingBuffer 這個(gè)“中轉(zhuǎn)倉(cāng)庫(kù)”的大小。。

# ethtool -G eth1 rx 4096 tx 4096

Linux 網(wǎng)絡(luò)性能的 15 個(gè)優(yōu)化建議

這樣網(wǎng)卡會(huì)被分配更大一點(diǎn)的”中轉(zhuǎn)站“,可以解決偶發(fā)的瞬時(shí)的丟包。不過(guò)這種方法有個(gè)小副作用,那就是排隊(duì)的包過(guò)多會(huì)增加處理網(wǎng)絡(luò)包的延時(shí)。所以應(yīng)該讓內(nèi)核處理網(wǎng)絡(luò)包的速度更快一些更好,而不是讓網(wǎng)絡(luò)包傻傻地在 RingBuffer 中排隊(duì)。我們后面會(huì)再介紹到 RSS ,它可以讓更多的核來(lái)參與網(wǎng)絡(luò)包接收。

建議6:減少內(nèi)存拷貝

假如你要發(fā)送一個(gè)文件給另外一臺(tái)機(jī)器上,那么比較基礎(chǔ)的做法是先調(diào)用 read 把文件讀出來(lái),再調(diào)用 send 把數(shù)據(jù)把數(shù)據(jù)發(fā)出去。這樣數(shù)據(jù)需要頻繁地在內(nèi)核態(tài)內(nèi)存和用戶態(tài)內(nèi)存之間拷貝,如圖 9.6。

Linux 網(wǎng)絡(luò)性能的 15 個(gè)優(yōu)化建議

目前減少內(nèi)存拷貝主要有兩種方法,分別是使用 mmap 和 sendfile 兩個(gè)系統(tǒng)調(diào)用。使用 mmap 系統(tǒng)調(diào)用的話,映射進(jìn)來(lái)的這段地址空間的內(nèi)存在用戶態(tài)和內(nèi)核態(tài)都是可以使用的。如果你發(fā)送數(shù)據(jù)是發(fā)的是 mmap 映射進(jìn)來(lái)的數(shù)據(jù),則內(nèi)核直接就可以從地址空間中讀取,這樣就節(jié)約了一次從內(nèi)核態(tài)到用戶態(tài)的拷貝過(guò)程。

Linux 網(wǎng)絡(luò)性能的 15 個(gè)優(yōu)化建議

不過(guò)在 mmap 發(fā)送文件的方式里,系統(tǒng)調(diào)用的開(kāi)銷并沒(méi)有減少,還是發(fā)生兩次內(nèi)核態(tài)和用戶態(tài)的上下文切換。如果你只是想把一個(gè)文件發(fā)送出去,而不關(guān)心它的內(nèi)容,則可以調(diào)用另外一個(gè)做的更極致的系統(tǒng)調(diào)用 - sendfile。在這個(gè)系統(tǒng)調(diào)用里,徹底把讀文件和發(fā)送文件給合并起來(lái)了,系統(tǒng)調(diào)用的開(kāi)銷又省了一次。再配合絕大多數(shù)網(wǎng)卡都支持的"分散-收集"(Scatter-gather)DMA 功能。可以直接從 PageCache 緩存區(qū)中 DMA 拷貝到網(wǎng)卡中。這樣絕大部分的 CPU 拷貝操作就都省去了。

Linux 網(wǎng)絡(luò)性能的 15 個(gè)優(yōu)化建議

建議7:使用 eBPF 繞開(kāi)協(xié)議棧的本機(jī) IO

如果你的業(yè)務(wù)中涉及到大量的本機(jī)網(wǎng)絡(luò) IO 可以考慮這個(gè)優(yōu)化方案。本機(jī)網(wǎng)絡(luò) IO 和跨機(jī) IO 比較起來(lái),確實(shí)是節(jié)約了驅(qū)動(dòng)上的一些開(kāi)銷。發(fā)送數(shù)據(jù)不需要進(jìn) RingBuffer 的驅(qū)動(dòng)隊(duì)列,直接把 skb 傳給接收協(xié)議棧(經(jīng)過(guò)軟中斷)。但是在內(nèi)核其它組件上,可是一點(diǎn)都沒(méi)少,系統(tǒng)調(diào)用、協(xié)議棧(傳輸層、網(wǎng)絡(luò)層等)、設(shè)備子系統(tǒng)整個(gè)走 了一個(gè)遍。連“驅(qū)動(dòng)”程序都走了(雖然對(duì)于回環(huán)設(shè)備來(lái)說(shuō)這個(gè)驅(qū)動(dòng)只是一個(gè)純軟件的虛擬出來(lái)的東東)。

如果想用本機(jī)網(wǎng)絡(luò) IO,但是又不想頻繁地在協(xié)議棧中繞來(lái)繞去。那么你可以試試 eBPF。使用 eBPF 的 sockmap 和 sk redirect 可以繞過(guò) TCP/IP 協(xié)議棧,而被直接發(fā)送給接收端的 socket,業(yè)界已經(jīng)有公司在這么做了。

Linux 網(wǎng)絡(luò)性能的 15 個(gè)優(yōu)化建議

建議8:盡量少用 recvfrom 等進(jìn)程阻塞的方式

在使用了 recvfrom 阻塞方式來(lái)接收 socket 上數(shù)據(jù)的時(shí)候。每次一個(gè)進(jìn)程專?為了等一個(gè) socket 上的數(shù)據(jù)就得被從 CPU 上拿下來(lái)。然后再換上另一個(gè) 進(jìn)程。等到數(shù)據(jù) ready 了,睡眠的進(jìn)程又會(huì)被喚醒??偣矁纱芜M(jìn)程上下文切換開(kāi)銷。如果我們服務(wù)器上需要有大量的用戶請(qǐng)求需要處理,那就需要有很多的進(jìn)程存在,而且不停地切換來(lái)切換去。這樣的缺點(diǎn)有如下這么幾個(gè):

  • 因?yàn)槊總€(gè)進(jìn)程只能同時(shí)等待一條連接,所以需要大量的進(jìn)程。
  • 進(jìn)程之間互相切換的時(shí)候需要消耗很多 CPU 周期,一次切換大約是 3 - 5 us 左右。
  • 頻繁的切換導(dǎo)致 L1、L2、L3 等高速緩存的效果大打折扣

大家可能以為這種網(wǎng)絡(luò) IO 模型很少見(jiàn)了。但其實(shí)在很多傳統(tǒng)的客戶端 SDK 中,比如 mysql、redis 和 kafka 仍然是沿用了這種方式。

建議9:使用成熟的網(wǎng)絡(luò)庫(kù)

使用 epoll 可以高效地管理海量的 socket。在服務(wù)器端。我們有各種成熟的網(wǎng)絡(luò)庫(kù)進(jìn)行使用。這些網(wǎng)絡(luò)庫(kù)都對(duì) epoll 使用了不同程度的封裝。

首先第一個(gè)要給大家參考的是 Redis。老版本的 Redis 里單進(jìn)程高效地使用 epoll 就能支持每秒數(shù)萬(wàn) QPS 的高性能。如果你的服務(wù)是單進(jìn)程的,可以參考 Redis 在網(wǎng)絡(luò) IO 這塊的源碼。

如果是多線程的,線程之間的分工有很多種模式。那么哪個(gè)線程負(fù)責(zé)等待讀 IO 事件,哪個(gè)線程負(fù)責(zé)處理用戶請(qǐng)求,哪個(gè)線程又負(fù)責(zé)給用戶寫(xiě)返回。根據(jù)分工的不同,又衍生出單 Reactor、多 Reactor、以及 Proactor 等多種模式。大家也不必頭疼,只要理解了這些原理之后選擇一個(gè)性能不錯(cuò)的網(wǎng)絡(luò)庫(kù)就可以了。比如 PHP 中的 Swoole、Golang 的 net 包、Java 中的 netty 、C++ 中的 Sogou Workflow 都封裝的非常的不錯(cuò)。

建議10:使用 Kernel-ByPass 新技術(shù)

如果你的服務(wù)對(duì)網(wǎng)絡(luò)要求確實(shí)特別特特別的高,而且各種優(yōu)化措施也都用過(guò)了,那么現(xiàn)在還有終極優(yōu)化大招 -- Kernel-ByPass 技術(shù)。

內(nèi)核在接收網(wǎng)絡(luò)包的時(shí)候要經(jīng)過(guò)很?的收發(fā)路徑。在這期間牽涉到很多內(nèi)核組件之間的協(xié)同、協(xié)議棧的處理、以及內(nèi)核態(tài)和用戶態(tài)的拷貝和切換。Kernel-ByPass 這類的技術(shù)方案就是繞開(kāi)內(nèi)核協(xié)議棧,自己在用戶態(tài)來(lái)實(shí)現(xiàn)網(wǎng)絡(luò)包的收發(fā)。這樣不但避開(kāi)了繁雜的內(nèi)核協(xié)議棧處理,也減少了頻繁了內(nèi)核態(tài)用戶態(tài)之間的拷貝和切換,性能將發(fā)揮到極致!

目前我所知道的方案有 SOLARFLARE 的軟硬件方案、DPDK 等等。如果大家感興趣,可以多去了解一下!

Linux 網(wǎng)絡(luò)性能的 15 個(gè)優(yōu)化建議

建議11:配置充足的端口范圍

客戶端在調(diào)用 connect 系統(tǒng)調(diào)用發(fā)起連接的時(shí)候,需要先選擇一個(gè)可用的端口。內(nèi)核在選用端口的時(shí)候,是采用從可用端口范圍中某一個(gè)隨機(jī)位置開(kāi)始遍歷的方式。如果端口不充足的話,內(nèi)核可能需要循環(huán)撞很多次才能選上一個(gè)可用的。這也會(huì)導(dǎo)致花費(fèi)更多的 CPU 周期在內(nèi)部的哈希表查找以及可能的自旋鎖等待上。因此不要等到端口用盡報(bào)錯(cuò)了才開(kāi)始加大端口范圍,而且應(yīng)該一開(kāi)始的時(shí)候就保持一個(gè)比較充足的值。

# vi /etc/sysctl.conf
net.ipv4.ip_local_port_range = 5000 65000
# sysctl -p //使配置生效

如果端口加大了仍然不夠用,那么可以考慮開(kāi)啟端口 reuse 和 recycle。這樣端口在連接斷開(kāi)的時(shí)候就不需要等待 2MSL 的時(shí)間了,可以快速回收。開(kāi)啟這個(gè)參數(shù)之前需要保證 tcp_timestamps 是開(kāi)啟的。

# vi /etc/sysctl.conf
net.ipv4.tcp_timestamps = 1
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tw_recycle = 1
# sysctl -p

建議12:小心連接隊(duì)列溢出

服務(wù)器端使用了兩個(gè)連接隊(duì)列來(lái)響應(yīng)來(lái)自客戶端的握手請(qǐng)求。這兩個(gè)隊(duì)列的長(zhǎng)度是在服務(wù)器 listen 的時(shí)候就確定好了的。如果發(fā)生溢出,很可能會(huì)丟包。所以如果你的業(yè)務(wù)使用的是短連接且流量比較大,那么一定得學(xué)會(huì)觀察這兩個(gè)隊(duì)列是否存在溢出的情況。因?yàn)橐坏┏霈F(xiàn)因?yàn)檫B接隊(duì)列導(dǎo)致的握手問(wèn)題,那么 TCP 連接耗時(shí)都是秒級(jí)以上了。

對(duì)于半連接隊(duì)列, 有個(gè)簡(jiǎn)單的辦法。那就是只要保證 tcp_syncookies 這個(gè)內(nèi)核參數(shù)是 1 就能保證不會(huì)有因?yàn)榘脒B接隊(duì)列滿而發(fā)生的丟包。

對(duì)于全連接隊(duì)列來(lái)說(shuō),可以通過(guò) netstat -s 來(lái)觀察。netstat -s 可查看到當(dāng)前系統(tǒng)全連接隊(duì)列滿導(dǎo)致的丟包統(tǒng)計(jì)。但該數(shù)字記錄的是總丟包數(shù),所以你需要再借助 watch 命令動(dòng)態(tài)監(jiān)控。

# watch 'netstat -s | grep overflowed' 
160 times the listen queue of a socket overflowed //全連接隊(duì)列滿導(dǎo)致的丟包

如果輸出的數(shù)字在你監(jiān)控的過(guò)程中變了,那說(shuō)明當(dāng)前服務(wù)器有因?yàn)槿B接隊(duì)列滿而產(chǎn)生的丟包。你就需要加大你的全連接隊(duì)列的?度了。全連接隊(duì)列是應(yīng)用程序調(diào)用 listen時(shí)傳入的 backlog 以及內(nèi)核參數(shù) net.core.somaxconn 二者之中較小的那個(gè)。如果需要加大,可能兩個(gè)參數(shù)都需要改。

如果你手頭并沒(méi)有服務(wù)器的權(quán)限,只是發(fā)現(xiàn)自己的客戶端機(jī)連接某個(gè) server 出現(xiàn)耗時(shí)長(zhǎng),想定位一下是否是因?yàn)槲帐株?duì)列的問(wèn)題。那也有間接的辦法,可以 tcpdump 抓包查看是否有 SYN 的 TCP Retransmission。如果有偶發(fā)的 TCP Retransmission, 那就說(shuō)明對(duì)應(yīng)的服務(wù)端連接隊(duì)列可能有問(wèn)題了。

建議13:減少握手重試

在 6.5 節(jié)我們看到如果握手發(fā)生異常,客戶端或者服務(wù)端就會(huì)啟動(dòng)超時(shí)重傳機(jī)制。這個(gè)超時(shí)重試的時(shí)間間隔是翻倍地增長(zhǎng)的,1 秒、3 秒、7 秒、15 秒、31 秒、63 秒 ......。對(duì)于我們提供給用戶直接訪問(wèn)的接口來(lái)說(shuō),重試第一次耗時(shí) 1 秒多已經(jīng)是嚴(yán)重影響用戶體驗(yàn)了。如果重試到第三次以后,很有可能某一個(gè)環(huán)節(jié)已經(jīng)報(bào)錯(cuò)返回 504 了。所以在這種應(yīng)用場(chǎng)景下,維護(hù)這么多的超時(shí)次數(shù)其實(shí)沒(méi)有任何意義。倒不如把他們?cè)O(shè)置的小一些,盡早放棄。其中客戶端的 syn 重傳次數(shù)由 tcp_syn_retries 控制,服務(wù)器半連接隊(duì)列中的超時(shí)次數(shù)是由 tcp_synack_retries 來(lái)控制。把它們兩個(gè)調(diào)成你想要的值。

建議14:如果請(qǐng)求頻繁,請(qǐng)棄用短連接改用長(zhǎng)連接

如果你的服務(wù)器頻繁請(qǐng)求某個(gè) server,比如 redis 緩存。和建議 1 比起來(lái),一個(gè)更好一點(diǎn)的方法是使用長(zhǎng)連接。這樣的好處有

1)節(jié)約了握手開(kāi)銷。短連接中每次請(qǐng)求都需要服務(wù)和緩存之間進(jìn)行握手,這樣每次都得讓用戶多等一個(gè)握手的時(shí)間開(kāi)銷。

2)規(guī)避了隊(duì)列滿的問(wèn)題。前面我們看到當(dāng)全連接或者半連接隊(duì)列溢出的時(shí)候,服務(wù)器直接丟包。而客戶端呢并不知情,所以傻傻地等 3 秒才會(huì)重試。要知道 tcp 本身并不是專門(mén)為互聯(lián)網(wǎng)服務(wù)設(shè)計(jì)的。這個(gè) 3 秒的超時(shí)對(duì)于互聯(lián)網(wǎng)用戶的體驗(yàn)影響是致命的。

3)端口數(shù)不容易出問(wèn)題。端連接中,在釋放連接的時(shí)候,客戶端使用的端口需要進(jìn)入 TIME_WAIT 狀態(tài),等待 2 MSL的時(shí)間才能釋放。所以如果連接頻繁,端口數(shù)量很容易不夠用。而長(zhǎng)連接就固定使用那么幾十上百個(gè)端口就夠用了。

建議15:TIME_WAIT 的優(yōu)化

很多線上服務(wù)如果使用了短連接的情況下,就會(huì)出現(xiàn)大量的 TIME_WAIT。

首先,我想說(shuō)的是沒(méi)有必要見(jiàn)到兩三萬(wàn)個(gè) TIME_WAIT 就恐慌的不行。從內(nèi)存的?度來(lái)考慮,一條 TIME_WAIT 狀態(tài)的連接僅僅是 0.5 KB 的內(nèi)存而已。從端口占用的角度來(lái)說(shuō),確實(shí)是消耗掉了一個(gè)端口。但假如你下次再連接的是不同的 Server 的話,該端口仍然可以使用。只有在所有 TIME_WAIT 都聚集在和一個(gè) Server 的連接上的時(shí)候才會(huì)有問(wèn)題。

那怎么解決呢? 其實(shí)辦法有很多。第一個(gè)辦法是按上面建議開(kāi)啟端口 reuse 和 recycle。 第二個(gè)辦法是限制 TIME_WAIT 狀態(tài)的連接的最大數(shù)量。

# vi /etc/sysctl.conf
net.ipv4.tcp_max_tw_buckets = 32768
# sysctl -p

如果再?gòu)氐滓恍?,也可以干脆直接?連接代替頻繁的短連接。連接頻率大大降低以后,自然也就沒(méi)有 TIME_WAIT 的問(wèn)題了。?

責(zé)任編輯:華軒 來(lái)源: 今日頭條
相關(guān)推薦

2024-01-22 13:16:00

接口性能優(yōu)化本地緩存

2022-10-09 13:36:44

接口性能優(yōu)化

2018-02-23 13:55:16

ASP.NET性能優(yōu)化技巧

2009-03-16 16:00:19

HibernateJ2EE配置

2009-07-17 16:43:02

JRuby性能優(yōu)化

2023-11-01 11:59:13

2020-06-05 08:53:31

接口性能實(shí)踐

2014-08-27 10:24:33

.NETC#

2012-04-26 22:00:10

iPhone

2010-12-20 10:56:32

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

2010-06-03 11:39:28

網(wǎng)絡(luò)性能

2020-03-31 14:16:25

前端性能優(yōu)化HTTP

2019-10-08 10:25:00

MySQL數(shù)據(jù)庫(kù)DNS

2022-05-11 12:15:50

scriptweb性能

2023-01-26 01:33:09

web性能優(yōu)化

2024-12-23 08:10:00

Python代碼性能代碼

2017-03-29 14:44:20

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

2021-07-29 14:20:34

網(wǎng)絡(luò)優(yōu)化移動(dòng)互聯(lián)網(wǎng)數(shù)據(jù)存儲(chǔ)

2012-04-28 09:28:43

MySQL數(shù)據(jù)庫(kù)數(shù)據(jù)庫(kù)優(yōu)化

2022-02-16 14:10:51

服務(wù)器性能優(yōu)化Linux
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)