優(yōu)全攻略:sysctl網(wǎng)絡(luò)參數(shù)、磁盤(pán)IO與內(nèi)存優(yōu)化實(shí)戰(zhàn))
簡(jiǎn)介這份《LINUX性能調(diào)優(yōu)方法總結(jié).docx》是一份面向運(yùn)維工程師、系統(tǒng)管理員及后端開(kāi)發(fā)者的Linux性能優(yōu)化參考文檔內(nèi)容聚焦網(wǎng)絡(luò)性能與磁盤(pán)子系統(tǒng)兩大方向。資源以docx格式交付共1個(gè)文件包體約51KB輕量便于快速查閱。文中不僅給出了sysctl.conf內(nèi)核參數(shù)配置示例如TCP SYN Cookie、窗口縮放及緩沖區(qū)上限調(diào)整還講解了noatime掛載選項(xiàng)、hdparm磁盤(pán)測(cè)試等實(shí)用操作并提供fstab修改樣例與注意事項(xiàng)。對(duì)這些設(shè)置的具體位置、生效方式及適用環(huán)境做了清晰交代適合對(duì)服務(wù)器性能有調(diào)優(yōu)需求、希望獲得可直接參照方案的中級(jí)以上Linux使用者。文檔從內(nèi)核參數(shù)到文件系統(tǒng)掛載選項(xiàng)均給出可直接套用的配置片段對(duì)檢測(cè)時(shí)機(jī)和風(fēng)險(xiǎn)提醒也有說(shuō)明可當(dāng)作日常服務(wù)器維護(hù)或面試復(fù)習(xí)的速查清單。已有214人學(xué)習(xí)下載按要點(diǎn)整理、驗(yàn)證充分后可直接用于生產(chǎn)環(huán)境優(yōu)化參考。1. Linux 性能調(diào)優(yōu)方法總結(jié)這份文檔到底能解決什么做運(yùn)維的人大概率都經(jīng)歷過(guò)這種場(chǎng)景業(yè)務(wù)一上量TCP 連接數(shù)飆升應(yīng)用頻繁超時(shí)netstat -an里能看到幾百個(gè)SYN_RECV磁盤(pán) IO 長(zhǎng)期在 90% 以上。這時(shí)候翻到一份 Linux 性能調(diào)優(yōu)方法總結(jié)里面寫(xiě)滿(mǎn)了sysctl參數(shù)、hdparm命令、ulimit限制但如果沒(méi)有理清參數(shù)之間的關(guān)聯(lián)照著敲是很容易把生產(chǎn)環(huán)境調(diào)出問(wèn)題的。這份文檔的核心價(jià)值不在某一條命令而在它把網(wǎng)絡(luò)、磁盤(pán)、文件描述符、內(nèi)存四個(gè)調(diào)優(yōu)方向完整串在了一起。適合的人有兩類(lèi)一類(lèi)是剛接手服務(wù)器、需要從系統(tǒng)層面壓出余量的運(yùn)維新手另一類(lèi)是遇到連接數(shù)打不上去、磁盤(pán)響應(yīng)變慢、SYN 攻擊導(dǎo)致服務(wù)不可用等具體問(wèn)題的排查者。它最大的特點(diǎn)是參數(shù)直接可抄同時(shí)保留了proc接口、sysctl.conf、rc.local等多種落地方式這也是很多資料只給結(jié)論、不解釋生效機(jī)制的地方。2. 網(wǎng)絡(luò)參數(shù)調(diào)優(yōu)sysctl 機(jī)制與一套可落地的 TCP 配置2.1 proc 接口、sysctl 與內(nèi)核參數(shù)的關(guān)系網(wǎng)絡(luò)調(diào)優(yōu)前必須先搞清楚參數(shù)到底改在哪。Linux 內(nèi)核把運(yùn)行時(shí)的可調(diào)參數(shù)暴露在/proc虛擬文件系統(tǒng)下其中網(wǎng)絡(luò)相關(guān)的全部位于/proc/sys/net/目錄。比如/proc/sys/net/ipv4/tcp_syncookies這個(gè)文件的值就是內(nèi)核當(dāng)前是否啟用 SYN cookies 的真實(shí)狀態(tài)。直接對(duì)文件寫(xiě)入只能臨時(shí)生效重啟后一切歸零/proc目錄下的所有內(nèi)容本來(lái)就是內(nèi)存中的映射不是持久化存儲(chǔ)。sysctl的出現(xiàn)就是為了解決參數(shù)容易改、難以管理的問(wèn)題。它會(huì)讀取/etc/sysctl.conf中的配置幫你把值填充到對(duì)應(yīng)的/proc文件里。這樣你只需要維護(hù)一個(gè)配置文件就能在系統(tǒng)啟動(dòng)時(shí)自動(dòng)恢復(fù)所有調(diào)優(yōu)參數(shù)。執(zhí)行sysctl -p /etc/sysctl.conf則可以在不重啟的情況下手動(dòng)加載一次配置。這個(gè)機(jī)制是理解后面所有調(diào)優(yōu)動(dòng)作的前提。2.2 互聯(lián)網(wǎng)服務(wù)器的激進(jìn)網(wǎng)絡(luò)參數(shù)配置文檔里給出了一套比較激進(jìn)的網(wǎng)絡(luò)參數(shù)適合互聯(lián)網(wǎng)服務(wù)器尤其是并發(fā)連接數(shù)較高的 Web 場(chǎng)景。配置寫(xiě)入/etc/sysctl.conf示例如下。# Use TCP syncookies when needed net.ipv4.tcp_syncookies 1 # Enable TCP window scaling net.ipv4.tcp_window_scaling 1 # Increase TCP max buffer size net.core.rmem_max 16777216 net.core.wmem_max 16777216 # Increase Linux autotuning TCP buffer limits net.ipv4.tcp_rmem 4096 87380 16777216 net.ipv4.tcp_wmem 4096 65536 16777216 # Increase number of ports available net.ipv4.ip_local_port_range 1024 65000這套配置里每一行都有具體作用。tcp_syncookies用于防止 SYN Flood 攻擊導(dǎo)致的內(nèi)存耗盡tcp_window_scaling允許 TCP 窗口超過(guò)默認(rèn)的 64 KB 上限高延遲鏈路下下載速度提升明顯rmem_max和wmem_max分別把接收、發(fā)送緩沖區(qū)的上限拉高到 16 MB讓?xiě)?yīng)用能更快地丟出數(shù)據(jù)去服務(wù)下一個(gè)請(qǐng)求tcp_rmem和tcp_wmem是三個(gè)值依次代表最小值、默認(rèn)值和最大值內(nèi)核會(huì)根據(jù)連接情況在三個(gè)值之間自動(dòng)調(diào)整第三個(gè)值不能超過(guò)對(duì)應(yīng)的rmem_max、wmem_maxip_local_port_range擴(kuò)大可用端口范圍從默認(rèn)的 32768-60999 擴(kuò)展到 1024-65000意味著服務(wù)器可以同時(shí)支撐更多出站連接。修改完執(zhí)行sysctl -p /etc/sysctl.conf參數(shù)立即生效這種方式比echo寫(xiě)入多個(gè)/proc文件要簡(jiǎn)潔得多也方便后續(xù)回滾和審計(jì)。2.3 TCP 時(shí)間戳、SACK 與窗口伸縮的取舍文檔中還有一組被注釋掉的參數(shù)很多人會(huì)忽略它們的存在意義。net.ipv4.tcp_timestamps控制 TCP 頭是否攜帶時(shí)間戳選項(xiàng)開(kāi)啟后每個(gè)包要多出 12 字節(jié)。對(duì)高帶寬場(chǎng)景來(lái)說(shuō)時(shí)間戳能幫助內(nèi)核做更精確的 RTT 估算和防回繞序號(hào)判斷但對(duì)內(nèi)網(wǎng)低延遲環(huán)境或帶寬極其有限的環(huán)境關(guān)閉它能省下一定的協(xié)議開(kāi)銷(xiāo)。tcp_sack是選擇性應(yīng)答允許接收方只報(bào)告丟失的段而不是整個(gè)窗口都重傳。在有隨機(jī)丟包的鏈路尤其是無(wú)線(xiàn)鏈路上SACK 能避免重傳風(fēng)暴。文檔原樣給出的值是echo 1 /proc/sys/net/ipv4/tcp_sack這是默認(rèn)行為只有在確定鏈路不會(huì)丟包且想省 CPU 的場(chǎng)景下才考慮關(guān)閉。tcp_window_scaling則必須配合緩沖區(qū)上限共同調(diào)整只開(kāi)窗口伸縮但不提高wmem_max大窗口就是空話(huà)。三個(gè)參數(shù)本質(zhì)上都在改變 TCP 協(xié)議棧的行為調(diào)整前要用sysctl -a | grep tcp_看清當(dāng)前值調(diào)整后觀(guān)察吞吐量變化而不是一股腦全開(kāi)。2.4 網(wǎng)絡(luò)參數(shù)落地的三種方式對(duì)比除了/etc/sysctl.conf文檔還提到了/etc/rc.local和命令直寫(xiě)兩種方式。三種方式各有適用場(chǎng)景。落地方式生效范圍重啟后狀態(tài)適用場(chǎng)景sysctl -w 參數(shù)值立即生效僅當(dāng)前運(yùn)行內(nèi)核丟失臨時(shí)調(diào)優(yōu)、壓測(cè)驗(yàn)證修改/etc/sysctl.conf并執(zhí)行sysctl -p立即生效并持久化保留生產(chǎn)環(huán)境正式變更在/etc/rc.local中寫(xiě)echo命令每次啟動(dòng)執(zhí)行一次保留內(nèi)核版本較老、sysctl 不支持的參數(shù)我一般會(huì)優(yōu)先選第二種。/etc/rc.local的方式雖然也能持久化但排查時(shí)別人未必能一眼看出參數(shù)被設(shè)置在哪個(gè)文件里不符合配置集中管理的習(xí)慣。如果你維護(hù)的是多臺(tái)服務(wù)器建議把sysctl.conf納入配置管理工具統(tǒng)一下發(fā)避免每臺(tái)機(jī)器手工改出差異。3. 磁盤(pán)與文件子系統(tǒng)noatime、hdparm 與 ulimit 的正確改法3.1 atime 是磁盤(pán)性能的無(wú)形殺手磁盤(pán)在 LAMP 架構(gòu)里同時(shí)承擔(dān)靜態(tài)文件、模板、代碼、數(shù)據(jù)庫(kù)表與索引的讀取延遲高是它的固有特性。文檔第一個(gè)強(qiáng)調(diào)的動(dòng)作是禁用 atime 記錄。atime 全稱(chēng) access time每次讀文件時(shí)文件系統(tǒng)都要更新這個(gè)時(shí)間戳哪怕內(nèi)容沒(méi)變。系統(tǒng)管理員實(shí)際很少去查 atime但它帶來(lái)的寫(xiě)操作在訪(fǎng)問(wèn)密集的業(yè)務(wù)下會(huì)被放大成明顯的 IO 壓力。修改方式是在/etc/fstab第四列加noatime選項(xiàng)。注意改完 fstab 并不會(huì)立即生效需要重新掛載文件系統(tǒng)常見(jiàn)做法是mount -o remount /或者等下次重啟。下面是文檔中的示例結(jié)構(gòu)。/dev/VolGroup00/LogVol00 / ext3 defaults,noatime 1 1 LABEL/boot /boot ext3 defaults,noatime 1 2 devpts /dev/pts devpts gid5,mode620 0 0 tmpfs /dev/shm tmpfs defaults 0 0 proc /proc proc defaults 0 0 sysfs /sys sysfs defaults 0 0 LABELSWAP-hdb2 swap swap defaults 0 0 LABELSWAP-hda3 swap swap defaults 0 0擴(kuò)展一下relatime是比noatime更溫和的選項(xiàng)它只在 atime 早于 mtime/ctime 時(shí)才更新兼顧兼容性。如果你的業(yè)務(wù)有程序依賴(lài) atime 做文件訪(fǎng)問(wèn)判斷優(yōu)先用relatime而不是直接上noatime能避免一些日志采集類(lèi)的程序行為異常。3.2 hdparm 測(cè)速與 IDE 數(shù)據(jù)傳輸模式磁盤(pán)性能的另一個(gè)關(guān)鍵點(diǎn)是驅(qū)動(dòng)是否選對(duì)了傳輸模式。Linux 不一定能自動(dòng)探測(cè)出訪(fǎng)問(wèn) IDE 磁盤(pán)的最佳方式hdparm就是用來(lái)查明和設(shè)置 IDE 磁盤(pán)訪(fǎng)問(wèn)參數(shù)的工具。hdparm -t /dev/hda文檔中的示例輸出為T(mén)iming buffered disk reads: 182 MB in 3.02 seconds 60.31 MB/sec這個(gè)數(shù)字可以作為優(yōu)化前后的基準(zhǔn)。執(zhí)行測(cè)速前務(wù)必保證系統(tǒng)空閑否則其他進(jìn)程的 IO 會(huì)污染結(jié)果。常用參數(shù)整理如下參數(shù)作用示例-vi查詢(xún)磁盤(pán)支持的設(shè)置和當(dāng)前使用的設(shè)置hdparm -vi /dev/hda-c查詢(xún)/啟用 IDE 32 位 IO 支持hdparm -c 1 /dev/hda-m設(shè)置每中斷多扇區(qū)模式大于 0 代表每中斷傳輸?shù)淖畲笊葏^(qū)數(shù)hdparm -m 16 /dev/hda-d 1 -X啟用 DMA 并設(shè)置 IDE 傳輸模式hdparm -d 1 -X 69 /dev/hdaSCSI 和光纖通道系統(tǒng)的調(diào)優(yōu)依賴(lài)具體驅(qū)動(dòng)器型號(hào)文檔也明確說(shuō)了這點(diǎn)。對(duì)于這類(lèi)設(shè)備調(diào)優(yōu)命令應(yīng)該寫(xiě)進(jìn)rc.local或?qū)?yīng)的啟動(dòng)腳本里保證重啟后配置不丟。需要提醒的是hdparm的-X參數(shù)如果設(shè)錯(cuò)輕則磁盤(pán)讀寫(xiě)報(bào)錯(cuò)重則需要重啟才能恢復(fù)操作前先用-vi確認(rèn)當(dāng)前模式和設(shè)備能力。3.3 文件描述符與進(jìn)程數(shù)限制ulimit 的臨時(shí)與永久Linux 對(duì)每個(gè)用戶(hù)有最大進(jìn)程數(shù)和最大文件打開(kāi)數(shù)的限制。ulimit -a可以顯示當(dāng)前所有限制默認(rèn)每進(jìn)程可打開(kāi)文件數(shù)是 1024這對(duì)數(shù)據(jù)庫(kù)連接池、Java 應(yīng)用這種大量持有 socket 的場(chǎng)景來(lái)說(shuō)是明顯瓶頸。ulimit -u 10000 # 最大進(jìn)程數(shù) ulimit -n 4096 # 每個(gè)進(jìn)程可打開(kāi)的文件數(shù) ulimit -d unlimited # 數(shù)據(jù)段長(zhǎng)度 ulimit -m unlimited # 最大內(nèi)存大小 ulimit -s unlimited # 堆棧大小 ulimit -t unlimited # CPU 時(shí)間 ulimit -v unlimited # 虛擬內(nèi)存ulimit命令直接影響當(dāng)前 shell 會(huì)話(huà)臨時(shí)生效退出登錄就失效。永久修改要看具體目錄# 修改系統(tǒng)級(jí)限制 vi /etc/security/limits.conf# 以下內(nèi)容添加到 limits.conf * soft noproc 11000 * hard noproc 11000 * soft nofile 4100 * hard nofile 4100noproc是最大進(jìn)程數(shù)nofile是最大文件打開(kāi)數(shù)*代表所有用戶(hù)。還有一個(gè)細(xì)節(jié)/etc/profile加ulimit語(yǔ)句可以讓所有登錄用戶(hù)獲得同樣的限額但有些發(fā)行版需要確認(rèn)/etc/pam.d/login和/etc/pam.d/system-auth中存在pam_limits.so的加載行否則limits.conf不會(huì)生效。不同發(fā)行版中該模塊的路徑可能有差異建議用find /lib -name pam_limits.so確認(rèn)。4. 內(nèi)存與網(wǎng)絡(luò)防護(hù)參數(shù)看起來(lái)很美但容易翻車(chē)的那幾個(gè)值4.1 虛擬內(nèi)存參數(shù)bdflush 與 kswapd虛擬內(nèi)存調(diào)優(yōu)在文檔中被標(biāo)注為需要不停監(jiān)測(cè)的子系統(tǒng)因?yàn)閮?nèi)存參數(shù)改動(dòng)很容易影響到其他部分。vm.bdflush控制內(nèi)核把 dirty buffers 刷到磁盤(pán)的行為總共有 9 個(gè)參數(shù)文檔建議只改前 3 個(gè)允許排隊(duì)寫(xiě)入的最大緩沖區(qū)百分比、bdflush 即刻寫(xiě)的最大緩沖值、同步前緩沖區(qū)變 dirty 的最大百分比。sysctl -w vm.bdflush30 500 0 0 500 3000 60 20 0vm.kswapd控制內(nèi)核交換守護(hù)進(jìn)程的行為三個(gè)參數(shù)分別對(duì)應(yīng)每次掃描頁(yè)數(shù)量的四倍值、每次交換出去的最小頁(yè)數(shù)量、立即寫(xiě)入的頁(yè)數(shù)量。sysctl -w vm.kswapd1024 32 64這里必須踩一個(gè)實(shí)際的坑bdflush是 Linux 2.4 時(shí)代的內(nèi)核參數(shù)2.6 之后的內(nèi)核已經(jīng)把它換成了dirty_ratio、dirty_background_ratio、dirty_writeback_centisecs這一組更細(xì)粒度的參數(shù)。如果你在 CentOS 7、Ubuntu 18.04 及以后版本上執(zhí)行sysctl -w vm.bdflush大概率會(huì)得到error: permission denied on key vm.bdflush或者找不到該 key。遇到這種情況用dirty_background_ratio和dirty_ratio替代前者是內(nèi)存中臟數(shù)據(jù)占可用內(nèi)存的百分比閾值達(dá)到后后臺(tái)異步刷盤(pán)后者是進(jìn)程同步刷盤(pán)的閾值。4.2 網(wǎng)絡(luò)防護(hù)參數(shù)重定向、SYN cookies 與 ICMP網(wǎng)絡(luò)調(diào)優(yōu)不止是調(diào)速度還要防性能下降。文檔里有一整組 sysctl 命令專(zhuān)門(mén)處理安全問(wèn)題這些設(shè)置同時(shí)也保護(hù)著系統(tǒng)性能不被攻擊拖垮。sysctl -w net.ipv4.conf.eth0.accept_source_route0 sysctl -w net.ipv4.conf.lo.accept_source_route0 sysctl -w net.ipv4.conf.default.accept_source_route0 sysctl -w net.ipv4.conf.all.accept_source_route0 sysctl -w net.ipv4.tcp_syncookies1 sysctl -w net.ipv4.conf.eth0.secure_redirects1 sysctl -w net.ipv4.conf.all.accept_redirects0 sysctl -w net.ipv4.conf.all.send_redirects0 sysctl -w net.ipv4.icmp_echo_ignore_broadcasts1 sysctl -w net.ipv4.icmp_ignore_bogus_error_responses1accept_source_route關(guān)閉的是 IP 源路由選項(xiàng)防止攻擊者指定數(shù)據(jù)包路徑繞過(guò)防火墻secure_redirects只接受來(lái)自網(wǎng)關(guān)的可靠重定向send_redirects關(guān)閉則是因?yàn)榉?wù)器如果不是路由器就沒(méi)有義務(wù)告知其他主機(jī)路徑icmp_echo_ignore_broadcasts拒絕廣播 ping這能擋掉一部分 smurf 攻擊。這些配置很多發(fā)行版默認(rèn)已經(jīng)是關(guān)閉或啟用的狀態(tài)但顯式寫(xiě)入配置可以防止默認(rèn)策略在升級(jí)時(shí)被改動(dòng)。4.3 用 vmstat 驗(yàn)證內(nèi)存調(diào)優(yōu)效果前面多次提到修改后要監(jiān)測(cè)落在實(shí)處就是vmstat。它輸出的是 CPU、內(nèi)存、IO 的實(shí)時(shí)狀態(tài)調(diào)優(yōu)前后各取一段數(shù)據(jù)做對(duì)比是最基本的習(xí)慣。vmstat 5 5procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu----- r b swpd free buff cache si so bi bo in cs us sy id wa st 1 0 0 482936 39016 1600360 0 0 0 1 124 319 1 1 98 0 0看輸出時(shí)重點(diǎn)對(duì)比bi和bo它們分別代表每秒從塊設(shè)備讀入、寫(xiě)入到塊設(shè)備的塊數(shù)。調(diào)優(yōu)后bi明顯下降說(shuō)明讀緩存命中率上來(lái)了或者 atime 禁用生效了。wa是 IO wait持續(xù)大于 30% 說(shuō)明磁盤(pán)已經(jīng)嚴(yán)重拖累 CPU。每次只改一個(gè)內(nèi)存參數(shù)、跑一輪壓測(cè)、記錄一次 vmstat是避免內(nèi)存調(diào)優(yōu)變成玄學(xué)的唯一辦法。5. 常見(jiàn)問(wèn)題與避坑參數(shù)不生效、內(nèi)核不支持、回退無(wú)門(mén)5.1 執(zhí)行 sysctl -p 報(bào)錯(cuò) Unknown key現(xiàn)象修改完/etc/sysctl.conf執(zhí)行sysctl -p時(shí)提示error: Unknown key。原因文檔是較早期內(nèi)核時(shí)代的寫(xiě)法部分參數(shù)在當(dāng)代內(nèi)核上已經(jīng)被移除或改名。例如net.ipv4.tcp_tw_recycle在 Linux 4.12 之后被刪除vm.bdflush被dirty_ratio系列取代。解決先執(zhí)行sysctl -a | grep 關(guān)鍵詞確認(rèn)當(dāng)前內(nèi)核是否支持該參數(shù)例如sysctl -a | grep tcp_tw。不存在的參數(shù)直接用#注釋掉不要為了讓 sysctl 全部生效而對(duì)內(nèi)核版本做降級(jí)那代價(jià)遠(yuǎn)大于收益。5.2 開(kāi)啟了 tcp_tw_recycle 之后NAT 環(huán)境大量連接被重置現(xiàn)象服務(wù)端開(kāi)啟了tcp_tw_recycleNAT 網(wǎng)關(guān)后的用戶(hù)訪(fǎng)問(wèn)出現(xiàn)大量連接被 RST業(yè)務(wù)偶發(fā)失敗。原因tcp_tw_recycle啟用后內(nèi)核會(huì)丟棄來(lái)自同一源 IP、時(shí)間戳遞增但小于上次記錄的連接而 NAT 環(huán)境下多個(gè)用戶(hù)共享同一個(gè)公網(wǎng) IP時(shí)間戳并不一定遞增內(nèi)核會(huì)誤判是舊連接重放。解決服務(wù)器面向公網(wǎng)且用戶(hù)經(jīng)過(guò) NAT 的場(chǎng)景直接不要開(kāi)啟tcp_tw_recycle。tcp_tw_reuse只作用于發(fā)起連接的一端對(duì) Web 服務(wù)器這種被動(dòng)接收連接的角色幾乎沒(méi)有副作用但仍然要確認(rèn)應(yīng)用對(duì)連接復(fù)用沒(méi)有特殊要求。兩者不要照單全收。5.3 ip_local_port_range 改錯(cuò)導(dǎo)致端口段沖突現(xiàn)象把net.ipv4.ip_local_port_range和某些服務(wù)監(jiān)聽(tīng)的固定端口設(shè)在了同一段出站連接出現(xiàn)Cannot assign requested address。原因本地端口范圍是給主動(dòng)出站連接用的源端口會(huì)從這個(gè)范圍內(nèi)選擇。若范圍內(nèi)包含服務(wù)本身監(jiān)聽(tīng)的端口內(nèi)核會(huì)盡量避免復(fù)用但范圍太窄或被服務(wù)占用太多可用端口耗盡。解決查看當(dāng)前占用情況用ss -s統(tǒng)計(jì) socket用cat /proc/sys/net/ipv4/ip_local_port_range確認(rèn)當(dāng)前范圍。把起始端口抬高到大于所有固定監(jiān)聽(tīng)端口比如1024 65000在多數(shù)場(chǎng)景安全但如果有服務(wù)監(jiān)聽(tīng)在 6000-8000 段就要把起始值改到 10000 以上。5.4 ulimit 修改后不生效新會(huì)話(huà)仍然是 1024現(xiàn)象在limits.conf里寫(xiě)了* soft nofile 65535重新登錄后ulimit -n還是 1024。原因多數(shù)發(fā)行版要求系統(tǒng)加載pam_limits.so。登錄過(guò)程由 PAM 管理如果/etc/pam.d/login或/etc/pam.d/system-auth里沒(méi)有這一行l(wèi)imits.conf根本不會(huì)被解析。解決確認(rèn)配置文件里存在session required pam_limits.so一行注意 32 位和 64 位系統(tǒng)的模塊路徑差異64 位系統(tǒng)通常是/lib64/security/pam_limits.so。修改后重新登錄不要只執(zhí)行ulimit -n覆蓋當(dāng)前會(huì)話(huà)。SSH 方式登錄時(shí)要確認(rèn)sshd_config中的UseLogin或相關(guān)配置沒(méi)有被設(shè)置成阻止 PAM 會(huì)話(huà)執(zhí)行。5.5 fstab 語(yǔ)法錯(cuò)了一個(gè)符號(hào)開(kāi)機(jī)直接進(jìn)維護(hù)模式現(xiàn)象在fstab加noatime時(shí)誤刪了空格或?qū)戝e(cuò)掛載點(diǎn)重啟后系統(tǒng)無(wú)法進(jìn)入正常多用戶(hù)模式。原因/etc/fstab每一列的順序和分隔符都有嚴(yán)格要求解析失敗時(shí)內(nèi)核無(wú)法完成掛載只能進(jìn)入 emergency 模式。解決改完fstab先執(zhí)行mount -a做一次無(wú)風(fēng)險(xiǎn)驗(yàn)證輸出沒(méi)有報(bào)錯(cuò)再重啟。更穩(wěn)妥的做法是保留一份cp /etc/fstab /etc/fstab.bak出問(wèn)題時(shí)在維護(hù)模式下用mv恢復(fù)。記住fstab是系統(tǒng)啟動(dòng)的生命線(xiàn)改之前永遠(yuǎn)先備份。6. 調(diào)優(yōu)完成的驗(yàn)證與落地從參數(shù)確認(rèn)到基線(xiàn)對(duì)比參數(shù)改完、服務(wù)正常啟動(dòng)不代表調(diào)優(yōu)結(jié)束。少了驗(yàn)證步驟調(diào)優(yōu)就是盲目的。我的習(xí)慣是做完一輪改動(dòng)后強(qiáng)制走一遍三件事確認(rèn)參數(shù)生效、采集新基線(xiàn)、核對(duì)變更清單。確認(rèn)參數(shù)生效用三條命令就夠了sysctl -a | grep -E tcp_syncookies|tcp_window_scaling|rmem_max|wmem_max cat /proc/sys/net/ipv4/ip_local_port_range ulimit -nsysctl -a輸出的是內(nèi)核當(dāng)前實(shí)際值和配置文件里的值一一比對(duì)。cat /proc/sys/net/ipv4/ip_local_port_range驗(yàn)證端口范圍。ulimit -n必須在新的登錄會(huì)話(huà)里執(zhí)行因?yàn)槟惝?dāng)前這個(gè) shell 可能還保留著舊的限制值。新基線(xiàn)采集至少要有前后兩組數(shù)據(jù)。用top、vmstat 5 5、ss -s分別記錄 CPU、內(nèi)存、IO、socket 狀態(tài)。ss -s的輸出里可以直接看到 TIME-WAIT、SYN 等狀態(tài)的 socket 數(shù)量這是驗(yàn)證tcp_fin_timeout、tcp_max_syn_backlog是否生效的最直接證據(jù)。業(yè)務(wù)側(cè)還要盯著應(yīng)用層的請(qǐng)求響應(yīng)時(shí)間和錯(cuò)誤率系統(tǒng)參數(shù)再好應(yīng)用表現(xiàn)沒(méi)有改善說(shuō)明問(wèn)題本就不在那層。變更清單是很多團(tuán)隊(duì)漏掉的重要環(huán)節(jié)。每次修改都記錄這樣幾項(xiàng)改了哪個(gè)文件、改動(dòng)了哪一行、原值是多少、新值是多少、執(zhí)行了什么命令讓它生效、應(yīng)急預(yù)案是什么。后面排查問(wèn)題用得上將來(lái)回滾也不用靠回憶猜。從第一次拆這份調(diào)優(yōu)文檔到現(xiàn)在我?guī)缀躔B(yǎng)成了一種強(qiáng)迫癥每臺(tái)新接手服務(wù)器先做一次sysctl -a /tmp/sysctl_before.txt再改任何參數(shù)最后 diff 兩個(gè)文件確認(rèn)自己到底改了什么、哪些參數(shù)沒(méi)生效。這套笨辦法在無(wú)數(shù)次深夜變更中救過(guò)我希望也能幫你在 Linux 性能調(diào)優(yōu)這條路上少踩幾個(gè)坑。本文還有配套的精品資源點(diǎn)擊獲取