Rumah >Operasi dan penyelenggaraan >Nginx >Cara mengoptimumkan Nginx dan Node.js untuk rangkaian beban tinggi

Cara mengoptimumkan Nginx dan Node.js untuk rangkaian beban tinggi

PHPz
PHPzke hadapan
2023-05-17 15:13:141514semak imbas

Penalaan Rangkaian
Jika anda tidak memahami terlebih dahulu mekanisme penghantaran asas nginx dan node.js dan melakukan pengoptimuman disasarkan, tidak kira betapa terperinci pengoptimuman kedua-duanya, ia akan menjadi dengan sia-sia. Biasanya, nginx menghubungkan klien dan aplikasi huluan melalui soket tcp.
Sistem kami mempunyai banyak ambang dan sekatan untuk tcp, yang ditetapkan melalui parameter kernel. Nilai lalai parameter ini selalunya ditetapkan untuk tujuan umum dan tidak dapat memenuhi trafik tinggi dan keperluan hayat pendek pelayan web.
Berikut ialah beberapa parameter yang menjadi calon untuk penalaan tcp. Untuk menjadikannya berkesan, anda boleh meletakkannya dalam fail /etc/sysctl.conf, atau meletakkannya dalam fail konfigurasi baharu, seperti /etc/sysctl.d/99-tuning.conf, dan kemudian jalankan sysctl -p ke biarkan kernel memuatkan mereka. Kami menggunakan sysctl-cookbook untuk melakukan kerja fizikal ini.
Perlu diambil perhatian bahawa nilai yang disenaraikan di sini adalah selamat untuk digunakan, tetapi masih disyorkan agar anda mengkaji maksud setiap parameter untuk memilih nilai yang lebih sesuai berdasarkan beban, perkakasan dan penggunaan anda.

Salin kod Kod adalah seperti berikut:

.ipv4. ip_local_port_range='1024 65000'
net.ipv4.tcp_tw_reuse='1'
net.ipv4.tcp_fin_timeout='15'
net.core.netdev_max_backlog> core.rmem_max ='16777216'
net.core.somaxconn='4096'
net.core.wmem_max='16777216'
net.ipv4.tcp_max_syn_backlog='20480>netnet.ipv4.tcp_no_metrics_save='1'
net.ipv4.tcp_rmem='4096 87380 16777216'
net.ipv4.tcp_rmem='4096 87380 16777216'
net.ipv4.tcp_rmem='4096 87380 16777216'
net. 4. tcp_synack_ret ​​​​ries=' 2'
net.ipv4.tcp_wmem='4096 65536 16777216'
vm.min_free_kbytes='65536'
pada beberapa penting

net.ipv4.ip_local_port_rangeUntuk melayan klien hiliran untuk aplikasi huluan, nginx mesti membuka dua sambungan tcp, satu kepada klien dan satu kepada aplikasi. Apabila pelayan menerima banyak sambungan, port yang tersedia sistem akan cepat habis. Dengan mengubah suai parameter net.ipv4.ip_local_port_range, anda boleh meningkatkan julat port yang tersedia. Jika ralat sedemikian ditemui dalam /var/log/syslog: "kemungkinan syn banjir pada port 80. menghantar kuki", ini bermakna sistem tidak dapat mencari port yang tersedia. Meningkatkan parameter net.ipv4.ip_local_port_range boleh mengurangkan ralat ini. net.ipv4.tcp_tw_reuse
Apabila pelayan perlu bertukar antara sejumlah besar sambungan tcp, sejumlah besar sambungan dalam keadaan time_wait akan dijana. time_wait bermakna sambungan itu sendiri ditutup, tetapi sumbernya belum dikeluarkan. Menetapkan net_ipv4_tcp_tw_reuse kepada 1 membolehkan kernel cuba mengitar semula sambungan apabila ia selamat, yang jauh lebih murah daripada mewujudkan semula sambungan baharu.
net.ipv4.tcp_fin_timeout
Ini ialah masa minimum sambungan dalam keadaan time_wait mesti menunggu sebelum dikitar semula. Menjadikannya lebih kecil boleh mempercepatkan kitar semula.

