提升linux下tcp服務器并發(fā)連接數(shù)限制_第1頁
提升linux下tcp服務器并發(fā)連接數(shù)限制_第2頁
提升linux下tcp服務器并發(fā)連接數(shù)限制_第3頁
提升linux下tcp服務器并發(fā)連接數(shù)限制_第4頁
提升linux下tcp服務器并發(fā)連接數(shù)限制_第5頁
已閱讀5頁,還剩6頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

1、1、 1、修改用戶進程可打開文件數(shù)限制2、 在Linux平臺上,無論編寫客戶端程序還是服務端程序,在進行高并發(fā)TCP連接處理時,最高的并發(fā)數(shù)量都要受到系統(tǒng)對用戶單一進程同時可打開文件數(shù)量的限制(這是因為系統(tǒng)為每個TCP連接都要創(chuàng)建一個socket句柄,每個socket句柄同時也是一個文件句柄)??墒褂胾limit命令查看系統(tǒng)允許當前用戶進程打開的文件數(shù)限制:3、 spengas4 $ ulimit -n4、 10245、 這表示當前用戶的每個進程最多允許同時打開1024個文件,這1024個文件中還得除去每個進程必然打開的標準輸入,標準輸出,標準錯誤,服務器監(jiān)聽 socket,進程間通訊的uni

2、x域socket等文件,那么剩下的可用于客戶端socket連接的文件數(shù)就只有大概1024-10=1014個左右。也就是說缺省情況下,基于Linux的通訊程序最多允許同時1014個TCP并發(fā)連接。6、 對于想支持更高數(shù)量的TCP并發(fā)連接的通訊處理程序,就必須修改Linux對當前用戶的進程同時打開的文件數(shù)量的軟限制(soft limit)和硬限制(hardlimit)。其中軟限制是指Linux在當前系統(tǒng)能夠承受的范圍內(nèi)進一步限制用戶同時打開的文件數(shù);硬限制則是根據(jù)系統(tǒng)硬件資源狀況(主要是系統(tǒng)內(nèi)存)計算出來的系統(tǒng)最多可同時打開的文件數(shù)量。通常軟限制小于或等于硬限制。7、 修改上述限制的最簡單的辦法就

3、是使用ulimit命令:8、 spengas4 $ ulimit -n 9、 上述命令中,在中指定要設置的單一進程允許打開的最大文件數(shù)。如果系統(tǒng)回顯類似于“Operation notpermitted”之類的話,說明上述限制修改失敗,實際上是因為在中指定的數(shù)值超過了Linux系統(tǒng)對該用戶打開文件數(shù)的軟限制或硬限制。因此,就需要修改Linux系統(tǒng)對用戶的關(guān)于打開文件數(shù)的軟限制和硬限制。10、 第一步,修改/etc/security/limits.conf文件,在文件中添加如下行:11、 speng soft nofile 1024012、 speng hard nofile 1024013、 其

4、中speng指定了要修改哪個用戶的打開文件數(shù)限制,可用*號表示修改所有用戶的限制;soft或hard指定要修改軟限制還是硬限制;10240則指定了想要修改的新的限制值,即最大打開文件數(shù)(請注意軟限制值要小于或等于硬限制)。修改完后保存文件。14、15、 第二步,修改/etc/pam.d/login文件,在文件中添加如下行:16、 session required /lib/security/pam_limits.so17、 這是告訴Linux在用戶完成系統(tǒng)登錄后,應該調(diào)用pam_limits.so模塊來設置系統(tǒng)對該用戶可使用的各種資源數(shù)量的最大限制(包括用戶可打開的最大文件數(shù)限制),而pam_

5、limits.so模塊就會從/etc/security/limits.conf文件中讀取配置來設置這些限制值。修改完后保存此文件。18、 第三步,查看Linux系統(tǒng)級的最大打開文件數(shù)限制,使用如下命令:19、 spengas4 $ cat /proc/sys/fs/file-max20、 1215821、 這表明這臺Linux系統(tǒng)最多允許同時打開(即包含所有用戶打開文件數(shù)總和)12158個文件,是Linux系統(tǒng)級硬限制,所有用戶級的打開文件數(shù)限制都不應超過這個數(shù)值。通常這個系統(tǒng)級硬限制是Linux系統(tǒng)在啟動時根據(jù)系統(tǒng)硬件資源狀況計算出來的最佳的最大同時打開文件數(shù)限制,如果沒有特殊需要,不應該修

