Rumah  >  Artikel  >  Operasi dan penyelenggaraan  >  Apakah faktor yang mempengaruhi bilangan sambungan TCP dalam sistem Linux

Apakah faktor yang mempengaruhi bilangan sambungan TCP dalam sistem Linux

青灯夜游
青灯夜游asal
2022-11-07 18:47:382266semak imbas

Faktor utama yang mempengaruhi bilangan sambungan tcp dalam sistem Linux ialah memori dan bilangan deskriptor fail yang dibenarkan, kerana setiap sambungan tcp menduduki jumlah memori tertentu, dan setiap soket ialah deskriptor fail, dan yang lain 1024 Pelabuhan berikut biasanya adalah pelabuhan simpanan.

Apakah faktor yang mempengaruhi bilangan sambungan TCP dalam sistem Linux

Persekitaran pengendalian tutorial ini: sistem linux7.3, komputer Dell G3.

Dalam aplikasi tcp, pelayan mendengar pada port tetap terlebih dahulu, pelanggan secara aktif memulakan sambungan dan sambungan tcp diwujudkan selepas tiga jabat tangan. Jadi untuk satu mesin, apakah bilangan maksimum sambungan TCP serentak?

Bagaimana untuk mengenal pasti sambungan TCP

Sebelum menentukan bilangan maksimum sambungan, mari kita lihat dahulu cara sistem mengenal pasti tcp sambungan. Sistem menggunakan 4-tuple untuk mengenal pasti sambungan TCP secara unik: {localip, localport,remoteip,remoteport}.

Bilangan maksimum sambungan tcp untuk klien

Setiap kali klien memulakan permintaan sambungan tcp, melainkan port terikat, sistem akan biasanya memilih yang terbiar Port tempatan (port tempatan) adalah eksklusif dan tidak boleh dikongsi dengan sambungan TCP lain. Jenis data port TCP tidak ditandatangani pendek, jadi bilangan maksimum port tempatan hanya 65536. Port 0 mempunyai makna istimewa dan tidak boleh digunakan dengan cara ini, port yang tersedia hanya 65535 sahaja digunakan sebagai pelanggan, bilangan maksimum sambungan TCP untuk pelanggan ialah 65535, sambungan ini boleh disambungkan ke serverip yang berbeza.

Bilangan maksimum sambungan tcp ke pelayan

Pelayan biasanya ditetapkan untuk mendengar pada port tempatan, menunggu permintaan sambungan pelanggan . Tanpa mengambil kira penggunaan semula alamat (pilihan SO_REUSEADDR Unix), walaupun terdapat berbilang IP pada bahagian pelayan, port pendengaran tempatan adalah eksklusif Oleh itu, hanya terdapat remoteip (iaitu, klien) dan port jauh (klien) dalam 4-tuple sambungan tcp bahagian pelayan) adalah berubah-ubah, jadi sambungan TCP maksimum ialah bilangan IP pelanggan × bilangan port klien Untuk IPV4, tanpa mengira faktor seperti klasifikasi alamat IP, bilangan maksimum Sambungan TCP adalah kira-kira 2 hingga kuasa ke-32 (bilangan IP) × 2 hingga kuasa ke-16 (bilangan port), iaitu, bilangan maksimum sambungan TCP pada mesin tunggal pada bahagian pelayan adalah lebih kurang 2 hingga kuasa ke-48 .

Bilangan sebenar sambungan tcp

Di atas ialah bilangan maksimum sambungan untuk satu mesin dalam persekitaran sebenar dipengaruhi oleh sumber mesin, sistem pengendalian, dsb., terutamanya pada bahagian pelayan, bilangan maksimum sambungan TCP serentak jauh daripada mencapai had atas teori. Faktor utama yang mengehadkan bilangan sambungan di bawah Unix/Linux ialah memori dan bilangan deskriptor fail yang dibenarkan (setiap sambungan TCP menduduki jumlah memori tertentu, dan setiap soket ialah deskriptor fail Selain itu, port di bawah 1024 biasanya). pelabuhan terpelihara. Di bawah konfigurasi kernel 2.6 lalai, selepas ujian, setiap soket menduduki antara 15 dan 20k memori.