Cara menyemak status sambungan

Gunakan netstat:netstat -tan | awk '{print $6}' | >ss -s
nginx
ss -s
jumlah: 388 (kernel 541)
tcp: 47461 (estab 311, ditutup 47135, yatim 4, synrecv 0, portswait 47), 33938
jumlah pengangkutan ip ipv6
* 541 - -
mentah 0 0 0
udp 13 10 3
tcp 326 325 1
inet 35 39 🎜>inet 35 39 🎜
Apabila beban pada pelayan web meningkat secara beransur-ansur, kita akan mula menghadapi beberapa batasan pelik nginx. Sambungan terputus dan kernel terus melaporkan banjir syn. Pada masa ini, purata beban dan penggunaan CPU adalah sangat kecil, dan pelayan jelas boleh mengendalikan lebih banyak sambungan, yang benar-benar mengecewakan.
Setelah disiasat, didapati terdapat banyak kaitan dalam keadaan time_wait. Ini adalah output daripada salah satu pelayan:
Terdapat 47135 sambungan masa_tunggu! Lebih-lebih lagi, ia dapat dilihat dari ss bahawa mereka semua adalah sambungan tertutup. Ini menunjukkan bahawa pelayan telah menggunakan kebanyakan port yang tersedia, dan juga membayangkan bahawa pelayan memperuntukkan port baharu untuk setiap sambungan. Penalaan rangkaian membantu sedikit masalah ini, tetapi masih tidak ada port yang mencukupi.
Selepas penyelidikan lanjut, saya menjumpai dokumen tentang arahan keepalive sambungan huluan, yang mengatakan:
Tetapkan bilangan maksimum sambungan keepalive terbiar ke pelayan huluan ini akan dikekalkan dalam cache proses pekerja. .
Menarik. Secara teorinya, persediaan ini meminimumkan sambungan terbuang dengan menghantar permintaan ke atas sambungan tembolok. Dokumentasi juga menyebut bahawa kita harus menetapkan proxy_http_version kepada "1.1" dan mengosongkan pengepala "sambungan". Selepas penyelidikan lanjut, saya mendapati bahawa ini adalah idea yang baik, kerana http/1.1 sangat mengoptimumkan penggunaan sambungan tcp berbanding dengan http1.0, dan nginx menggunakan http/1.0 secara lalai.
Selepas mengubah suai seperti yang dicadangkan dalam dokumen, fail konfigurasi pautan atas kami menjadi seperti ini:


Salin kod Kod adalah seperti berikut:

upstream backend_nodejs {
server nodejs-3:5016 max_fails=0 fail_timeout=10s;
server nodejs-4:5016 max_fails=0 fail_timeout=10s;
server nodejs-4:5016 max_fails=10s;
server max:_501s fail_timeout=10s;
server nodejs-6:5016 max_fails=0 fail_timeout=10s;
keepalive 512;

}


Saya turut mengubah suai tetapan proksi dalam bahagian pelayan seperti yang dicadangkan . Pada masa yang sama, proxy_next_upstream telah ditambahkan untuk melangkau pelayan yang gagal, keepalive_timeout pelanggan telah dilaraskan dan log akses telah dimatikan. Konfigurasi menjadi seperti ini:

Salin kod Kod adalah seperti berikut:


pelayan {
dengar 80;
server_name fast.gosquared.com;
client_max_body_size 16m;
keepalive_timeout 10;
lokasi / {
proxy_next_upstream error timeout http_500 http_502 http_503 http_504;
proxy_set_header connection "_">🎜 ://backend_nodejs;
}
access_log off;
error_log /dev/null crit;
}