6、改此限制,除非想為用戶級打開文件數(shù)限制設置超過此限制的值。修改此硬限制的方法是修改/etc/rc.local腳本,在腳本中添加如下行:22、 echo 22158 /proc/sys/fs/file-max23、 這是讓Linux在啟動完成后強行將系統(tǒng)級打開文件數(shù)硬限制設置為22158。修改完后保存此文件。24、 完成上述步驟后重啟系統(tǒng),一般情況下就可以將Linux系統(tǒng)對指定用戶的單一進程允許同時打開的最大文件數(shù)限制設為指定的數(shù)值。如果重啟后用 ulimit- n命令查看用戶可打開文件數(shù)限制仍然低于上述步驟中設置的最大值,這可能是因為在用戶登錄腳本/etc/profile中使用ulimit-n

7、命令已經(jīng)將用戶可同時打開的文件數(shù)做了限制。由于通過ulimit-n修改系統(tǒng)對用戶可同時打開文件的最大數(shù)限制時,新修改的值只能小于或等于上次ulimit-n 設置的值,因此想用此命令增大這個限制值是不可能的。所以,如果有上述問題存在,就只能去打開/etc/profile腳本文件,在文件中查找是否使用了 ulimit-n限制了用戶可同時打開的最大文件數(shù)量,如果找到,則刪除這行命令,或者將其設置的值改為合適的值,然后保存文件,用戶退出并重新登錄系統(tǒng)即可。25、 通過上述步驟,就為支持高并發(fā)TCP連接處理的通訊處理程序解除關(guān)于打開文件數(shù)量方面的系統(tǒng)限制。26、27、28、 2、修改網(wǎng)絡內(nèi)核對TCP連接

8、的有關(guān)限制29、 在Linux上編寫支持高并發(fā)TCP連接的客戶端通訊處理程序時,有時會發(fā)現(xiàn)盡管已經(jīng)解除了系統(tǒng)對用戶同時打開文件數(shù)的限制,但仍會出現(xiàn)并發(fā)TCP連接數(shù)增加到一定數(shù)量時,再也無法成功建立新的TCP連接的現(xiàn)象。出現(xiàn)這種現(xiàn)在的原因有多種。30、 第一種原因可能是因為Linux網(wǎng)絡內(nèi)核對本地端口號范圍有限制。此時,進一步分析為什么無法建立TCP連接,會發(fā)現(xiàn)問題出在connect()調(diào)用返回失敗,查看系統(tǒng)錯誤提示消息是“Cant assign requestedaddress”。同時,如果在此時用tcpdump工具監(jiān)視網(wǎng)絡,會發(fā)現(xiàn)根本沒有TCP連接時客戶端發(fā)SYN包的網(wǎng)絡流量。這些情況說明問

9、題在于本地Linux系統(tǒng)內(nèi)核中有限制。其實,問題的根本原因在于Linux內(nèi)核的TCP/IP協(xié)議實現(xiàn)模塊對系統(tǒng)中所有的客戶端TCP連接對應的本地端口號的范圍進行了限制(例如,內(nèi)核限制本地端口號的范圍為102432768之間)。當系統(tǒng)中某一時刻同時存在太多的TCP客戶端連接時,由于每個TCP客戶端連接都要占用一個唯一的本地端口號(此端口號在系統(tǒng)的本地端口號范圍限制中),如果現(xiàn)有的TCP客戶端連接已將所有的本地端口號占滿,則此時就無法為新的TCP客戶端連接分配一個本地端口號了,因此系統(tǒng)會在這種情況下在connect()調(diào)用中返回失敗,并將錯誤提示消息設為“Cant assignrequested a

10、ddress”。有關(guān)這些控制邏輯可以查看Linux內(nèi)核源代碼,以linux2.6內(nèi)核為例,可以查看tcp_ipv4.c文件中如下函數(shù):31、 static int tcp_v4_hash_connect(struct sock *sk)32、 請注意上述函數(shù)中對變量sysctl_local_port_range的訪問控制。變量sysctl_local_port_range的初始化則是在tcp.c文件中的如下函數(shù)中設置:33、 void _init tcp_init(void)34、 內(nèi)核編譯時默認設置的本地端口號范圍可能太小,因此需要修改此本地端口范圍限制。35、36、 第一步,修改/etc/

