linux基礎(chǔ)之-高并發(fā)內(nèi)核優(yōu)化(學(xué)習(xí)起來吧~)
前言
眾所周知在默認(rèn)參數(shù)情況下Linux對高并發(fā)支持并不好,主要受限于單進程最大打開文件數(shù)限制、內(nèi)核TCP參數(shù)方面和IO事件分配機制等。下面就從幾方面來調(diào)整使Linux系統(tǒng)能夠支持高并發(fā)環(huán)境。
1. Iptables相關(guān)
如非必須,關(guān)掉或卸載iptables防火墻,并阻止kernel加載iptables模塊。這些模塊會影響并發(fā)性能。
2. 單進程最大打開文件數(shù)限制
一般的發(fā)行版,限制單進程最大可以打開1024個文件,這是遠遠不能滿足高并發(fā)需求的,調(diào)整過程如下:
將root啟動的單一進程的最大可打開的文件數(shù)設(shè)為65535個。如果系統(tǒng)回顯類似于“Operationnotpermitted”之類的話,說明上述限制修改失敗,實際上是因為在中指定的數(shù)值超過了Linux系統(tǒng)對該用戶打開文件數(shù)的軟限制或硬限制。因此,需修改Linux系統(tǒng)對用戶的關(guān)于打開文件數(shù)的軟限制和硬限制。
第一步,修改limits.conf文件,并添加:
其中’*'號表示修改所有用戶的限制;soft或hard指定要修改軟限制還是硬限制;65536則指定了想要修改的新的限制值,即最大打開文件數(shù)(請注意軟限制值要小于或等于硬限制)。修改完后保存文件。
第二步,修改/etc/pam.d/login文件,在文件中添加如下行:
這告訴Linux在用戶完成系統(tǒng)登錄后,應(yīng)調(diào)用pam_limits.so模塊來設(shè)置系統(tǒng)對該用戶可用的各種資源數(shù)量的最大限制(包括用戶可打開的最大文件數(shù)限制),而pam_limits.so模塊會從/etc/security/limits.conf文件中讀取配置來設(shè)置這些限制值。修改完后保存此文件。
第三步,查看Linux系統(tǒng)級的最大打開文件數(shù)限制,使用如下命令:
表明這臺Linux系統(tǒng)最多允許同時打開(即包含所有用戶打開文件數(shù)總和)32568個文件,是Linux系統(tǒng)級硬限制,所有用戶級的打開文件數(shù)限制都不應(yīng)超過該數(shù)值。通常這個系統(tǒng)級硬限制是Linux系統(tǒng)在啟動時根據(jù)系統(tǒng)硬件資源狀況計算出的最佳的最大同時打開文件數(shù)限制,如無特殊需要,不應(yīng)該修改此限制,除非想為用戶級打開文件數(shù)限制設(shè)置超過此限制的值。修改此硬限制的方法是修改 /etc/sysctl.conf 文件內(nèi) fs.file-max= 131072
這是讓Linux在啟動完成后強行將系統(tǒng)級打開文件數(shù)硬限制設(shè)為131072。
完成上述步驟后重啟系統(tǒng),一般可將Linux系統(tǒng)對指定用戶的單一進程允許同時打開的最大文件數(shù)限制設(shè)為指定值。如重啟后 ulimit -n命令查看用戶可打開文件數(shù)仍低于上步設(shè)的最大值,可能是因在用戶登錄腳本 /etc/profile 中用 ulimit -n 命令已將用戶同時打開的文件數(shù)做了限制。由于通過 ulimit -n 修改系統(tǒng)對用戶可同時打開文件的最大數(shù)限制,新修改值只能小于或等于上次 ulimit -n 設(shè)置值,因此想用此命令增大這個限制值是不可能。所以如有上述問題,就只能去打開 /etc/profile 腳本文件,在文件中查找是否用了 ulimit -n 限制了用戶可同時打開的最大文件數(shù)量,如找到則刪除,或?qū)⑵湓O(shè)為合適值,然后保存文件,用戶退出并重新登錄系統(tǒng)即可。
通過上述步驟,就為支持高并發(fā)TCP連接處理的通訊處理程序解除關(guān)于打開文件數(shù)量方面的系統(tǒng)限制。
【文章福利】小編推薦自己的Linux內(nèi)核技術(shù)交流群:【891587639】整理了一些個人覺得比較好的學(xué)習(xí)書籍、視頻資料共享在群文件里面,有需要的可以自行添加哦!??!前100名進群領(lǐng)取,額外贈送一份價值699的內(nèi)核資料包(含視頻教程、電子書、實戰(zhàn)項目及代碼)??