Selepas menggunakan konfigurasi baharu, saya mendapati soket yang diduduki oleh pelayan telah dikurangkan sebanyak 90% . Permintaan kini boleh dihantar menggunakan sambungan yang jauh lebih sedikit. Output baharu adalah seperti berikut:

ss -s
jumlah: 558 (kernel 604)
tcp: 4675 (estab 485, ditutup 4183, yatim piatu 0, synrecv 0, timewait 4183/0), port 4183/0
jumlah pengangkutan ip ipv6
* 604 - -
mentah 0 0 0
udp 13 10 3
tcp 492 491 1
inet 505 501 4
node >dapat Terima kasih kepada reka bentuk dipacu acara yang mengendalikan I/O secara tak segerak, Node.js boleh mengendalikan sejumlah besar sambungan dan permintaan di luar kotak. Walaupun terdapat teknik penalaan lain, artikel ini akan menumpukan terutamanya pada aspek proses node.js.
Nod adalah satu-benang dan tidak akan menggunakan berbilang teras secara automatik. Dalam erti kata lain, aplikasi tidak boleh mendapatkan keupayaan penuh pelayan secara automatik.

Mencapai pengelompokan proses nod
Kami boleh mengubah suai aplikasi supaya ia memotong berbilang benang dan menerima data pada port yang sama, dengan itu membolehkan beban menjangkau berbilang teras. Node mempunyai modul kluster yang menyediakan semua alatan yang diperlukan untuk mencapai matlamat ini, tetapi menambahkannya pada aplikasi memerlukan banyak kerja manual. Jika anda menggunakan ekspres, eBay mempunyai modul yang dipanggil cluster2 yang boleh digunakan.
Halang penukaran konteks
Apabila menjalankan berbilang proses, anda harus memastikan setiap teras CPU hanya sibuk dengan satu proses pada satu masa. Secara umumnya, jika CPU mempunyai n teras, kita harus menjana proses aplikasi n-1. Ini memastikan bahawa setiap proses mendapat potongan masa yang munasabah, meninggalkan satu teras percuma untuk penjadual kernel menjalankan tugas lain. Kami juga perlu memastikan bahawa pada asasnya tiada tugas lain selain node.js dilaksanakan pada pelayan untuk mengelakkan perbalahan CPU. Kami pernah membuat kesilapan dan menggunakan dua aplikasi node.js pada pelayan, dan kemudian setiap aplikasi membuka proses n-1. Akibatnya, mereka bersaing untuk CPU antara satu sama lain, menyebabkan beban sistem meningkat dengan mendadak. Walaupun pelayan kami semuanya mesin 8 teras, prestasi overhed yang disebabkan oleh penukaran konteks masih dapat dirasai dengan jelas. Penukaran konteks merujuk kepada fenomena bahawa CPU menggantung tugas semasa untuk melaksanakan tugas lain. Pada suis, kernel mesti menggantung semua keadaan proses semasa dan kemudian memuatkan dan melaksanakan proses lain. Untuk menyelesaikan masalah ini, kami mengurangkan bilangan proses yang dimulakan oleh setiap aplikasi supaya mereka boleh berkongsi CPU secara adil Akibatnya, beban sistem telah dikurangkan:



Sila ambil perhatian gambar di atas, lihat bagaimana beban sistem (garisan biru) menurun di bawah bilangan teras CPU (garisan merah). Pada pelayan lain, kami melihat perkara yang sama. Memandangkan jumlah beban kerja kekal sama, peningkatan prestasi dalam graf di atas hanya boleh dikaitkan dengan pengurangan suis konteks. Cara mengoptimumkan Nginx dan Node.js untuk rangkaian beban tinggi

Atas ialah kandungan terperinci Cara mengoptimumkan Nginx dan Node.js untuk rangkaian beban tinggi. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Artikel ini dikembalikan pada:yisu.com. Jika ada pelanggaran, sila hubungi admin@php.cn Padam