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

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

這種本機(jī)網(wǎng)絡(luò) IO 方法,性能可以翻倍!

2023-07-15 08:53 作者:清澄秋爽  | 我要投稿

原文地址:https://mp.weixin.qq.com/s/fHzKYlW0WMhP2jxh2H_59A


大家好,我是飛哥!

很多讀者在看完《127.0.0.1 之本機(jī)網(wǎng)絡(luò)通信過程知多少 ?》這一篇后,讓我講講 Unix Domain Socket。好了,今天就安排!

在本機(jī)網(wǎng)絡(luò) IO 中,我們講到過基于普通 socket 的本機(jī)網(wǎng)絡(luò)通信過程中,其實(shí)在內(nèi)核工作流上并沒有節(jié)約太多的開銷。該走的系統(tǒng)調(diào)用、協(xié)議棧、鄰居系統(tǒng)、設(shè)備驅(qū)動(dòng)(雖然說對(duì)于本機(jī)網(wǎng)絡(luò) loopback 設(shè)備來說只是一個(gè)軟件虛擬的東東)全都走了一遍。其工作過程如下圖

圖片

那么我們今天來看另外一種本機(jī)網(wǎng)絡(luò) IO 通信方式 -- Unix Domain Socket??纯催@種方式在性能開銷上和基于 127.0.0.1 的本機(jī)網(wǎng)絡(luò) IO 有沒有啥差異呢。

本文中,我們將分析 Unix Domain Socket 的內(nèi)部工作原理。你將理解為什么這種方式的性能比 127.0.0.1 要好很多。最后我們還給出了實(shí)際的性能測(cè)試對(duì)比數(shù)據(jù)。

相信你已經(jīng)迫不及待了,別著急,讓我們一一展開細(xì)說!

一、使用方法

Unix Domain Socket(后面統(tǒng)一簡(jiǎn)稱 UDS) 使用起來和傳統(tǒng)的 socket 非常的相似。區(qū)別點(diǎn)主要有兩個(gè)地方需要關(guān)注。

第一,在創(chuàng)建 socket 的時(shí)候,普通的 socket 第一個(gè)參數(shù) family 為 AF_INET, 而 UDS 指定為 AF_UNIX 即可。

第二,Server 的標(biāo)識(shí)不再是 ip 和 端口,而是一個(gè)路徑,例如 /dev/shm/fpm-cgi.sock。

其實(shí)在平時(shí)我們使用 UDS 并不一定需要去寫一段代碼,很多應(yīng)用程序都支持在本機(jī)網(wǎng)絡(luò) IO 的時(shí)候配置。例如在 Nginx 中,如果要訪問的本機(jī) fastcgi 服務(wù)是以 UDS 方式提供服務(wù)的話,只需要在配置文件中配置這么一行就搞定了。

如果 對(duì)于一個(gè) UDS 的 server 來說,它的代碼示例大概結(jié)構(gòu)如下,大家簡(jiǎn)單了解一下。只是個(gè)示例不一定可運(yùn)行。

基于 UDS 的 client 也是和普通 socket 使用方式差不太多,創(chuàng)建一個(gè) socket,然后 connect 即可。

二、連接過程

總的來說,基于 UDS 的連接過程比 inet 的 socket 連接過程要簡(jiǎn)單多了??蛻舳讼葎?chuàng)建一個(gè)自己用的 socket,然后調(diào)用 connect 來和服務(wù)器建立連接。

在 connect 的時(shí)候,會(huì)申請(qǐng)一個(gè)新 socket 給 server 端將來使用,和自己的 socket 建立好連接關(guān)系以后,就放到服務(wù)器正在監(jiān)聽的 socket 的接收隊(duì)列中。這個(gè)時(shí)候,服務(wù)器端通過 accept 就能獲取到和客戶端配好對(duì)的新 socket 了。

總的 UDS 的連接建立流程如下圖。

圖片

內(nèi)核源碼中最重要的邏輯在 connect 函數(shù)中,我們來簡(jiǎn)單展開看一下。unix 協(xié)議族中定義了這類 socket 的所有方法,它位于 net/unix/af_unix.c 中。

我們找到 connect 函數(shù)的具體實(shí)現(xiàn),unix_stream_connect。

主要的連接操作都是在這個(gè)函數(shù)中完成的。和我們平常所見的 TCP 連接建立過程,這個(gè)連接過程簡(jiǎn)直是太簡(jiǎn)單了。沒有三次握手,也沒有全連接隊(duì)列、半連接隊(duì)列,更沒有啥超時(shí)重傳。

直接就是將兩個(gè) socket 結(jié)構(gòu)體中的指針互相指向?qū)Ψ骄托辛恕>褪?unix_peer(newsk) = sk 和?unix_peer(sk)?= newsk 這兩句。

當(dāng)關(guān)聯(lián)關(guān)系建立好之后,通過 __skb_queue_tail 將 skb 放到服務(wù)器的接收隊(duì)列中。注意這里的 skb 里保存著新 socket 的指針,因?yàn)榉?wù)進(jìn)程通過 accept 取出這個(gè) skb 的時(shí)候,就能獲取到和客戶進(jìn)程中 socket 建立好連接關(guān)系的另一個(gè) socket。

怎么樣,UDS 的連接建立過程是不是很簡(jiǎn)單!?

三、發(fā)送過程

