42 | 案例篇:如何优化 NAT 性能?(下)
生活随笔
收集整理的這篇文章主要介紹了
42 | 案例篇:如何优化 NAT 性能?(下)
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
上一節(jié),我們學(xué)習(xí)了 NAT 的原理,明白了如何在 Linux 中管理 NAT 規(guī)則。先來(lái)簡(jiǎn)單復(fù)習(xí)一下。 NAT 技術(shù)能夠重寫(xiě) IP 數(shù)據(jù)包的源 IP 或目的 IP,所以普遍用來(lái)解決公網(wǎng) IP 地址短缺的問(wèn)題。它可以讓網(wǎng)絡(luò)中的多臺(tái)主機(jī),通過(guò)共享同一個(gè)公網(wǎng) IP 地址,來(lái)訪問(wèn)外網(wǎng)資源。同時(shí),由于 NAT 屏蔽了內(nèi)網(wǎng)網(wǎng)絡(luò),也為局域網(wǎng)中機(jī)器起到安全隔離的作用。 Linux 中的 NAT ,基于內(nèi)核的連接跟蹤模塊實(shí)現(xiàn)。所以,它維護(hù)每個(gè)連接狀態(tài)的同時(shí),也對(duì)網(wǎng)絡(luò)性能有一定影響。那么,碰到 NAT 性能問(wèn)題時(shí),我們又該怎么辦呢? 接下來(lái),我就通過(guò)一個(gè)案例,帶你學(xué)習(xí) NAT 性能問(wèn)題的分析思路。
案例準(zhǔn)備
下面的案例仍然基于 Ubuntu 18.04,同樣適用于其他的 Linux 系統(tǒng)。我使用的案例環(huán)境是這樣的: 機(jī)器配置:2 CPU,8GB 內(nèi)存。 預(yù)先安裝 docker、tcpdump、curl、ab、SystemTap 等工具,比如 # Ubuntu apt-get install -y docker.io tcpdump curl apache2-utils# CentOS curl -fsSL https://get.docker.com | sh yum install -y tcpdump curl httpd-tools 大部分工具,你應(yīng)該都比較熟悉,這里我簡(jiǎn)單介紹一下 SystemTap 。SystemTap?
SystemTap 是 Linux 的一種動(dòng)態(tài)追蹤框架,它把用戶提供的腳本,轉(zhuǎn)換為內(nèi)核模塊來(lái)執(zhí)行,用來(lái)監(jiān)測(cè)和跟蹤內(nèi)核的行為。關(guān)于它的原理,你暫時(shí)不用深究,后面的內(nèi)容還會(huì)介紹到。這里你只要知道怎么安裝就可以了: # Ubuntu apt-get install -y systemtap-runtime systemtap # Configure ddebs source echo "deb http://ddebs.ubuntu.com $(lsb_release -cs) main restricted universe multiverse deb http://ddebs.ubuntu.com $(lsb_release -cs)-updates main restricted universe multiverse deb http://ddebs.ubuntu.com $(lsb_release -cs)-proposed main restricted universe multiverse" | \ sudo tee -a /etc/apt/sources.list.d/ddebs.list # Install dbgsym apt-key adv --keyserver keyserver.ubuntu.com --recv-keys F2EDC64DC5AEE1F6B9C621F0C8CAB6595FDFF622 apt-get update apt install ubuntu-dbgsym-keyring stap-prep apt-get install linux-image-`uname -r`-dbgsym# CentOS yum install systemtap kernel-devel yum-utils kernel stab-prep 本次案例還是我們最常見(jiàn)的 Nginx,并且會(huì)用 ab 作為它的客戶端,進(jìn)行壓力測(cè)試。案例中總共用到兩臺(tái)虛擬機(jī),我畫(huà)了一張圖來(lái)表示它們的關(guān)系。 接下來(lái),我們打開(kāi)兩個(gè)終端,分別 SSH 登錄到兩臺(tái)機(jī)器上(以下步驟,假設(shè)終端編號(hào)與圖示 VM 編號(hào)一致),并安裝上面提到的這些工具。注意,curl 和 ab 只需要在客戶端 VM(即 VM2)中安裝。 同以前的案例一樣,下面的所有命令都默認(rèn)以 root 用戶運(yùn)行。如果你是用普通用戶身份登陸系統(tǒng),請(qǐng)運(yùn)行 sudo su root 命令,切換到 root 用戶。 如果安裝過(guò)程中有什么問(wèn)題,同樣鼓勵(lì)你先自己搜索解決,解決不了的,可以在留言區(qū)向我提問(wèn)。如果你以前已經(jīng)安裝過(guò)了,就可以忽略這一點(diǎn)了。 接下來(lái),我們就進(jìn)入到案例環(huán)節(jié)。案例分析
為了對(duì)比 NAT 帶來(lái)的性能問(wèn)題,我們首先運(yùn)行一個(gè)不用 NAT 的 Nginx 服務(wù),并用 ab 測(cè)試它的性能。 在終端一中,執(zhí)行下面的命令,啟動(dòng) Nginx,注意選項(xiàng) --network=host ,表示容器使用 Host 網(wǎng)絡(luò)模式,即不使用 NAT: docker run --name nginx-hostnet --privileged --network=host -itd feisky/nginx:80 然后到終端二中,執(zhí)行 curl 命令,確認(rèn) Nginx 正常啟動(dòng): curl http://192.168.0.30/ ... <p><em>Thank you for using nginx.</em></p> </body> </html> 繼續(xù)在終端二中,執(zhí)行 ab 命令,對(duì) Nginx 進(jìn)行壓力測(cè)試。不過(guò)在測(cè)試前要注意,Linux 默認(rèn)允許打開(kāi)的文件描述數(shù)比較小,比如在我的機(jī)器中,這個(gè)值只有 1024: # open files ulimit -n 1024 所以,執(zhí)行 ab 前,先要把這個(gè)選項(xiàng)調(diào)大,比如調(diào)成 65536: # 臨時(shí)增大當(dāng)前會(huì)話的最大文件描述符數(shù) ulimit -n 65536 接下來(lái),再去執(zhí)行 ab 命令,進(jìn)行壓力測(cè)試: # -c 表示并發(fā)請(qǐng)求數(shù)為 5000,-n 表示總的請(qǐng)求數(shù)為 10 萬(wàn) # -r 表示套接字接收錯(cuò)誤時(shí)仍然繼續(xù)執(zhí)行,-s 表示設(shè)置每個(gè)請(qǐng)求的超時(shí)時(shí)間為 2s ab -c 5000 -n 100000 -r -s 2 http://192.168.0.30/ ... Requests per second: 6576.21 [#/sec] (mean) Time per request: 760.317 [ms] (mean) Time per request: 0.152 [ms] (mean, across all concurrent requests) Transfer rate: 5390.19 [Kbytes/sec] receivedConnection Times (ms)min mean[+/-sd] median max Connect: 0 177 714.3 9 7338 Processing: 0 27 39.8 19 961 Waiting: 0 23 39.5 16 951 Total: 1 204 716.3 28 7349 ... 關(guān)于 ab 輸出界面的含義,我已經(jīng)在 怎么評(píng)估系統(tǒng)的網(wǎng)絡(luò)性能 文章中介紹過(guò),忘了的話自己先去復(fù)習(xí)。從這次的界面,你可以看出:- 每秒請(qǐng)求數(shù)(Requests per second)為 6576;
- 每個(gè)請(qǐng)求的平均延遲(Time per request)為 760ms;
- 建立連接的平均延遲(Connect)為 177ms。
- 每秒請(qǐng)求數(shù)(Requests per second)為 76;
- 每個(gè)請(qǐng)求的延遲(Time per request)為 65s;
- 建立連接的延遲(Connect)為 1300ms。
- 第一,利用 Netfilter 中的鉤子函數(shù)(Hook),修改源地址或者目的地址。
- 第二,利用連接跟蹤模塊 conntrack ,關(guān)聯(lián)同一個(gè)連接的請(qǐng)求和響應(yīng)。
- 第一,接收網(wǎng)絡(luò)包時(shí),在連接跟蹤表中查找連接,并為新的連接分配跟蹤對(duì)象(Bucket)。
- 第二,在 Linux 網(wǎng)橋中轉(zhuǎn)發(fā)包。這是因?yàn)榘咐?Nginx 是一個(gè) Docker 容器,而容器的網(wǎng)絡(luò)通過(guò)網(wǎng)橋來(lái)實(shí)現(xiàn);
- 第三,接收網(wǎng)絡(luò)包時(shí),執(zhí)行 DNAT,即把 8080 端口收到的包轉(zhuǎn)發(fā)給容器。
- net.netfilter.nf_conntrack_count,表示當(dāng)前連接跟蹤數(shù);
- net.netfilter.nf_conntrack_max,表示最大連接跟蹤數(shù);
- net.netfilter.nf_conntrack_buckets,表示連接跟蹤表的大小。
- 每秒請(qǐng)求數(shù)(Requests per second)為 6315(不用 NAT 時(shí)為 6576);
- 每個(gè)請(qǐng)求的延遲(Time per request)為 791ms(不用 NAT 時(shí)為 760ms);
- 建立連接的延遲(Connect)為 355ms(不用 NAT 時(shí)為 177ms)。
小結(jié)
今天,我?guī)阋黄饘W(xué)習(xí)了,如何排查和優(yōu)化 NAT 帶來(lái)的性能問(wèn)題。 由于 NAT 基于 Linux 內(nèi)核的連接跟蹤機(jī)制來(lái)實(shí)現(xiàn)。所以,在分析 NAT 性能問(wèn)題時(shí),我們可以先從 conntrack 角度來(lái)分析,比如用 systemtap、perf 等,分析內(nèi)核中 conntrack 的行文;然后,通過(guò)調(diào)整 netfilter 內(nèi)核選項(xiàng)的參數(shù),來(lái)進(jìn)行優(yōu)化。 其實(shí),Linux 這種通過(guò)連接跟蹤機(jī)制實(shí)現(xiàn)的 NAT,也常被稱(chēng)為有狀態(tài)的 NAT,而維護(hù)狀態(tài),也帶來(lái)了很高的性能成本。 所以,除了調(diào)整內(nèi)核行為外,在不需要狀態(tài)跟蹤的場(chǎng)景下(比如只需要按預(yù)定的 IP 和端口進(jìn)行映射,而不需要?jiǎng)討B(tài)映射),我們也可以使用無(wú)狀態(tài)的 NAT (比如用 tc 或基于 DPDK 開(kāi)發(fā)),來(lái)進(jìn)一步提升性能。 思考 最后,給你留一個(gè)思考題。你有沒(méi)有碰到過(guò) NAT 帶來(lái)的性能問(wèn)題?你是怎么定位和分析它的根源的?最后,又是通過(guò)什么方法來(lái)優(yōu)化解決的?你可以結(jié)合今天的案例,總結(jié)自己的思路。總結(jié)
以上是生活随笔為你收集整理的42 | 案例篇:如何优化 NAT 性能?(下)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 41 | 案例篇:如何优化 NAT 性能
- 下一篇: 43 | 套路篇:网络性能优化的几个思路