11、sysctl.conf文件,在文件中添加如下行:37、 net.ipv4.ip_local_port_range = 1024 6500038、 這表明將系統(tǒng)對本地端口范圍限制設置為102465000之間。請注意,本地端口范圍的最小值必須大于或等于1024;而端口范圍的最大值則應小于或等于65535。修改完后保存此文件。39、40、 第二步,執(zhí)行sysctl命令:41、 spengas4 $ sysctl -p42、 如果系統(tǒng)沒有錯誤提示,就表明新的本地端口范圍設置成功。如果按上述端口范圍進行設置,則理論上單獨一個進程最多可以同時建立60000多個TCP客戶端連接。43、 第二種無法建立TCP

12、連接的原因可能是因為Linux網(wǎng)絡內(nèi)核的IP_TABLE防火墻對最大跟蹤的TCP連接數(shù)有限制。此時程序會表現(xiàn)為在 connect()調(diào)用中阻塞,如同死機,如果用tcpdump工具監(jiān)視網(wǎng)絡,也會發(fā)現(xiàn)根本沒有TCP連接時客戶端發(fā)SYN包的網(wǎng)絡流量。由于 IP_TABLE防火墻在內(nèi)核中會對每個TCP連接的狀態(tài)進行跟蹤,跟蹤信息將會放在位于內(nèi)核內(nèi)存中的conntrackdatabase中,這個數(shù)據(jù)庫的大小有限,當系統(tǒng)中存在過多的TCP連接時,數(shù)據(jù)庫容量不足,IP_TABLE無法為新的TCP連接建立跟蹤信息,于是表現(xiàn)為在connect()調(diào)用中阻塞。此時就必須修改內(nèi)核對最大跟蹤的TCP連接數(shù)的限制,方法

13、同修改內(nèi)核對本地端口號范圍的限制是類似的:44、45、 第一步,修改/etc/sysctl.conf文件,在文件中添加如下行:46、 net.ipv4.ip_conntrack_max = 1024047、 這表明將系統(tǒng)對最大跟蹤的TCP連接數(shù)限制設置為10240。請注意,此限制值要盡量小,以節(jié)省對內(nèi)核內(nèi)存的占用。48、49、 第二步,執(zhí)行sysctl命令:50、 spengas4 $ sysctl -p51、 如果系統(tǒng)沒有錯誤提示,就表明系統(tǒng)對新的最大跟蹤的TCP連接數(shù)限制修改成功。如果按上述參數(shù)進行設置,則理論上單獨一個進程最多可以同時建立10000多個TCP客戶端連接。52、53、54、

14、 3、使用支持高并發(fā)網(wǎng)絡I/O的編程技術(shù)55、 在Linux上編寫高并發(fā)TCP連接應用程序時,必須使用合適的網(wǎng)絡I/O技術(shù)和I/O事件分派機制。56、 可用的I/O技術(shù)有同步I/O,非阻塞式同步I/O(也稱反應式I/O),以及異步I/O。在高TCP并發(fā)的情形下,如果使用同步I/O,這會嚴重阻塞程序的運轉(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的

15、技術(shù)就是使用AIO。57、58、 從I/O事件分派機制來看,使用select()是不合適的,因為它所支持的并發(fā)連接數(shù)有限(通常在1024個以內(nèi))。如果考慮性能,poll()也是不合適的,盡管它可以支持的較高的TCP并發(fā)數(shù),但是由于其采用“輪詢”機制,當并發(fā)數(shù)較高時,其運行效率相當?shù)停⒖赡艽嬖贗/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連接的情形下使用其實也有嚴重的性能問題。但在最新的Linux內(nèi)核中,AIO的實

16、現(xiàn)已經(jīng)得到改進)。59、60、 綜上所述,在開發(fā)支持高并發(fā)TCP連接的Linux應用程序時,應盡量使用epoll或AIO技術(shù)來實現(xiàn)并發(fā)的TCP連接上的I/O控制,這將為提升程序?qū)Ω卟l(fā)TCP連接的支持提供有效的I/O保證。1、修改用戶進程可打開文件數(shù)限制61、 在Linux平臺上,無論編寫客戶端程序還是服務端程序,在進行高并發(fā)TCP連接處理時,最高的并發(fā)數(shù)量都要受到系統(tǒng)對用戶單一進程同時可打開文件數(shù)量的限制(這是因為系統(tǒng)為每個TCP連接都要創(chuàng)建一個socket句柄,每個socket句柄同時也是一個文件句柄)??墒褂胾limit命令查看系統(tǒng)允許當前用戶進程打開的文件數(shù)限制:62、 spengas