Jadi, pada bahagian pelayan, dengan meningkatkan memori dan mengubah suai parameter seperti bilangan maksimum deskriptor fail, tidak ada masalah untuk bilangan maksimum sambungan TCP serentak pada satu mesin melebihi 100,000, atau bahkan berjuta-juta.

Ini jelas merupakan salah faham 65535 merujuk kepada jumlah port yang tersedia, yang tidak bermakna pelayan hanya boleh menerima 65535 sambungan serentak pada masa yang sama.

Contohnya:

Kami membuat tapak web dan mengikatnya ke port TCP 80. Hasilnya ialah semua pengguna yang melawati tapak web ini mengakses port 80 pelayan , bukannya pelabuhan lain. Port yang boleh dilihat boleh digunakan semula. Walaupun pelayan Linux hanya mendengar perkhidmatan pada port 80, ia membenarkan 100,000 atau 1 juta pengguna menyambung ke pelayan. Sistem Linux tidak mengehadkan bilangan sambungan Sama ada pelayan boleh menahan begitu banyak sambungan bergantung pada konfigurasi perkakasan pelayan, seni bina perisian dan pengoptimuman.

01

Kami tahu bahawa premis paling asas untuk dua proses berkomunikasi ialah dapat mengenal pasti proses secara unik. Dalam komunikasi proses tempatan, kita boleh menggunakan PID untuk mengenal pasti proses secara unik, tetapi PID hanya unik secara tempatan, dan kebarangkalian konflik PID antara dua proses dalam rangkaian adalah sangat tinggi.

Pada masa ini, anda perlu mencari cara lain Alamat IP boleh mengenal pasti hos secara unik, dan protokol lapisan TCP dan nombor port boleh mengenal pasti proses hos dengan cara ini, alamat IP + protokol + nombor port boleh digunakan untuk mengenal pasti secara unik proses A dalam rangkaian.

Selepas dapat mengenal pasti proses pada rangkaian secara unik, mereka boleh berkomunikasi menggunakan soket. Soket ialah lapisan abstraksi antara lapisan aplikasi dan lapisan pengangkutan Ia mengabstrakkan operasi kompleks lapisan TCP/IP ke dalam beberapa antara muka mudah untuk lapisan aplikasi memanggil dan melaksanakan proses untuk berkomunikasi dalam rangkaian.

Soket berasal daripada Unix dan merupakan pelaksanaan mod "buka-baca/tulis-tutup" Pelayan dan pelanggan masing-masing mengekalkan satu ". Fail", selepas mewujudkan sambungan dan membukanya, anda boleh menulis kandungan pada fail anda sendiri untuk pihak yang satu lagi membaca atau membaca kandungan pihak yang satu lagi dan menutup fail tersebut apabila komunikasi tamat.

02

Satu-satunya perkara yang boleh menentukan sambungan ialah 4 perkara:

1

2. Port Pelayan

3. IP Pelanggan

4. Port Pelanggan

IP dan Port pelayan boleh kekal tidak berubah, selagi IP dan Port pelanggan. adalah berbeza antara satu sama lain untuk menentukan nombor sambungan.

Soket boleh mewujudkan berbilang sambungan Sambungan TCP ditandakan sebagai empat tuple (source_ip, source_port, destination_ip, destination_port), iaitu, (sumber IP, Source. port, IP destinasi, port destinasi) ialah gabungan empat elemen. Selagi satu elemen dalam gabungan empat elemen berbeza, sambungan yang berbeza boleh dibezakan.

Contohnya:

-> Alamat IP hos anda ialah 1.1.1.1, dengar pada port 8080

->Apabila mesej datang daripada 2.2.2.2 Sambungan permintaan, port 5555. Empat tuple sambungan ini ialah (1.1.1.1, 8080, 2.2.2.2, 5555)

-> Pada masa ini, 2.2.2.2 menghantar permintaan sambungan kedua dengan port 6666. Empat tuple sambungan baharu ialah (1.1.1.1, 8080, 2.2.2.2, 6666)

Kemudian, port 8080 hos anda telah mewujudkan dua sambungan

-> Permintaan sambungan ketiga dihantar daripada (2.2.2.2), port ialah 5555 (atau 6666). Permintaan untuk sambungan ketiga tidak dapat diwujudkan kerana tidak ada cara untuk membezakannya daripada dua sambungan di atas.