3. 內(nèi)核TCP參數(shù)方面
Linux系統(tǒng)下,TCP連接斷開后,會以 TIME_WAIT 狀態(tài)保留一定時間,然后才釋放端口。當(dāng)并發(fā)請求過多時,會產(chǎn)生大量 TIME_WAIT 狀態(tài)連接,無法及時斷開會占用大量的端口資源和服務(wù)器資源。這時可優(yōu)化TCP內(nèi)核參數(shù),及時將TIME_WAIT狀態(tài)的端口清理掉。
下面方法只對大量 TIME_WAIT 狀態(tài)的連接導(dǎo)致系統(tǒng)資源消耗有效,如不是這種情況,效果可能不明顯??捎?netstat 命令查 TIME_WAIT 狀態(tài),輸入下面命令,
查看當(dāng)前TCP連接的狀態(tài)和對應(yīng)的連接數(shù)量:
只用關(guān)心 TIME_WAIT 個數(shù),看到有18000多個 TIME_WAIT,這就占了18000多個端口。端口數(shù)量只有65535個,占一個少一個,嚴(yán)重影響到新連接。這時,有必要調(diào)整下Linux的TCP內(nèi)核參數(shù),讓系統(tǒng)更快的釋放TIME_WAIT連接。
編輯配置文件:/etc/sysctl.conf,在這個文件中,加入下面幾行內(nèi)容:
經(jīng)過這樣調(diào)整后,除進一步提升服務(wù)器的負載能力外,還能防御小流量程度的DoS、CC和SYN攻擊。
此外,如果連接數(shù)本身就很多,可再優(yōu)化TCP 的可用端口范圍,進一步提升服務(wù)器的并發(fā)能力。依然是往上面的參數(shù)文件中,加入下面配置:
這幾個參數(shù),建議在流量非常大的服務(wù)器上開啟,會有顯著效果。一般的流量小的服務(wù)器上,沒必要去設(shè)這幾個參數(shù)。
4. 內(nèi)核其他TCP參數(shù)說明
同時還涉及到 TCP 擁塞算法問題,可用下面命令查看本機的擁塞算法控制模塊:
5. IO事件分配機制
在Linux啟用高并發(fā)TCP連接,必須確認(rèn)應(yīng)用程序是否用了合適的網(wǎng)絡(luò) I/O 技術(shù)和 I/O 事件分派機制??捎玫?I/O 技術(shù)有同步 I/O ,非阻塞式同步I/O ,以及異步I/O。在高TCP并發(fā)情形下,如果用同步I/O,會嚴(yán)重阻塞程序運轉(zhuǎn),除非為每個TCP連接的I/O創(chuàng)建個線程。但過多的線程又會因系統(tǒng)對線程的調(diào)度造成巨大開銷。
因此,在高TCP并發(fā)的情形下用同步I/O不可取,這時可考慮用非阻塞式同步I/O或異步I/O。非阻塞式同步I/O的技術(shù)包括使用select(),poll(),epoll等機制。異步I/O技術(shù)就是用AIO。
從I/O事件分派機制來看,用select()不合適,因為它所支持的并發(fā)連接數(shù)有限(通常在1024個以內(nèi))。如果考慮性能,poll()也不合適,盡管它可支持的較高的TCP并發(fā)數(shù),但由于其采用“輪詢”機制,當(dāng)并發(fā)數(shù)較高時,其運行效率相當(dāng)?shù)?,并可能存在I/O事件分派不均,導(dǎo)致部分TCP連接上的I/O出現(xiàn)“饑餓”現(xiàn)象。
而如果用epoll或AIO,則無上述問題(早期Linux內(nèi)核的AIO技術(shù)實現(xiàn)是通過在內(nèi)核中為每個I/O請求創(chuàng)建個線程來實現(xiàn)的,這種實現(xiàn)機制在高并發(fā)TCP連接的情形下使用其實也有嚴(yán)重的性能問題。但在最新的Linux內(nèi)核中,AIO的實現(xiàn)已得到改進)。
綜上所述,在開發(fā)支持高并發(fā)TCP連接的Linux應(yīng)用程序時,應(yīng)盡量用epoll或AIO技術(shù)來實現(xiàn)并發(fā)的TCP連接上的I/O控制,這將為提升程序?qū)Ω卟l(fā)TCP連接的支持提供有效的I/O保證。
經(jīng)過這樣優(yōu)化配置后,服務(wù)器的TCP并發(fā)處理能力會顯著提高。以上配置僅供參考,用于生產(chǎn)環(huán)境請根據(jù)自己的實際情況調(diào)整觀察再調(diào)整。