17、4 $ ulimit -n63、 102464、 這表示當前用戶的每個進程最多允許同時打開1024個文件,這1024個文件中還得除去每個進程必然打開的標準輸入,標準輸出,標準錯誤,服務器監(jiān)聽 socket,進程間通訊的unix域socket等文件,那么剩下的可用于客戶端socket連接的文件數(shù)就只有大概1024-10=1014個左右。也就是說缺省情況下,基于Linux的通訊程序最多允許同時1014個TCP并發(fā)連接。65、 對于想支持更高數(shù)量的TCP并發(fā)連接的通訊處理程序,就必須修改Linux對當前用戶的進程同時打開的文件數(shù)量的軟限制(soft limit)和硬限制(hardlimit)。其中軟

18、限制是指Linux在當前系統(tǒng)能夠承受的范圍內(nèi)進一步限制用戶同時打開的文件數(shù);硬限制則是根據(jù)系統(tǒng)硬件資源狀況(主要是系統(tǒng)內(nèi)存)計算出來的系統(tǒng)最多可同時打開的文件數(shù)量。通常軟限制小于或等于硬限制。66、 修改上述限制的最簡單的辦法就是使用ulimit命令:67、 spengas4 $ ulimit -n 68、 上述命令中,在中指定要設置的單一進程允許打開的最大文件數(shù)。如果系統(tǒng)回顯類似于“Operation notpermitted”之類的話,說明上述限制修改失敗,實際上是因為在中指定的數(shù)值超過了Linux系統(tǒng)對該用戶打開文件數(shù)的軟限制或硬限制。因此,就需要修改Linux系統(tǒng)對用戶的關(guān)于打開文件數(shù)

19、的軟限制和硬限制。69、 第一步,修改/etc/security/limits.conf文件,在文件中添加如下行:70、 speng soft nofile 1024071、 speng hard nofile 1024072、 其中speng指定了要修改哪個用戶的打開文件數(shù)限制,可用*號表示修改所有用戶的限制;soft或hard指定要修改軟限制還是硬限制;10240則指定了想要修改的新的限制值,即最大打開文件數(shù)(請注意軟限制值要小于或等于硬限制)。修改完后保存文件。73、74、 第二步,修改/etc/pam.d/login文件,在文件中添加如下行:75、 session required /

20、lib/security/pam_limits.so76、 這是告訴Linux在用戶完成系統(tǒng)登錄后,應該調(diào)用pam_limits.so模塊來設置系統(tǒng)對該用戶可使用的各種資源數(shù)量的最大限制(包括用戶可打開的最大文件數(shù)限制),而pam_limits.so模塊就會從/etc/security/limits.conf文件中讀取配置來設置這些限制值。修改完后保存此文件。77、 第三步,查看Linux系統(tǒng)級的最大打開文件數(shù)限制,使用如下命令:78、 spengas4 $ cat /proc/sys/fs/file-max79、 1215880、 這表明這臺Linux系統(tǒng)最多允許同時打開(即包含所有用戶打開

21、文件數(shù)總和)12158個文件,是Linux系統(tǒng)級硬限制,所有用戶級的打開文件數(shù)限制都不應超過這個數(shù)值。通常這個系統(tǒng)級硬限制是Linux系統(tǒng)在啟動時根據(jù)系統(tǒng)硬件資源狀況計算出來的最佳的最大同時打開文件數(shù)限制,如果沒有特殊需要,不應該修改此限制,除非想為用戶級打開文件數(shù)限制設置超過此限制的值。修改此硬限制的方法是修改/etc/rc.local腳本,在腳本中添加如下行:81、 echo 22158 /proc/sys/fs/file-max82、 這是讓Linux在啟動完成后強行將系統(tǒng)級打開文件數(shù)硬限制設置為22158。修改完后保存此文件。83、 完成上述步驟后重啟系統(tǒng),一般情況下就可以將Linux