Begitu juga, Anda boleh mengikat soket TCP dan soket UDP pada nombor port dan alamat IP yang sama

Oleh kerana nombor port adalah sama, tetapi protokolnya adalah berbeza Sama, jadi pelabuhan adalah bebas sepenuhnya.

TCP/UDP biasanya menggunakan lima tuple untuk mencari sambungan:

source_ip, source_port, destination_ip, destination_port, protocol_type

iaitu (sumber IP , port sumber, IP destinasi, port destinasi, nombor protokol)

Ringkasnya, bilangan pelayan serentak tidak ditentukan oleh port 65535 TCP. Bilangan mata wang yang boleh ditahan oleh pelayan pada masa yang sama ditentukan oleh banyak faktor seperti lebar jalur, perkakasan dan reka bentuk program.

Jadi, kita dapat memahami sebab Taobao, Tencent, Toutiao, Baidu, Sina, BeepBeep, dll. boleh menahan ratusan juta akses serentak sesaat kerana mereka menggunakan kluster pelayan. Kelompok pelayan diedarkan dalam bilik komputer yang besar di seluruh negara Apabila bilangan lawatan adalah kecil, beberapa pelayan akan ditutup, dan apabila bilangan lawatan adalah tinggi, pelayan baharu akan dibuka secara berterusan.

Akal budi 1: Sekatan pemegang fail

Rakan yang menulis atur cara pelayan rangkaian di bawah Linux mesti tahu bahawa setiap sambungan tcp menduduki deskriptor fail Setelah ini Deskriptor fail mempunyai telah digunakan, dan ralat dikembalikan kepada kami apabila sambungan baharu tiba ialah "Soket/Fail: Tidak dapat membuka begitu banyak fail" .

Pada masa ini anda perlu memahami batasan sistem pengendalian pada bilangan maksimum fail yang boleh dibuka.

  • Had Proses

    • Melaksanakan ulimit -n output 1024, menunjukkan bahawa proses hanya boleh membuka sehingga 1024 fail, jadi anda perlu Dengan konfigurasi lalai ini, sehingga beribu-ribu sambungan TCP serentak boleh dibuat.

    • Pengubahsuaian sementara: ulimit -n 1000000, tetapi pengubahsuaian sementara ini hanya sah untuk persekitaran penggunaan semasa pengguna yang sedang log masuk, dan akan menjadi tidak sah selepas sistem dimulakan semula atau pengguna log keluar.

    • Pengubahsuaian yang menjadi tidak sah selepas dimulakan semula (tetapi saya telah menguji di bawah CentOS 6.5 dan mendapati tiada ketidaksahihan selepas dimulakan semula): Edit fail /etc/security/limits.conf dan kandungan yang diubah suai ialah

      * soft nofile 1000000

      * hard nofile 1000000

    • Pengubahsuaian kekal: edit /etc/rc.local dan tambah kandungan berikut selepasnya

      ulimit -SHn 1000000

  • Had global

    • Laksanakan kucing /proc/sys/fs/file- nr output 9344 0 592026, masing-masing: 1. Bilangan pemegang fail yang telah diperuntukkan, 2. Bilangan pemegang fail yang telah diperuntukkan tetapi tidak digunakan, 3. Bilangan maksimum pemegang fail. Tetapi dalam versi kernel 2.6, nilai item kedua sentiasa 0. Ini bukan ralat Ini sebenarnya bermakna semua deskriptor fail yang diperuntukkan telah digunakan.

    • Kami boleh menukar nilai ini kepada nilai yang lebih besar dan mengubah suai fail /etc/sysctl.conf dengan kebenaran root:

      fs.file-max = 1000000

      net.ipv4.ip_conntrack_max = 1000000

      net.ipv4.netfilter.ip_conntrack_max = 1000000

Akal budi 2: Sekatan julat nombor port?

Nombor port di bawah 1024 pada sistem pengendalian dikhaskan oleh sistem dan 1024-65535 digunakan oleh pengguna. Oleh kerana setiap sambungan TCP menduduki nombor port, kami boleh mempunyai sehingga lebih daripada 60,000 sambungan serentak. Rasanya tak ramai kawan yang salah idea ni kan? (Saya selalu berfikir begitu pada masa lalu)

