Rumah > Artikel > Operasi dan penyelenggaraan > Cara mengoptimumkan Nginx dan Node.js untuk rangkaian beban tinggi
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
nginxss -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:
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;
}
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 kaedah 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 nodKami 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 konteksApabila 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. Apabila bertukar, 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 bayar. perhatikan gambar di atas dan lihat sistem Bagaimana beban (garisan biru) turun 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.
Tanpa susunan tertentu:
1 Apabila masalah prestasi dihadapi, jika pengiraan dan pemprosesan boleh dilakukan pada lapisan aplikasi, kemudian ambilnya dari lapisan pangkalan data keluarlah. Pengisihan dan pengelompokan adalah contoh klasik. Ia sentiasa lebih mudah untuk meningkatkan prestasi pada lapisan aplikasi daripada pada lapisan pangkalan data. Sama seperti MySQL, sqlite lebih mudah dikawal. 2. Berkenaan pengkomputeran selari, cuba elakkan jika boleh. Jika ia tidak dapat dielakkan, ingatlah bahawa dengan kuasa yang besar datang tanggungjawab yang besar. Jika boleh, cuba elakkan manipulasi langsung benang. Beroperasi pada tahap abstraksi yang lebih tinggi apabila boleh. Contohnya, dalam iOS, GCD, operasi pengedaran dan baris gilir adalah rakan anda. Otak manusia tidak direka untuk menganalisis keadaan sementara yang tidak terhingga - saya belajar ini dengan cara yang sukar. 3. Permudahkan negeri ini seboleh-bolehnya dan lokalkan ia sebanyak mungkin. Kebolehgunaan diutamakan. 4. Kaedah ringkas dan boleh digabungkan adalah rakan anda. 5. Komen kod berbahaya kerana ia mudah ketinggalan zaman atau mengelirukan, tetapi ini bukan alasan untuk tidak menulis ulasan. Jangan mengulas perkara remeh, tetapi jika perlu, komen panjang secara strategik diperlukan di beberapa tempat istimewa. Ingatan anda akan mengkhianati anda, mungkin esok pagi, mungkin selepas secawan kopi. 6. Jika anda berpendapat senario kes penggunaan mungkin "okay", mungkin ini adalah tempat anda gagal teruk dalam produk keluaran anda sebulan kemudian. Jadilah seorang yang ragu-ragu, menguji, mengesahkan. 7 Apabila ragu-ragu, bercakap dengan semua orang dalam pasukan.8. Lakukan perkara yang betul – anda biasanya tahu maksudnya.
9. Pengguna anda tidak bodoh, mereka tidak mempunyai kesabaran untuk memahami jalan pintas anda.
10 Jika pembangun tidak ditugaskan untuk penyelenggaraan jangka panjang sistem yang anda bangunkan, berhati-hati dengannya. 80% daripada darah, peluh dan air mata ditumpahkan dalam masa selepas perisian dikeluarkan - maka anda akan menjadi orang yang tidak pandai, tetapi juga "ahli" yang lebih bijak.
11 Senarai tugasan ialah kawan baik anda.
12 Ambil inisiatif untuk menjadikan kerja anda lebih menyeronokkan, kadangkala ini memerlukan usaha anda.
13. Peristiwa senyap yang saya masih sedar daripada mimpi buruk. Pemantauan, pembalakan, amaran. Berhati-hati dengan pelbagai penggera palsu dan kebodohan deria yang tidak dapat dielakkan. Pastikan sistem anda berwaspada terhadap kegagalan dan tepat pada masanya.
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!