Iptables berkaitan
Jika tidak perlu, matikan atau nyahpasang tembok api iptables dan halang kernel daripada memuatkan modul iptables. Modul ini boleh menjejaskan prestasi konkurensi.
Hadkan bilangan maksimum fail yang dibuka dengan satu proses
Pengedaran umum mengehadkan satu proses kepada maksimum 1024 fail, yang jauh daripada memenuhi keperluan konkurensi yang tinggi Proses pelarasan adalah seperti berikut: taip di # prompt Enter:
# ulimit–n 65535
Salin selepas log masuk
Tetapkan bilangan maksimum fail yang boleh dibuka dengan satu proses yang dimulakan oleh root kepada 65535. Jika sistem menggemakan sesuatu seperti "Operasi tidak dibenarkan", ini bermakna pengubahsuaian had di atas gagal Malah, nilai yang dinyatakan melebihi had lembut atau had keras sistem Linux pada bilangan fail yang boleh dibuka oleh pengguna. Oleh itu, adalah perlu untuk mengubah suai had lembut dan keras sistem Linux pada bilangan fail terbuka untuk pengguna.
Langkah pertama adalah untuk mengubah suai fail Limits.conf dan tambah:
# vim /etc/security/limits.conf
* softnofile 65536
* hard nofile65536
Salin selepas log masuk
ethe '*' Tanda menunjukkan pengubahsuaian semua pengguna; yang anda ingin ubah Nilai had baharu ialah bilangan maksimum fail terbuka (sila ambil perhatian bahawa nilai had lembut mestilah kurang daripada atau sama dengan had keras). Simpan fail selepas membuat perubahan. Langkah kedua ialah mengubah suai fail /etc/pam.d/login dan menambah baris berikut pada fail:
# vim /etc/pam.d/login
sessionrequired /lib/security/pam_limits.so
Salin selepas log masuk
Ini memberitahu Linux bahawa selepas pengguna melengkapkan log masuk sistem, modul pam_limits.so harus dipanggil untuk ditetapkan sistem tersedia kepada pengguna Had maksimum pada bilangan pelbagai sumber (termasuk had bilangan maksimum fail yang boleh dibuka oleh pengguna), dan modul pam_limits.so akan membaca konfigurasi daripada /etc/ security/limits.conf fail untuk menetapkan nilai had ini. Simpan fail ini selepas pengubahsuaian.
第三步,查看Linux系统级的最大打开文件数限制,使用如下命令:
# cat/proc/sys/fs/file-max
32568
Salin selepas log masuk
这表明这台Linux系统最多允许同时打开(即包含所有用户打开文件数总和)32568个文件,是Linux系统级硬限制,所有用户级的打开文件数限制都不应超过这个数值。通常这个系统级硬限制是Linux系统在启动时根据系统硬件资源状况计算出来的最佳的最大同时打开文件数限制,如果没有特殊需要,不应该修改此限制,除非想为用户级打开文件数限制设置超过此限制的值。修改此硬限制的方法是修改/etc/sysctl.conf文件内fs.file-max= 131072
这是让Linux在启动完成后强行将系统级打开文件数硬限制设置为131072。修改完后保存此文件。
完成上述步骤后重启系统,一般情况下就可以将Linux系统对指定用户的单一进程允许同时打开的最大文件数限制设为指定的数值。如果重启后用ulimit-n命令查看用户可打开文件数限制仍然低于上述步骤中设置的最大值,这可能是因为在用户登录脚本/etc/profile中使用ulimit-n命令已经将用户可同时打开的文件数做了限制。
由于通过ulimit-n修改系统对用户可同时打开文件的最大数限制时,新修改的值只能小于或等于上次ulimit-n设置的值,因此想用此命令增大这个限制值是不可能的。所以,如果有上述问题存在,就只能去打开/etc/profile脚本文件,在文件中查找是否使用了ulimit-n限制了用户可同时打开的最大文件数量,如果找到,则删除这行命令,或者将其设置的值改为合适的值,然后保存文件,用户退出并重新登录系统即可。
通过上述步骤,就为支持高并发TCP连接处理的通讯处理程序解除关于打开文件数量方面的系统限制。
内核TCP参数方面
Linux系统下,TCP连接断开后,会以TIME_WAIT状态保留一定的时间,然后才会释放端口。当并发请求过多的时候,就会产生大量的TIME_WAIT状态的连接,无法及时断开的话,会占用大量的端口资源和服务器资源。这个时候我们可以优化TCP的内核参数,来及时将TIME_WAIT状态的端口清理掉。
下面介绍的方法只对拥有大量TIME_WAIT状态的连接导致系统资源消耗有效,如果不是这种情况下,效果可能不明显。可以使用netstat命令去查TIME_WAIT状态的连接状态,输入下面的组合命令,查看当前TCP连接的状态和对应的连接数量:
# netstat-n | awk ‘/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}’
Salin selepas log masuk
这个命令会输出类似下面的结果:
LAST_ACK16
SYN_RECV348
ESTABLISHED70
FIN_WAIT1229
FIN_WAIT230
CLOSING33
TIME_WAIT18098
Salin selepas log masuk
我们只用关心TIME_WAIT的个数,在这里可以看到,有18000多个TIME_WAIT,这样就占用了18000多个端口。要知道端口的数量只有65535个,占用一个少一个,会严重的影响到后继的新连接。这种情况下,我们就有必要调整下Linux的TCP内核参数,让系统更快的释放TIME_WAIT连接。
编辑配置文件:/etc/sysctl.conf,在这个文件中,加入下面的几行内容:
# vim /etc/sysctl.conf
net.ipv4.tcp_syncookies= 1
net.ipv4.tcp_tw_reuse= 1
net.ipv4.tcp_tw_recycle= 1
net.ipv4.tcp_fin_timeout= 30
Salin selepas log masuk
输入下面的命令,让内核参数生效:
# sysctl-p
Salin selepas log masuk
简单的说明上面的参数的含义:
- net.ipv4.tcp_syncookies= 1 表示开启SYNCookies。当出现SYN等待队列溢出时,启用cookies来处理,可防范少量SYN攻击,默认为0,表示关闭;
- net.ipv4.tcp_tw_reuse= 1 表示开启重用。允许将TIME-WAITsockets重新用于新的TCP连接,默认为0,表示关闭;
- net.ipv4.tcp_tw_recycle= 1 表示开启TCP连接中TIME-WAITsockets的快速回收,默认为0,表示关闭;
- net.ipv4.tcp_fin_timeout 修改系統默认的TIMEOUT 时间。
在经过这样的调整之后,除了会进一步提升服务器的负载能力之外,还能够防御小流量程度的DoS、CC和SYN攻击。
此外,如果你的连接数本身就很多,我们可以再优化一下TCP的可使用端口范围,进一步提升服务器的并发能力。依然是往上面的参数文件中,加入下面这些配置:
net.ipv4.tcp_keepalive_time= 1200
net.ipv4.ip_local_port_range= 1024 65535
net.ipv4.tcp_max_syn_backlog= 8192
net.ipv4.tcp_max_tw_buckets= 5000
Salin selepas log masuk
这几个参数,建议只在流量非常大的服务器上开启,会有显著的效果。一般的流量小的服务器上,没有必要去设置这几个参数。
- net.ipv4.tcp_keepalive_time= 1200 menunjukkan kekerapan TCP menghantar mesej keepalive apabila keepalive didayakan. Lalai ialah 2 jam, tukar kepada 20 minit.
- ip_local_port_range= 1024 65535 menunjukkan julat port yang digunakan untuk sambungan keluar. Lalai adalah sangat kecil, ditukar kepada 1024 kepada 65535.
- net.ipv4.tcp_max_syn_backlog= 8192 menunjukkan panjang baris gilir SYN, lalai ialah 1024, meningkatkan panjang baris gilir kepada 8192 boleh menampung lebih banyak sambungan rangkaian menunggu sambungan.
- net.ipv4.tcp_max_tw_buckets= 5000 bermakna sistem mengekalkan bilangan maksimum TIME_WAIT pada masa yang sama Jika nombor ini melebihi, TIME_WAIT akan dikosongkan serta-merta dan mesej amaran akan dicetak. Lalai ialah 180000, tukar kepada 5000. Parameter ini boleh mengawal bilangan maksimum TIME_WAIT, selagi ia melebihi. Perihalan parameter TCP lain bagi kernel
- net.ipv4.tcp_max_syn_backlog= 65536 Nilai maksimum permintaan sambungan yang direkodkan yang belum menerima maklumat pengesahan pelanggan. Untuk sistem dengan memori 128M, nilai lalai ialah 1024, dan untuk sistem dengan ingatan kecil, ia adalah 128.
- net.core.netdev_max_backlog= 32768 Bilangan maksimum paket yang dibenarkan untuk beratur apabila setiap antara muka rangkaian menerima paket lebih cepat daripada kernel boleh memprosesnya.
- net.core.somaxconn= 32768 Sebagai contoh, tunggakan fungsi dengar dalam aplikasi web akan mengehadkan net.core.somaxconn parameter kernel kami kepada 128 secara lalai, dan NGX_LISTEN_BACKLOG yang ditakrifkan oleh nginx menjadi lalai kepada 511 , jadi adalah perlu untuk melaraskan nilai ini.
- net.core.wmem_default = 8388608
- net.core.rmem_default = 8388608
- net.core.rmem_max = 16777216 #Maximum Socket Read Buffer, Nilai Pengoptimuman Rujukan: 8732 00
- .core.wmem_max= 16777216 #Penimbal tulis soket maksimum, nilai pengoptimuman rujukan: 873200
- net.ipv4.tcp_timestsmps= 0 Cap masa boleh mengelakkan pembalut nombor jujukan. Pautan 1Gbps pasti akan menemui nombor urutan yang telah digunakan sebelum ini. Cap masa membenarkan kernel menerima paket "tidak normal" sedemikian. Ia perlu dimatikan di sini.
- net.ipv4.tcp_synack_retries= 2 Untuk membuka sambungan kepada peer, kernel perlu menghantar SYN dengan ACK sebagai tindak balas kepada SYN sebelumnya. Ini adalah jabat tangan kedua dalam apa yang dipanggil jabat tangan tiga hala. Tetapan ini menentukan bilangan paket SYN+ACK yang dihantar oleh kernel sebelum menghentikan sambungan.
- net.ipv4.tcp_syn_retries= 2 Bilangan paket SYN yang dihantar sebelum kernel berhenti membuat sambungan.
- net.ipv4.tcp_tw_reuse= 1 Dayakan guna semula. Membenarkan soket TIME-WAIT digunakan semula untuk sambungan TCP baharu.
- net.ipv4.tcp_wmem= 8192 436600 873200 penimbal tulis TCP, nilai pengoptimuman rujukan: 8192 436600 873200
-
- 0 873200 TCP baca penimbal, nilai pengoptimuman rujukan: 32768 436600 873200
- net.ipv4.tcp_mem= 94500000 91500000 92700000 Terdapat juga 3 nilai, bermakna:
- net.ipv4.tcp_mem[0]: Di bawah nilai ini, TCP tidak mempunyai tekanan, 🎜🎜🎜🎜net.ipv4.tcp_mem[1]: Pada nilai ini, masukkan peringkat tekanan memori.
- net.ipv4.tcp_mem[2]: Di atas nilai ini, TCP enggan memperuntukkan soket. Unit memori yang dinyatakan di atas adalah halaman, bukan bait. Nilai pengoptimuman rujukan ialah: 7864321048576 1572864
- net.ipv4.tcp_max_orphans= 3276800 Bilangan maksimum soket TCP dalam sistem yang tidak dikaitkan dengan mana-mana pemegang fail pengguna. Jika nombor ini melebihi, sambungan akan ditetapkan semula serta-merta dan mesej amaran akan dicetak. Had ini hanya untuk menghalang serangan DoS mudah Anda tidak boleh terlalu bergantung padanya atau mengurangkan nilai ini secara buatan Anda harus meningkatkan nilai ini (jika anda meningkatkan memori).
- net.ipv4.tcp_fin_timeout= 30 Jika soket diminta untuk ditutup oleh hujung setempat, parameter ini menentukan berapa lama ia kekal dalam keadaan FIN-WAIT-2. Rakan sebaya boleh membuat kesilapan dan tidak pernah menutup sambungan, malah ranap tanpa diduga. Nilai lalai ialah 60 saat. Nilai biasa untuk 2.2 kernel ialah 180 saat Anda boleh menekan tetapan ini, tetapi ingat bahawa walaupun mesin anda adalah pelayan WEB yang dimuatkan dengan ringan, terdapat risiko limpahan memori disebabkan oleh sejumlah besar soket mati. 2 kurang berbahaya daripada FIN-WAIT-1 kerana ia hanya boleh memakan sehingga 1.5K memori, tetapi tempoh kemandirian mereka lebih lama.
Ia juga melibatkan isu algoritma kesesakan TCP Anda boleh menggunakan arahan berikut untuk melihat modul kawalan algoritma kesesakan yang disediakan oleh mesin ini:
-
sysctl net.ipv4.tcp_available_congestion_controlUntuk beberapa algoritma
. , sila rujuk perkara berikut untuk mendapatkan butiran: kelebihan dan kekurangan, persekitaran yang berkenaan dan analisis prestasi algoritma kawalan kesesakan TCP Contohnya, anda boleh mencuba hybla untuk kelewatan tinggi dan algoritma htcp untuk kelewatan sederhana, dsb. Jika anda ingin menetapkan algoritma kesesakan TCP kepada hybla net.ipv4.tcp_congestion_control=hyblaSelain itu, untuk versi kernel yang lebih tinggi daripada 3.7.1, kami boleh mendayakan tcp_fastopen: net.ipv4.tcp_fastopen= 3 Mekanisme pengedaran peristiwa
Untuk mendayakan sambungan TCP berkonkurensi tinggi di Linux, anda mesti mengesahkan sama ada aplikasi menggunakan teknologi rangkaian I/O dan mekanisme penghantaran peristiwa I/O yang sesuai. Teknologi I/O yang tersedia ialah I/O segerak, I/O segerak tidak menyekat dan I/O tak segerak. Dalam kes konkurensi TCP yang tinggi, jika I/O segerak digunakan, ini akan menyekat operasi program dengan serius melainkan utas dicipta untuk I/O bagi setiap sambungan TCP. Walau bagaimanapun, terlalu banyak benang akan menyebabkan overhed yang besar disebabkan oleh penjadualan benang sistem. Oleh itu, adalah tidak digalakkan untuk menggunakan I/O segerak dalam situasi konkurensi TCP tinggi Dalam kes ini, anda boleh mempertimbangkan untuk menggunakan I/O segerak tidak menyekat atau I/O tak segerak. Teknologi I/O segerak yang tidak menyekat termasuk penggunaan select(), poll(), epoll dan mekanisme lain. Teknologi I/O tak segerak ialah menggunakan AIO.
Dari perspektif mekanisme penghantaran acara I/O, adalah tidak sesuai untuk menggunakan select() kerana ia menyokong bilangan sambungan serentak yang terhad (biasanya dalam 1024). Jika anda menganggap prestasi, tinjauan pendapat() juga tidak sesuai Walaupun ia boleh menyokong bilangan mata wang TCP yang lebih tinggi, disebabkan oleh mekanisme "pungutan suara", apabila bilangan mata wang tinggi, kecekapan operasinya agak rendah, dan mungkin terdapat. Acara I/O diedarkan secara tidak sekata, menyebabkan I/O "kebuluran" pada beberapa sambungan TCP. Jika anda menggunakan epoll atau AIO, tiada masalah di atas (pelaksanaan awal teknologi AIO dalam kernel Linux telah dicapai dengan mencipta benang dalam kernel untuk setiap permintaan I/O. Mekanisme pelaksanaan ini sangat berkesan dalam kes high sambungan TCP serentak sebenarnya terdapat masalah prestasi yang serius dengan penggunaannya, tetapi dalam kernel Linux terkini, pelaksanaan AIO telah dipertingkatkan).
Ringkasnya, apabila membangunkan aplikasi Linux yang menyokong sambungan TCP serentak tinggi, anda harus cuba menggunakan teknologi epoll atau AIO untuk mencapai kawalan I/O pada sambungan TCP serentak Ini akan meningkatkan keupayaan program untuk mengendalikan sambungan TCP serentak tinggi menyediakan jaminan I/O yang cekap.
Selepas konfigurasi dioptimumkan sedemikian, keupayaan pemprosesan serentak TCP pelayan akan dipertingkatkan dengan ketara. Konfigurasi di atas adalah untuk rujukan sahaja Jika digunakan dalam persekitaran pengeluaran, sila amati dan laraskan mengikut situasi sebenar anda.