web伺服器和cache伺服器,高並發下,socket最大聯接數限制調整:
1,更改使用者程序可開啟最大檔案數限制。
即時生效:ulimit-nxxx
永久生效:
echo"ulimit-HSn65536">>/etc/rc.local
echo"ulimit-HSn65536">>/root/.bash_profile
ulimit-HSn65536
2,更改網路核心對最大tcp聯接數限制。
/etc/sysctl.conf
一、
在Linux平台上,無論編撰客戶端程序還是服務端程序,在進列寬並發TCP聯接處理時,最高的並發數目都要遭到系統對用戶單一進程同時可打開文件數目的限制(這是由於系統為每位TCP聯結都要建立一個socket句柄,每位socket句柄同時也是一個檔案句柄)。諸如:一個redis程序,只啟動一個進程,則只能開啟1024個檔案(預設1024)(1024個tcp連線=1024個socket聯接句柄=1024個檔案句柄),
可使用ulimit指令查看系統容許目前使用者程序開啟的檔案數限制:
$ulimit-n
1024
這表示當前用戶的每位進程最多容許同時打開1024個文件,這1024個文件中還得去除每位進程必然打開的標準輸入,標準輸出,標準錯誤,伺服器竊聽socket,進程間通信的unix域socket等文件,這麼剩下的可用於顧客端socket聯接的文件數就只有大約1024-10=1014個左右。也就是說預設情況下,基於Linux的通訊程序最多容許同時1014個TCP並發聯接。
對於想支援更高數目的TCP並發聯接的通訊處理程序,就必須更改Linux對目前使用者的進程同時開啟的檔案數目:
軟限制(softlimit):是指Linux在目前系統還能承受的範圍內進一步限制使用者同時開啟的檔案數;
硬限制(hardlimit):是依據系統硬體資源狀況(主要是系統顯存)估算下來的系統最多可同時開啟的檔案數目。
一般軟限制大於或等於硬限制
更改單一進程開啟最大檔案數限制的最簡單的方法就是使用ulimit命令:
[speng@as4~]$ulimit-n
上述指令中,在手指定要設定的單一程序容許開啟的最大檔案數。假如係統回顯類似於"Operationnotpermitted"之類的話嵌入式linux培訓,說明上述限制更改失敗,實際上是由於在手指定的數值超過了Linux系統對該用戶打開文件數的軟限製或硬限制。因而,就須要更改Linux系統對使用者的關於開啟檔案數的軟限制和硬限制。
第一步,更改/etc/security/limits.conf文件,在文件中加入以下行:
spengsoftnofile10240
spenghardnofile10240
其中speng指定了要更改那個使用者的開啟檔案數限制,可用'*'號表示更改所有使用者的限制;
soft或hard指定要更改軟體限制還是硬限制;10240則指定了想要更改的新的限制值,即最大開啟檔案數(請注意軟限制值大於或等於硬限制)。更改完後儲存文件。
第二步,更改/etc/pam.d/login文件,在文件中添加如下行:
sessionrequired/lib/security/pam_limits.so這是告訴Linux在使用者完成系統登陸後,應當呼叫pam_limits.so模組來設定係統對該使用者可使用的各類資源數目的最大限制(包括使用者可開啟的最大檔案數限制),而pam_limits.so模組都會從/etc/security/limits.conf檔案中讀取設定來設定這種限制值。更改完後儲存此文件。
第三步,查看Linux系統層級的最大開啟檔案數限制,使用下列指令:
[speng@as4~]$cat/proc/sys/fs/file-max
12158
這表示這台Linux系統最多容許同時開啟(即包含所有使用者開啟檔案數總和)12158個文件,是Linux系統級硬限制,所有使用者層級的開啟檔案數限制都不應超過這個數值。一般這個系統級硬限制是Linux系統在啟動時按照系統硬體資源狀況估算下來的最佳的最大同時打開文件數限制,假如沒有特殊須要,不應當更改此限制,除非想為用戶級打開文件數限制設定超過此限制的值。
更改此硬限制的方式是更改/etc/rc.local腳本,在腳本中添加如下行:
echo22158>/proc/sys/fs/file-max
這是讓Linux在啟動完成後強行將系統級開啟檔案數硬限制設定為22158.更改完後儲存此檔案。
完成上述步驟後重新啟動系統,通常情況下就可以將Linux系統對指定使用者的單一進程容許同時開啟的最大檔案數限制設為指定的數值。假如重啟後用ulimit-n命令查看用戶可打開文件數限制始終高於上述步驟中設定的最大值,這可能是由於在用戶登錄腳本/etc/profile中使用ulimit-n命令早已將用戶可同時打開的文件數做了限制。因為透過ulimit-n更改系統對使用者可同時開啟檔案的最大數限制時,新更改的值只能大於或等於先前ulimit-n設定的值,因而想用此指令來減少這個限制值是不可能的。
所以,假若有上述問題存在,就只能去打開/etc/profile腳本文件,在文件中查找是否使用了ulimit-n限制了用戶可同時打開的最大文件數目,假若找到,則刪掉這行命令,或則將其設定的值改為合適的值,之後保存文件,用戶退出並重新登錄系統即可。透過上述步驟,就為支援高並發TCP連結處理的通訊處理程序解除關於開啟檔案數目方面的系統限制。
二、修改網路內核對TCP聯接的有關限制
在Linux上編撰支援高並發TCP聯接的顧客端通訊處理程序時,有時會發覺雖然早已解除了系統對用戶同時開啟檔案數的限制,但仍會出現並發TCP聯接數降低到一定數目時,再也未能成功建構新的TCP連結的現象。出現這些現今的緣由有多種。
Sebab pertama mungkin kernel rangkaian Linux mempunyai sekatan pada julat nombor port tempatan. Pada masa ini, jika anda menganalisis lebih lanjut mengapa sambungan TCP tidak dapat diselesaikan, anda akan mendapati bahawa masalahnya ialah panggilan connect() gagal dikembalikan Mesej ralat sistem ialah "Can'tassignrequestedaddress". anda menggunakan alat tcpdump untuk memantau rangkaian pada masa ini, anda akan Didapati bahawa tiada trafik rangkaian untuk pelanggan menghantar paket SYN semasa sambungan TCP. Keadaan ini menunjukkan bahawa masalahnya terletak pada batasan dalam kernel sistem Linux tempatan.
Walaupun, punca masalah ialah modul pelaksanaan kontrak TCP/IP kernel Linux mengehadkan julat nombor port tempatan yang sepadan dengan semua sambungan TCP pelanggan dalam sistem (contohnya, kernel mengehadkan julat port tempatan nombor hingga 1024~32768 antara). Apabila terdapat terlalu banyak sambungan klien TCP dalam sistem pada masa tertentu, kerana setiap sambungan klien TCP menduduki nombor port tempatan yang unik (nombor port ini berada dalam had julat nombor port tempatan sistem), jika Sesetengah sambungan klien TCP mempunyai menduduki semua nombor port tempatan, dan sukar untuk memperuntukkan nombor port tempatan untuk sambungan klien TCP baharu Atas sebab ini, sistem akan kembali dalam panggilan connect() dalam kes ini dan menetapkan mesej ralat kepada "Can 'tassignrequestedaddress".
Untuk logik kawalan ini, anda boleh melihat kod sumber kernel Linux Mengambil kernel linux2.6 sebagai contoh, anda boleh melihat fungsi berikut dalam fail tcp_ipv4.c:
.staticinttcp_v4_hash_connect(structsock*sk)
Sila ambil perhatian kawalan akses kepada pembolehubah sysctl_local_port_range dalam fungsi di atas. Permulaan pembolehubah sysctl_local_port_range ditetapkan dalam fungsi berikut dalam fail tcp.c:
void__inittcp_init(void)
Julat nombor port tempatan lalai yang ditetapkan apabila kernel disusun mungkin terlalu kecil, jadi had julat port tempatan ini perlu ditukar.
Langkah pertama ialah menukar fail /etc/sysctl.conf untuk memuat turun imej sistem linux dan menambah baris berikut pada fail:
net.ipv4.ip_local_port_range=102465000
Ini menunjukkan bahawa had julat port tempatan sistem ditetapkan kepada antara 1024~65000. Sila ambil perhatian bahawa nilai minimum julat port tempatan mestilah kurang daripada atau sama dengan 1024 dan nilai maksimum julat port hendaklah lebih besar daripada atau sama dengan 65535. Simpan fail ini selepas membuat perubahan.
Langkah kedua ialah melaksanakan arahan sysctl:
[speng@as4~]$sysctl-p
Jika tiada mesej ralat dalam sistem, ini bermakna julat port tempatan baharu berjaya ditetapkan. Jika ditetapkan mengikut julat port di atas, secara teorinya satu proses boleh melengkapkan lebih daripada 60,000 sambungan klien TCP pada masa yang sama.
Sebab kedua kegagalan untuk melengkapkan sambungan TCP mungkin kerana tembok api kernel rangkaian Linux mempunyai had pada bilangan maksimum sambungan TCP yang dijejaki. Pada masa ini, program akan kelihatan disekat dalam panggilan connect(), sama seperti mematikan Jika anda menggunakan alat tcpdump untuk memantau rangkaian, anda juga akan mendapati bahawa tiada trafik rangkaian untuk pelanggan menghantar SYN. paket semasa sambungan TCP. Kerana tembok api akan menjejaki status setiap sambungan TCP dalam kernel, maklumat penjejakan akan diletakkan dalam pangkalan data conntrack yang terletak dalam memori kernel Saiz pangkalan data ini adalah terhad Apabila terdapat terlalu banyak sambungan TCP dalam sistem. kapasiti pangkalan data tidak mencukupi , IP_TABLE gagal membina maklumat pengesanan untuk sambungan TCP baharu, jadi ia kelihatan menyekat dalam panggilan connect(). Pada ketika ini, anda mesti menukar had kernel pada bilangan maksimum sambungan TCP yang dijejaki Teknik ini serupa dengan menukar had kernel pada julat nombor port tempatan:
Langkah pertama ialah menukar fail /etc/sysctl.conf dan tambah baris berikut pada fail:
net.ipv4.ip_conntrack_max=10240
Ini menunjukkan bahawa had sistem pada bilangan maksimum sambungan TCP yang dijejaki ditetapkan kepada 10240. Sila ambil perhatian bahawa nilai had ini hendaklah sekecil mungkin untuk menjimatkan penggunaan memori kernel.
Langkah kedua ialah melaksanakan arahan sysctl:
[speng@as4~]$sysctl-p
Jika tiada mesej ralat dalam sistem, ini bermakna sistem telah berjaya menukar had bilangan maksimum sambungan TCP yang dijejaki. Jika parameter di atas ditetapkan, secara teorinya satu proses boleh melengkapkan lebih daripada 10,000 sambungan klien TCP pada masa yang sama.
Tiga,
Apabila menggunakan teknologi pengaturcaraan yang menyokong I/O rangkaian serentak tinggi untuk menyusun aplikasi sambungan TCP serentak tinggi di Linux, anda mesti menggunakan teknologi I/O rangkaian dan mekanisme penghantaran ribut I/O yang sesuai. Teknologi I/O yang tersedia termasuk I/O segerak, I/O segerak tidak menyekat (juga dikenali sebagai I/O reaktif), dan I/O tak segerak Dalam kes konkurensi TCP tinggi, jika I/O segerak digunakan, Ini akan menyekat operasi program dengan teruk melainkan satu utas dicipta untuk setiap I/O sambungan TCP.
Walau bagaimanapun, had nombor sambungan linux tcp, terlalu banyak benang akan menyebabkan perbelanjaan yang besar disebabkan penjadualan rangkaian sistem. Atas sebab ini, adalah tidak digalakkan untuk menggunakan I/O segerak dalam situasi konkurensi TCP tinggi Dalam kes ini, anda boleh mempertimbangkan untuk menggunakan teknik I/O segerak tidak menyekat atau I/O tidak menyekat menggunakan select (), poll(), epoll dan mekanisme lain. Teknologi I/O tak segerak ialah menggunakan AIO.
Dari perspektif mekanisme penghantaran ribut I/O, adalah tidak sesuai untuk menggunakan select() kerana ia menyokong bilangan sambungan serentak yang terhad (biasanya dalam lingkungan 1024). Jika prestasi dipertimbangkan, poll() juga tidak sesuai linux tcp connection number limit, walaupun ia boleh menyokong bilangan TCP concurrency yang lebih tinggi, dan kerana ia menggunakan mekanisme "coroutine", apabila bilangan concurrency adalah tinggi, ia berjalan Kecekapan agak rendah, dan mungkin terdapat taburan gelombang I/O yang tidak sekata, menyebabkan I/O "kebuluran" pada beberapa sambungan TCP. Jika anda menggunakan epoll atau AIO, tiada masalah sedemikian (pelaksanaan awal teknologi AIO dalam kernel Linux telah dicapai dengan mencipta benang untuk setiap permintaan I/O dalam kernel. Mekanisme pelaksanaan ini digunakan dalam kes high- concurrency sambungan TCP nampaknya juga terdapat masalah prestasi yang serius Tetapi dalam kernel Linux terkini, pelaksanaan AIO telah lama dipertingkatkan.
Ringkasnya, apabila membangunkan aplikasi Linux yang menyokong sambungan TCP serentak tinggi, teknologi epoll atau AIO harus digunakan sebaik mungkin untuk mencapai kawalan I/O pada sambungan TCP serentak Ini akan meningkatkan keupayaan program untuk mengendalikan TCP serentak tinggi sambungan. Sokongan menyediakan jaminan I/O yang berkesan.
Pengoptimuman parameter kernel sysctl.conf
/etc/sysctl.conf ialah fail konfigurasi yang digunakan untuk mengawal rangkaian Linux Ia sangat penting untuk program yang bergantung pada rangkaian (seperti pelayan web dan pelayan cache RHEL menyediakan pelarasan terbaik secara lalai).
Konfigurasi yang disyorkan (kosongkan kandungan /etc/sysctl.conf asal dan salin kandungan berikut ke dalamnya):
cp/etc/sysctl.conf/etc/sysctl.conf.bak
echo"">/etc/sysctl.conf
vim/etc/sysctl.conf
net.ipv4.ip_local_port_range=102465535
net.core.rmem_max=16777216
net.core.wmem_max=16777216
net.ipv4.tcp_rmem=40968738016777216
net.ipv4.tcp_wmem=40966553616777216
net.ipv4.tcp_fin_timeout=10
net.ipv4.tcp_tw_recycle=1
net.ipv4.tcp_timestamps=0
net.ipv4.tcp_window_scaling=0
net.ipv4.tcp_sack=0
dev_max_backlog=30000
net.ipv4.tcp_no_metrics_save=1
net.core.somaxconn=10240
net.ipv4.tcp_syncookies=0
net.ipv4.tcp_max_orphans=262144
net.ipv4.tcp_max_syn_backlog=262144
net.ipv4.tcp_synack_retries=2
net.ipv4.tcp_syn_retries=2
Konfigurasi ini merujuk kepada konfigurasi varnis pelayan cache yang disyorkan dan konfigurasi pengoptimuman sistem pelayan SunOne yang disyorkan.
Walau bagaimanapun, konfigurasi yang disyorkan oleh Varnish adalah bermasalah Operasi sebenar menunjukkan bahawa konfigurasi "net.ipv4.tcp_fin_timeout=3" selalunya akan menyebabkan halaman gagal dibuka dan apabila netizen menggunakan pelayar IE6, selepas melawati tapak web untuk a tempoh masa, Semua halaman web tidak akan dapat dibuka dan akan berfungsi seperti biasa selepas memulakan semula penyemak imbas. Mungkin kelajuan Internet di Amerika Syarikat adalah pantas, tetapi keadaan negara kita menentukan bahawa kita perlu melaraskan "net.ipv4.tcp_fin_timeout=10". Dalam kes 10 saat, semuanya adalah normal (inferens operasi sebenar).
Selepas perubahan selesai, laksanakan:
sysctl-p/etc/sysctl.conf
sysctl-wnet.ipv4.route.flush=1
Arahan berkuat kuasa. Untuk berada di bahagian yang selamat, anda juga boleh but semula sistem.
Laraskan bilangan maksimum pemegang fail terbuka (bilangan maksimum sambungan tcp dalam satu proses = bilangan maksimum sambungan soket dalam satu proses):
Selepas mengoptimumkan rangkaian sistem Linux, bilangan fail yang dibenarkan untuk dibuka oleh sistem mesti ditambah untuk menyokong konkurensi yang besar 1024 lalai adalah jauh dari mencukupi.
Melaksanakan arahan:
Kod Shell
gema "ulimit-HSn65536">>/etc/rc.local
gema "ulimit-HSn65536">>/root/.bash_profile
ulimit-HSn65535
以上是高並發下 web 伺服器和 cache 伺服器 socket 最大連線數限制調整方法的詳細內容。更多資訊請關注PHP中文網其他相關文章!