22、系統(tǒng)對指定用戶的單一進程允許同時打開的最大文件數(shù)限制設為指定的數(shù)值。如果重啟后用 ulimit- n命令查看用戶可打開文件數(shù)限制仍然低于上述步驟中設置的最大值,這可能是因為在用戶登錄腳本/etc/profile中使用ulimit-n命令已經(jīng)將用戶可同時打開的文件數(shù)做了限制。由于通過ulimit-n修改系統(tǒng)對用戶可同時打開文件的最大數(shù)限制時,新修改的值只能小于或等于上次ulimit-n 設置的值,因此想用此命令增大這個限制值是不可能的。所以,如果有上述問題存在,就只能去打開/etc/profile腳本文件,在文件中查找是否使用了 ulimit-n限制了用戶可同時打開的最大文件數(shù)量,如果找到,則刪

23、除這行命令,或者將其設置的值改為合適的值,然后保存文件,用戶退出并重新登錄系統(tǒng)即可。84、 通過上述步驟,就為支持高并發(fā)TCP連接處理的通訊處理程序解除關(guān)于打開文件數(shù)量方面的系統(tǒng)限制。85、86、87、 2、修改網(wǎng)絡內(nèi)核對TCP連接的有關(guān)限制88、 在Linux上編寫支持高并發(fā)TCP連接的客戶端通訊處理程序時,有時會發(fā)現(xiàn)盡管已經(jīng)解除了系統(tǒng)對用戶同時打開文件數(shù)的限制,但仍會出現(xiàn)并發(fā)TCP連接數(shù)增加到一定數(shù)量時,再也無法成功建立新的TCP連接的現(xiàn)象。出現(xiàn)這種現(xiàn)在的原因有多種。89、 第一種原因可能是因為Linux網(wǎng)絡內(nèi)核對本地端口號范圍有限制。此時,進一步分析為什么無法建立TCP連接,會發(fā)現(xiàn)問題出

24、在connect()調(diào)用返回失敗,查看系統(tǒng)錯誤提示消息是“Cant assign requestedaddress”。同時,如果在此時用tcpdump工具監(jiān)視網(wǎng)絡,會發(fā)現(xiàn)根本沒有TCP連接時客戶端發(fā)SYN包的網(wǎng)絡流量。這些情況說明問題在于本地Linux系統(tǒng)內(nèi)核中有限制。其實,問題的根本原因在于Linux內(nèi)核的TCP/IP協(xié)議實現(xiàn)模塊對系統(tǒng)中所有的客戶端TCP連接對應的本地端口號的范圍進行了限制(例如,內(nèi)核限制本地端口號的范圍為102432768之間)。當系統(tǒng)中某一時刻同時存在太多的TCP客戶端連接時,由于每個TCP客戶端連接都要占用一個唯一的本地端口號(此端口號在系統(tǒng)的本地端口號范圍限制中),

25、如果現(xiàn)有的TCP客戶端連接已將所有的本地端口號占滿,則此時就無法為新的TCP客戶端連接分配一個本地端口號了,因此系統(tǒng)會在這種情況下在connect()調(diào)用中返回失敗,并將錯誤提示消息設為“Cant assignrequested address”。有關(guān)這些控制邏輯可以查看Linux內(nèi)核源代碼,以linux2.6內(nèi)核為例,可以查看tcp_ipv4.c文件中如下函數(shù):90、 static int tcp_v4_hash_connect(struct sock *sk)91、 請注意上述函數(shù)中對變量sysctl_local_port_range的訪問控制。變量sysctl_local_port_ra

26、nge的初始化則是在tcp.c文件中的如下函數(shù)中設置:92、 void _init tcp_init(void)93、 內(nèi)核編譯時默認設置的本地端口號范圍可能太小,因此需要修改此本地端口范圍限制。94、95、 第一步,修改/etc/sysctl.conf文件,在文件中添加如下行:96、 net.ipv4.ip_local_port_range = 1024 6500097、 這表明將系統(tǒng)對本地端口范圍限制設置為102465000之間。請注意,本地端口范圍的最小值必須大于或等于1024;而端口范圍的最大值則應小于或等于65535。修改完后保存此文件。98、99、 第二步,執(zhí)行sysctl命令:1