Mari kita menganalisisnya

  • Cara untuk mengenal pasti sambungan TCP: Sistem menggunakan 4-tuple untuk mengenal pasti sambungan TCP secara unik: {local ip, local port, remote ip, remote port}. Baiklah, mari kita ambil penjelasan terima dalam Bab 4 "Pengaturcaraan Rangkaian UNIX: Jilid 1" dan lihat perkara konseptual Parameter kedua cliaddr mewakili alamat ip dan nombor port pelanggan. Sebagai pelayan, kami sebenarnya hanya menggunakan port semasa bind, yang menunjukkan bahawa nombor port 65535 bukanlah had pada jumlah concurrency.

  • Bilangan maksimum sambungan tcp ke pelayan: Pelayan biasanya ditetapkan untuk mendengar pada port tempatan, menunggu permintaan sambungan pelanggan. Tanpa mengambil kira penggunaan semula alamat (pilihan SO_REUSEADDR Unix), walaupun terdapat berbilang IP di bahagian pelayan, port pendengaran tempatan adalah eksklusif, jadi sambungan tcp 4-tuple sebelah pelayan hanya mempunyai ip jauh (iaitu, ip klien) dan port jauh. (Port klien) adalah berubah-ubah, jadi sambungan TCP maksimum ialah bilangan IP klien × bilangan port klien Untuk IPV4, tanpa mengira faktor seperti klasifikasi alamat IP, bilangan maksimum sambungan TCP adalah lebih kurang 2. kepada kuasa ke-32 (bilangan IP) )×2 kepada kuasa ke-16 (bilangan port), iaitu, bilangan maksimum sambungan TCP pada mesin tunggal pada bahagian pelayan adalah lebih kurang 2 hingga kuasa ke-48.

Tetapan biasa

1. Ubah suai had bilangan fail yang boleh dibuka oleh proses pengguna

dalam Linux Pada platform, sama ada anda menulis program klien atau program pelayan, apabila memproses sambungan TCP konkurensi tinggi, bilangan mata wang tertinggi tertakluk kepada had sistem pada bilangan fail yang boleh dibuka oleh pengguna pada masa yang sama dalam satu proses (ini kerana sistem menyediakan Pemegang soket mesti dibuat untuk setiap sambungan, dan setiap pemegang soket juga merupakan pemegang fail). Anda boleh menggunakan arahan ulimit untuk melihat had bilangan fail yang sistem membenarkan proses pengguna semasa dibuka:

[speng@as4 ~]$ ulimit -n
1024

Ini bermakna setiap proses pengguna semasa dibenarkan untuk dibuka sehingga 1024 fail pada masa yang sama Di antara 1024 fail ini, setiap proses mesti dikecualikan daripada input standard, output standard, soket mendengar pelayan, soket domain Unix untuk komunikasi antara proses dan fail lain fail yang tinggal yang boleh digunakan untuk sambungan soket klien hanya kira-kira 1024-10=1014. Maksudnya, secara lalai, program komunikasi berasaskan Linux membenarkan sehingga 1014 sambungan TCP serentak pada masa yang sama.
Untuk pengendali komunikasi yang ingin menyokong bilangan sambungan TCP serentak yang lebih tinggi, anda mesti mengubah suai had lembut dan had keras (had keras) Linux pada bilangan fail yang dibuka serentak oleh proses pengguna semasa. Had lembut bermakna Linux mengehadkan lagi bilangan fail yang boleh dibuka oleh pengguna pada masa yang sama dalam julat yang boleh ditanggung oleh sistem semasa, had keras ialah bilangan maksimum fail yang boleh dibuka oleh sistem pada masa yang sama dikira berdasarkan sumber perkakasan sistem (terutamanya memori sistem). Biasanya had lembut adalah kurang daripada atau sama dengan had keras.
Cara paling mudah untuk mengubah suai sekatan di atas adalah dengan menggunakan perintah ulimit:

[speng@as4 ~]$ ulimit -n