看完了連接建立過程,我們?cè)賮砜纯椿?UDS 的數(shù)據(jù)的收發(fā)。這個(gè)收發(fā)過程一樣也是非常的簡(jiǎn)單。發(fā)送方是直接將數(shù)據(jù)寫到接收方的接收隊(duì)列里的。

圖片

我們從 send 函數(shù)來看起。send 系統(tǒng)調(diào)用的源碼位于文件 net/socket.c 中。在這個(gè)系統(tǒng)調(diào)用里,內(nèi)部其實(shí)真正使用的是 sendto 系統(tǒng)調(diào)用。它只干了兩件簡(jiǎn)單的事情,

第一是在內(nèi)核中把真正的 socket 找出來,在這個(gè)對(duì)象里記錄著各種協(xié)議棧的函數(shù)地址。第二是構(gòu)造一個(gè) struct msghdr 對(duì)象,把用戶傳入的數(shù)據(jù),比如 buffer地址、數(shù)據(jù)長度啥的,統(tǒng)統(tǒng)都裝進(jìn)去. 剩下的事情就交給下一層,協(xié)議棧里的函數(shù) inet_sendmsg 了,其中 inet_sendmsg 函數(shù)的地址是通過 socket 內(nèi)核對(duì)象里的 ops 成員找到的。大致流程如圖。

圖片

在進(jìn)入到協(xié)議棧 inet_sendmsg 以后,內(nèi)核接著會(huì)找到 socket 上的具體協(xié)議發(fā)送函數(shù)。對(duì)于 Unix Domain Socket 來說,那就是 unix_stream_sendmsg。我們來看一下這個(gè)函數(shù)

和復(fù)雜的 TCP 發(fā)送接收過程相比,這里的發(fā)送邏輯簡(jiǎn)單簡(jiǎn)單到令人發(fā)指。申請(qǐng)一塊內(nèi)存(skb),把數(shù)據(jù)拷貝進(jìn)去。根據(jù) socket 對(duì)象找到另一端,直接把 skb 給放到對(duì)端的接收隊(duì)列里了

接收函數(shù)主題是 unix_stream_recvmsg,這個(gè)函數(shù)中只需要訪問它自己的接收隊(duì)列就行了,源碼就不展示了。所以在本機(jī)網(wǎng)絡(luò) IO 場(chǎng)景里,基于 Unix Domain Socket 的服務(wù)性能上肯定要好一些的。

四、性能對(duì)比

為了驗(yàn)證 Unix Domain Socket 到底比基于 127.0.0.1 的性能好多少,我做了一個(gè)性能測(cè)試。在網(wǎng)絡(luò)性能對(duì)比測(cè)試,最重要的兩個(gè)指標(biāo)是延遲和吞吐。我從 Github 上找了個(gè)好用的測(cè)試源碼:https://github.com/rigtorp/ipc-bench。我的測(cè)試環(huán)境是一臺(tái) 4 核 CPU,8G 內(nèi)存的 KVM 虛機(jī)。

在延遲指標(biāo)上,對(duì)比結(jié)果如下圖。

圖片

可見在小包(100 字節(jié))的情況下,UDS 方法的“網(wǎng)絡(luò)” IO 平均延遲只有 2707 納秒,而基于 TCP(訪問 127.0.0.1)的方式下延遲高達(dá) 5690 納秒。耗時(shí)整整是前者的兩倍。

在包體達(dá)到 100 KB 以后,UDS 方法延遲 24 微秒左右(1 微秒等于 1000 納秒),TCP 是 32 微秒,仍然高一截。這里低于 2 倍的關(guān)系了,是因?yàn)楫?dāng)包足夠大的時(shí)候,網(wǎng)絡(luò)協(xié)議棧上的開銷就顯得沒那么明顯了。

再來看看吞吐效果對(duì)比。

圖片

在小包的情況下,帶寬指標(biāo)可以達(dá)到 854 M,而基于 TCP 的 IO 方式下只有 386 M。數(shù)據(jù)就解讀到這里。

五、總結(jié)

本文分析了基于 Unix Domain Socket 的連接創(chuàng)建、以及數(shù)據(jù)收發(fā)過程。其中數(shù)據(jù)收發(fā)的工作過程如下圖。

圖片

相對(duì)比本機(jī)網(wǎng)絡(luò) IO 通信過程上,它的工作過程要清爽許多。其中 127.0.0.1 工作過程如下圖。

圖片

我們也對(duì)比了 UDP 和 TCP 兩種方式下的延遲和性能指標(biāo)。在包體不大于 1KB 的時(shí)候,UDS 的性能大約是 TCP 的兩倍多。所以,在本機(jī)網(wǎng)絡(luò) IO 的場(chǎng)景下,如果對(duì)性能敏感,飛哥建議你使用 Unix Domain Socket。

圖片



這種本機(jī)網(wǎng)絡(luò) IO 方法,性能可以翻倍!的評(píng)論 (共 條)

分享到微博請(qǐng)遵守國家法律
横峰县| 迭部县| 内丘县| 商洛市| 时尚| 巴彦县| 余庆县| 湾仔区| 炎陵县| 古丈县| 邻水| 龙江县| 井冈山市| 苍南县| 左权县| 深州市| 肥西县| 米泉市| 年辖:市辖区| 始兴县| 门源| 社会| 平泉县| 冀州市| 德州市| 潮州市| 永昌县| 三亚市| 柳河县| 日土县| 余干县| 渑池县| 磴口县| 汝城县| 泌阳县| 武义县| 米脂县| 武宁县| 乐东| 阳城县| 县级市|