27、00、 spengas4 $ sysctl -p101、 如果系統(tǒng)沒有錯誤提示,就表明新的本地端口范圍設置成功。如果按上述端口范圍進行設置,則理論上單獨一個進程最多可以同時建立60000多個TCP客戶端連接。102、 第二種無法建立TCP連接的原因可能是因為Linux網(wǎng)絡內(nèi)核的IP_TABLE防火墻對最大跟蹤的TCP連接數(shù)有限制。此時程序會表現(xiàn)為在 connect()調(diào)用中阻塞,如同死機,如果用tcpdump工具監(jiān)視網(wǎng)絡,也會發(fā)現(xiàn)根本沒有TCP連接時客戶端發(fā)SYN包的網(wǎng)絡流量。由于 IP_TABLE防火墻在內(nèi)核中會對每個TCP連接的狀態(tài)進行跟蹤,跟蹤信息將會放在位于內(nèi)核內(nèi)存中的conntrac

28、kdatabase中,這個數(shù)據(jù)庫的大小有限,當系統(tǒng)中存在過多的TCP連接時,數(shù)據(jù)庫容量不足,IP_TABLE無法為新的TCP連接建立跟蹤信息,于是表現(xiàn)為在connect()調(diào)用中阻塞。此時就必須修改內(nèi)核對最大跟蹤的TCP連接數(shù)的限制,方法同修改內(nèi)核對本地端口號范圍的限制是類似的:103、104、 第一步,修改/etc/sysctl.conf文件,在文件中添加如下行:105、 net.ipv4.ip_conntrack_max = 10240106、 這表明將系統(tǒng)對最大跟蹤的TCP連接數(shù)限制設置為10240。請注意,此限制值要盡量小,以節(jié)省對內(nèi)核內(nèi)存的占用。107、108、 第二步,執(zhí)行sysc

29、tl命令:109、 spengas4 $ sysctl -p110、 如果系統(tǒng)沒有錯誤提示,就表明系統(tǒng)對新的最大跟蹤的TCP連接數(shù)限制修改成功。如果按上述參數(shù)進行設置,則理論上單獨一個進程最多可以同時建立10000多個TCP客戶端連接。111、112、113、 3、使用支持高并發(fā)網(wǎng)絡I/O的編程技術(shù)114、 在Linux上編寫高并發(fā)TCP連接應用程序時,必須使用合適的網(wǎng)絡I/O技術(shù)和I/O事件分派機制。115、 可用的I/O技術(shù)有同步I/O,非阻塞式同步I/O(也稱反應式I/O),以及異步I/O。在高TCP并發(fā)的情形下,如果使用同步I/O,這會嚴重阻塞程序的運轉(zhuǎn),除非為每個TCP連接的I/O創(chuàng)

30、建一個線程。但是,過多的線程又會因系統(tǒng)對線程的調(diào)度造成巨大開銷。因此,在高TCP并發(fā)的情形下使用同步I /O 是不可取的,這時可以考慮使用非阻塞式同步I/O或異步I/O。非阻塞式同步I/O的技術(shù)包括使用select(),poll(),epoll等機制。異步I/O的技術(shù)就是使用AIO。116、117、 從I/O事件分派機制來看,使用select()是不合適的,因為它所支持的并發(fā)連接數(shù)有限(通常在1024個以內(nèi))。如果考慮性能,poll()也是不合適的,盡管它可以支持的較高的TCP并發(fā)數(shù),但是由于其采用“輪詢”機制,當并發(fā)數(shù)較高時,其運行效率相當?shù)停⒖赡艽嬖贗/O事件分派不均,導致部分 TCP連

31、接上的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連接的情形下使用其實也有嚴重的性能問題。但在最新的Linux內(nèi)核中,AIO的實現(xiàn)已經(jīng)得到改進)。118、119、 綜上所述,在開發(fā)支持高并發(fā)TCP連接的Linux應用程序時,應盡量使用epoll或AIO技術(shù)來實現(xiàn)并發(fā)的TCP連接上的I/O控制,這將為提升程序?qū)Ω卟l(fā)TCP連接的支持提供有效的I/O保證。1、修改用戶進程可打開文件數(shù)限制120、 在Linux平臺上,無論編寫客戶端程序還是服務端程序,在進行高并