Dalam arahan di atas, nyatakan bilangan maksimum fail yang dibenarkan untuk dibuka dengan satu proses untuk ditetapkan. Jika sistem menggemakan sesuatu seperti "Operation notpermitted", ini bermakna pengubahsuaian had di atas gagal Sebenarnya, ia adalah kerana nilai yang dinyatakan dalam melebihi had lembut atau had keras sistem Linux pada bilangan fail yang dibuka oleh pengguna. Oleh itu, adalah perlu untuk mengubah suai had lembut dan keras sistem Linux pada bilangan fail terbuka untuk pengguna.

Langkah pertama ialah mengubah suai fail /etc/security/limits.conf dan menambah baris berikut pada fail:

...
# End of file
speng soft nofile 10240
speng hard nofile 10240
root soft nofile 65535
root hard nofile 65535
* soft nofile 65535
* hard nofile 65535
[test@iZwz9e1dh1nweaex8ob5b7Z config]$

di mana speng menentukan yang mana satu untuk mengubah suai Untuk had pengguna pada bilangan fail yang dibuka, anda boleh menggunakan tanda '*' untuk menunjukkan mengubah suai had untuk semua pengguna lembut atau keras menentukan sama ada untuk mengubah suai had lembut atau had keras 10240; nilai had yang ingin anda ubah suai, iaitu 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:

session required /lib/security/pam_limits.so

Ini memberitahu Linux apabila pengguna melengkapkan Selepas log masuk ke sistem, modul pam_limits.so perlu dipanggil untuk menetapkan had maksimum sistem pada bilangan pelbagai sumber yang boleh digunakan oleh pengguna (termasuk had bilangan maksimum fail yang boleh dibuka oleh pengguna. ), dan modul pam_limits.so akan memuat turun fail daripada /etc/security Konfigurasi dibaca daripada fail /limits.conf untuk menetapkan nilai had ini. Simpan fail ini selepas pengubahsuaian.

Langkah ketiga ialah menyemak bilangan maksimum fail terbuka pada peringkat sistem Linux Gunakan arahan berikut:

[speng@as4 ~]$ cat /proc/sys/fs/file-max
12158

Ini menunjukkan bahawa sistem Linux ini membenarkan bilangan maksimum fail dibuka pada masa yang sama (Iaitu, termasuk jumlah bilangan fail terbuka untuk semua pengguna) 12,158 fail adalah had keras peringkat sistem Linux Semua had fail terbuka peringkat pengguna tidak sepatutnya melebihi nilai ini. Biasanya had keras peringkat sistem ini ialah bilangan maksimum maksimum fail yang dibuka pada masa yang sama yang dikira berdasarkan sumber perkakasan sistem apabila sistem Linux dimulakan Jika tiada keperluan khas, had ini tidak boleh diubah melainkan anda mahu mengehadkan bilangan fail yang dibuka pada peringkat pengguna Tetapkan nilai yang melebihi had ini. Cara untuk mengubah suai had keras ini ialah dengan mengubah suai skrip /etc/rc.local dan menambah baris berikut dalam skrip:

echo 22158 > /proc/sys/fs/file-max

Ini membolehkan Linux menetapkan had keras peringkat sistem secara paksa pada bilangan fail terbuka selepas permulaan selesai kepada 22158. Simpan fail ini selepas pengubahsuaian.

完成上述步骤后重启系统,一般情况下就可以将Linux系统对指定用户的单一进程允许同时打开的最大文件数限制设为指定的数值。如果重启后用 ulimit-n命令查看用户可打开文件数限制仍然低于上述步骤中设置的最大值,这可能是因为在用户登录脚本/etc/profile中使用ulimit -n命令已经将用户可同时打开的文件数做了限制。由于通过ulimit-n修改系统对用户可同时打开文件的最大数限制时,新修改的值只能小于或等于上次 ulimit-n设置的值,因此想用此命令增大这个限制值是不可能的。所以,如果有上述问题存在,就只能去打开/etc/profile脚本文件,在文件中查找是否使用了ulimit-n限制了用户可同时打开的最大文件数量,如果找到,则删除这行命令,或者将其设置的值改为合适的值,然后保存文件,用户退出并重新登录系统即可。

通过上述步骤,就为支持高并发TCP连接处理的通讯处理程序解除关于打开文件数量方面的系统限制。

2、修改网络内核对TCP连接的有关限制(参考对比下篇文章“优化内核参数”)