32、發(fā)TCP連接處理時,最高的并發(fā)數(shù)量都要受到系統(tǒng)對用戶單一進程同時可打開文件數(shù)量的限制(這是因為系統(tǒng)為每個TCP連接都要創(chuàng)建一個socket句柄,每個socket句柄同時也是一個文件句柄)??墒褂胾limit命令查看系統(tǒng)允許當前用戶進程打開的文件數(shù)限制:121、 spengas4 $ ulimit -n122、 1024123、 這表示當前用戶的每個進程最多允許同時打開1024個文件,這1024個文件中還得除去每個進程必然打開的標準輸入,標準輸出,標準錯誤,服務器監(jiān)聽 socket,進程間通訊的unix域socket等文件,那么剩下的可用于客戶端socket連接的文件數(shù)就只有大概1024-10=

33、1014個左右。也就是說缺省情況下,基于Linux的通訊程序最多允許同時1014個TCP并發(fā)連接。124、 對于想支持更高數(shù)量的TCP并發(fā)連接的通訊處理程序,就必須修改Linux對當前用戶的進程同時打開的文件數(shù)量的軟限制(soft limit)和硬限制(hardlimit)。其中軟限制是指Linux在當前系統(tǒng)能夠承受的范圍內(nèi)進一步限制用戶同時打開的文件數(shù);硬限制則是根據(jù)系統(tǒng)硬件資源狀況(主要是系統(tǒng)內(nèi)存)計算出來的系統(tǒng)最多可同時打開的文件數(shù)量。通常軟限制小于或等于硬限制。125、 修改上述限制的最簡單的辦法就是使用ulimit命令:126、 spengas4 $ ulimit -n 127、 上

34、述命令中,在中指定要設置的單一進程允許打開的最大文件數(shù)。如果系統(tǒng)回顯類似于“Operation notpermitted”之類的話,說明上述限制修改失敗,實際上是因為在中指定的數(shù)值超過了Linux系統(tǒng)對該用戶打開文件數(shù)的軟限制或硬限制。因此,就需要修改Linux系統(tǒng)對用戶的關(guān)于打開文件數(shù)的軟限制和硬限制。128、 第一步,修改/etc/security/limits.conf文件,在文件中添加如下行:129、 speng soft nofile 10240130、 speng hard nofile 10240131、 其中speng指定了要修改哪個用戶的打開文件數(shù)限制,可用*號表示修改所有用

35、戶的限制;soft或hard指定要修改軟限制還是硬限制;10240則指定了想要修改的新的限制值,即最大打開文件數(shù)(請注意軟限制值要小于或等于硬限制)。修改完后保存文件。132、133、 第二步,修改/etc/pam.d/login文件,在文件中添加如下行:134、 session required /lib/security/pam_limits.so135、 這是告訴Linux在用戶完成系統(tǒng)登錄后,應該調(diào)用pam_limits.so模塊來設置系統(tǒng)對該用戶可使用的各種資源數(shù)量的最大限制(包括用戶可打開的最大文件數(shù)限制),而pam_limits.so模塊就會從/etc/security/limi

36、ts.conf文件中讀取配置來設置這些限制值。修改完后保存此文件。136、 第三步,查看Linux系統(tǒng)級的最大打開文件數(shù)限制,使用如下命令:137、 spengas4 $ cat /proc/sys/fs/file-max138、 12158139、 這表明這臺Linux系統(tǒng)最多允許同時打開(即包含所有用戶打開文件數(shù)總和)12158個文件,是Linux系統(tǒng)級硬限制,所有用戶級的打開文件數(shù)限制都不應超過這個數(shù)值。通常這個系統(tǒng)級硬限制是Linux系統(tǒng)在啟動時根據(jù)系統(tǒng)硬件資源狀況計算出來的最佳的最大同時打開文件數(shù)限制,如果沒有特殊需要,不應該修改此限制,除非想為用戶級打開文件數(shù)限制設置超過此限制的值

37、。修改此硬限制的方法是修改/etc/rc.local腳本,在腳本中添加如下行:140、 echo 22158 /proc/sys/fs/file-max141、 這是讓Linux在啟動完成后強行將系統(tǒng)級打開文件數(shù)硬限制設置為22158。修改完后保存此文件。142、 完成上述步驟后重啟系統(tǒng),一般情況下就可以將Linux系統(tǒng)對指定用戶的單一進程允許同時打開的最大文件數(shù)限制設為指定的數(shù)值。如果重啟后用 ulimit- n命令查看用戶可打開文件數(shù)限制仍然低于上述步驟中設置的最大值,這可能是因為在用戶登錄腳本/etc/profile中使用ulimit-n命令已經(jīng)將用戶可同時打開的文件數(shù)做了限制。由于通過