在Linux上编写支持高并发TCP连接的客户端通讯处理程序时,有时会发现尽管已经解除了系统对用户同时打开文件数的限制,但仍会出现并发TCP连接数增加到一定数量时,再也无法成功建立新的TCP连接的现象。出现这种现在的原因有多种。

第一种原因可能是因为Linux网络内核对本地端口号范围有限制。此时,进一步分析为什么无法建立TCP连接,会发现问题出在connect()调用返回失败,查看系统错误提示消息是“Can’t assign requestedaddress”。同时,如果在此时用tcpdump工具监视网络,会发现根本没有TCP连接时客户端发SYN包的网络流量。这些情况说明问题在于本地Linux系统内核中有限制。其实,问题的根本原因在于Linux内核的TCP/IP协议实现模块对系统中所有的客户端TCP连接对应的本地端口号的范围进行了限制(例如,内核限制本地端口号的范围为1024~32768之间)。当系统中某一时刻同时存在太多的TCP客户端连接时,由于每个TCP客户端连接都要占用一个唯一的本地端口号(此端口号在系统的本地端口号范围限制中),如果现有的TCP客户端连接已将所有的本地端口号占满,则此时就无法为新的TCP客户端连接分配一个本地端口号了,因此系统会在这种情况下在connect()调用中返回失败,并将错误提示消息设为“Can’t assignrequested address”。有关这些控制逻辑可以查看Linux内核源代码,以linux2.6内核为例,可以查看tcp_ipv4.c文件中如下函数:

static int tcp_v4_hash_connect(struct sock *sk)

请注意上述函数中对变量sysctl_local_port_range的访问控制。变量sysctl_local_port_range的初始化则是在tcp.c文件中的如下函数中设置:

void __init tcp_init(void)

内核编译时默认设置的本地端口号范围可能太小,因此需要修改此本地端口范围限制。

第一步,修改/etc/sysctl.conf文件,在文件中添加如下行:

net.ipv4.ip_local_port_range = 1024 65000

这表明将系统对本地端口范围限制设置为1024~65000之间。请注意,本地端口范围的最小值必须大于或等于1024;而端口范围的最大值则应小于或等于65535。修改完后保存此文件。

第二步,执行sysctl命令:

[speng@as4 ~]$ sysctl -p

如果系统没有错误提示,就表明新的本地端口范围设置成功。如果按上述端口范围进行设置,则理论上单独一个进程最多可以同时建立60000多个TCP客户端连接。

第二种无法建立TCP连接的原因可能是因为Linux网络内核的IP_TABLE防火墙对最大跟踪的TCP连接数有限制。此时程序会表现为在 connect()调用中阻塞,如同死机,如果用tcpdump工具监视网络,也会发现根本没有TCP连接时客户端发SYN包的网络流量。由于 IP_TABLE防火墙在内核中会对每个TCP连接的状态进行跟踪,跟踪信息将会放在位于内核内存中的conntrackdatabase中,这个数据库的大小有限,当系统中存在过多的TCP连接时,数据库容量不足,IP_TABLE无法为新的TCP连接建立跟踪信息,于是表现为在connect()调用中阻塞。此时就必须修改内核对最大跟踪的TCP连接数的限制,方法同修改内核对本地端口号范围的限制是类似的:
第一步,修改/etc/sysctl.conf文件,在文件中添加如下行:

net.ipv4.ip_conntrack_max = 10240

这表明将系统对最大跟踪的TCP连接数限制设置为10240。请注意,此限制值要尽量小,以节省对内核内存的占用。

第二步,执行sysctl命令:

[speng@as4 ~]$ sysctl -p

如果系统没有错误提示,就表明系统对新的最大跟踪的TCP连接数限制修改成功。如果按上述参数进行设置,则理论上单独一个进程最多可以同时建立10000多个TCP客户端连接。

3、使用支持高并发网络I/O的编程技术

在Linux上编写高并发TCP连接应用程序时,必须使用合适的网络I/O技术和I/O事件分派机制。
可用的I/O技术有同步I/O,非阻塞式同步I/O(也称反应式I/O),以及异步I/O。《BIO,NIO,AIO的理解》