38、ulimit-n修改系統(tǒng)對用戶可同時打開文件的最大數(shù)限制時,新修改的值只能小于或等于上次ulimit-n 設置的值,因此想用此命令增大這個限制值是不可能的。所以,如果有上述問題存在,就只能去打開/etc/profile腳本文件,在文件中查找是否使用了 ulimit-n限制了用戶可同時打開的最大文件數(shù)量,如果找到,則刪除這行命令,或者將其設置的值改為合適的值,然后保存文件,用戶退出并重新登錄系統(tǒng)即可。143、 通過上述步驟,就為支持高并發(fā)TCP連接處理的通訊處理程序解除關(guān)于打開文件數(shù)量方面的系統(tǒng)限制。144、145、146、 2、修改網(wǎng)絡內(nèi)核對TCP連接的有關(guān)限制147、 在Linux上編寫支持

39、高并發(fā)TCP連接的客戶端通訊處理程序時,有時會發(fā)現(xiàn)盡管已經(jīng)解除了系統(tǒng)對用戶同時打開文件數(shù)的限制,但仍會出現(xiàn)并發(fā)TCP連接數(shù)增加到一定數(shù)量時,再也無法成功建立新的TCP連接的現(xiàn)象。出現(xiàn)這種現(xiàn)在的原因有多種。148、 第一種原因可能是因為Linux網(wǎng)絡內(nèi)核對本地端口號范圍有限制。此時,進一步分析為什么無法建立TCP連接,會發(fā)現(xiàn)問題出在connect()調(diào)用返回失敗,查看系統(tǒng)錯誤提示消息是“Cant assign requestedaddress”。同時,如果在此時用tcpdump工具監(jiān)視網(wǎng)絡,會發(fā)現(xiàn)根本沒有TCP連接時客戶端發(fā)SYN包的網(wǎng)絡流量。這些情況說明問題在于本地Linux系統(tǒng)內(nèi)核中有限制。

40、其實,問題的根本原因在于Linux內(nèi)核的TCP/IP協(xié)議實現(xiàn)模塊對系統(tǒng)中所有的客戶端TCP連接對應的本地端口號的范圍進行了限制(例如,內(nèi)核限制本地端口號的范圍為102432768之間)。當系統(tǒng)中某一時刻同時存在太多的TCP客戶端連接時,由于每個TCP客戶端連接都要占用一個唯一的本地端口號(此端口號在系統(tǒng)的本地端口號范圍限制中),如果現(xiàn)有的TCP客戶端連接已將所有的本地端口號占滿,則此時就無法為新的TCP客戶端連接分配一個本地端口號了,因此系統(tǒng)會在這種情況下在connect()調(diào)用中返回失敗,并將錯誤提示消息設為“Cant assignrequested address”。有關(guān)這些控制邏輯可以查

41、看Linux內(nèi)核源代碼,以linux2.6內(nèi)核為例,可以查看tcp_ipv4.c文件中如下函數(shù):149、 static int tcp_v4_hash_connect(struct sock *sk)150、 請注意上述函數(shù)中對變量sysctl_local_port_range的訪問控制。變量sysctl_local_port_range的初始化則是在tcp.c文件中的如下函數(shù)中設置:151、 void _init tcp_init(void)152、 內(nèi)核編譯時默認設置的本地端口號范圍可能太小,因此需要修改此本地端口范圍限制。153、154、 第一步,修改/etc/sysctl.conf文件,在文件中添加如下行:155、 net.ipv4.ip_local_port_range = 1024 65000156、 這表明將系統(tǒng)對本地端口范圍限制設置為102465000之間。請注意,本地端口范圍的最小值必須大于或等于1024;而端口范圍的最大值則應小于或等于65535。修改完后保存此文件。157、158、 第二步,執(zhí)行sysctl命令:159、 spengas4 $ sysctl -p160、 如果系統(tǒng)沒有錯誤提示,就表明新的本地端口范圍設置成功

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論