在高TCP并发的情形下,如果使用同步I/O,这会严重阻塞程序的运转,除非为每个TCP连接的I/O创建一个线程。但是,过多的线程又会因系统对线程的调度造成巨大开销。因此,在高TCP并发的情形下使用同步 I/O是不可取的,这时可以考虑使用非阻塞式同步I/O或异步I/O。非阻塞式同步I/O的技术包括使用select(),poll(),epoll等机制。异步I/O的技术就是使用AIO。
从I/O事件分派机制来看,使用select()是不合适的,因为它所支持的并发连接数有限(通常在1024个以内)。如果考虑性能,poll()也是不合适的,尽管它可以支持的较高的TCP并发数,但是由于其采用“轮询”机制,当并发数较高时,其运行效率相当低,并可能存在I/O事件分派不均,导致部分TCP连接上的I/O出现“饥饿”现象。而如果使用epoll或AIO,则没有上述问题(早期Linux内核的AIO技术实现是通过在内核中为每个 I/O请求创建一个线程来实现的,这种实现机制在高并发TCP连接的情形下使用其实也有严重的性能问题。但在最新的Linux内核中,AIO的实现已经得到改进)。
综上所述,在开发支持高并发TCP连接的Linux应用程序时,应尽量使用epoll或AIO技术来实现并发的TCP连接上的I/O控制,这将为提升程序对高并发TCP连接的支持提供有效的I/O保证。

内核参数sysctl.conf的优化

/etc/sysctl.conf 是用来控制linux网络的配置文件,对于依赖网络的程序(如web服务器和cache服务器)非常重要,RHEL默认提供的最好调整。

推荐配置(把原/etc/sysctl.conf内容清掉,把下面内容复制进去):

net.ipv4.ip_local_port_range = 1024 65536
net.core.rmem_max=16777216
net.core.wmem_max=16777216
net.ipv4.tcp_rmem=4096 87380 16777216
net.ipv4.tcp_wmem=4096 65536 16777216
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
net.core.netdev_max_backlog = 30000
net.ipv4.tcp_no_metrics_save=1
net.core.somaxconn = 262144
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

这个配置参考于cache服务器varnish的推荐配置和SunOne 服务器系统优化的推荐配置。

varnish调优推荐配置的地址为:http://varnish.projects.linpro.no/wiki/Performance

不过varnish推荐的配置是有问题的,实际运行表明“net.ipv4.tcp_fin_timeout = 3”的配置会导致页面经常打不开;并且当网友使用的是IE6浏览器时,访问网站一段时间后,所有网页都会打不开,重启浏览器后正常。可能是国外的网速快吧,我们国情决定需要调整“net.ipv4.tcp_fin_timeout = 10”,在10s的情况下,一切正常(实际运行结论)。

修改完毕后,执行:

/sbin/sysctl -p /etc/sysctl.conf
/sbin/sysctl -w net.ipv4.route.flush=1

命令生效。为了保险起见,也可以reboot系统。

调整文件数:

linux系统优化完网络必须调高系统允许打开的文件数才能支持大的并发,默认1024是远远不够的。

执行命令:

echo ulimit -HSn 65536 >> /etc/rc.local
echo ulimit -HSn 65536 >>/root/.bash_profile
ulimit -HSn 65536

备注:

对mysql用户可同时打开文件数设置为10240个;
将Linux系统可同时打开文件数设置为1000000个(一定要大于对用户的同时打开文件数限制);
将Linux系统对最大追踪的TCP连接数限制为20000个(但是,建议设置为10240;因为对mysql用户的同时打开文件数已经限制在10240个;且较小的值可以节省内存);
将linux系统端口范围配置为1024~30000(可以支持60000个以上连接,不建议修改;默认已经支持20000个以上连接);

综合上述四点,TCP连接数限制在10140个。
这10240个文件中还得除去每个进程必然打开的标准输入,标准输出,标准错误,服务器监听 socket,进程间通讯的unix域socket等文件。

因此,当需要对TCP连接数进行调整时只需要调整ulimit参数。

Linux下查看tcp连接数及状态命令:

netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'

相关推荐:《Linux视频教程

Atas ialah kandungan terperinci Apakah faktor yang mempengaruhi bilangan sambungan TCP dalam sistem Linux. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn