Apakah Node.js selalu lebih lambat dari Golang?

Ada perasaan bahwa setiap minggu ada "kerangka kerja web" baru untuk Node.js, yang disebut sesuatu yang bekerja lebih cepat daripada semua yang datang sebelumnya. Semua orang tahu bahwa Express lambat, tetapi apakah kerangka kerja berikutnya mampu benar-benar meningkatkan kinerja subsistem I / O Node.js? Satu-satunya hal yang dapat dilakukan adalah menghilangkan beban berlebih pada sistem yang dibuat oleh Express. Tidak ada pembicaraan tentang meningkatkan sesuatu yang mendasar. Bahkan, untuk memperbaiki situasi secara radikal, Anda harus bekerja di level yang lebih dalam, dan tidak menambahkan abstraksi baru di atas Node.js.

gambar

Apa yang diperlukan untuk membuat aplikasi server pada platform Node.js yang berjalan jauh lebih cepat dari semua yang ada saat ini?

Analisis situasi


Express adalah salah satu kerangka kerja web tertua untuk Node.js. Ini didasarkan pada kemampuan standar platform ini, memberikan pengembang antarmuka yang nyaman dibangun di sekitar konsep aplikasi, dan memungkinkan Anda untuk mengelola rute URL, parameter, metode, dan sejenisnya.

Ekspres sederhana, ini membantu programmer cepat mengembangkan aplikasi. Satu-satunya hal yang kurang adalah kinerja. Proyek yang terus muncul, seperti Fastify, berusaha memberi pengembang kemampuan yang sama dengan Express, tetapi dengan lebih sedikit kehilangan kinerja. Tapi mereka sendiri yang membuat beban tambahan pada sistem dan sangat mempengaruhi kinerja. Mereka sangat dibatasi oleh apa yang dapat disediakan platform Node.js. Dan itu bisa memberi, dibandingkan dengan pesaing, tidak terlalu banyak.


Jumlah permintaan HTTP yang diproses oleh berbagai server per detik

Perhatikan garis merah. Ini adalah platform maksimum Node.js. Baginya, terlepas dari apakah nama mereka mengandung kata "cepat" atau tidak, mereka tidak dapat melewati batas ini. Ini sebenarnya adalah batas kinerja yang sangat rendah ketika membandingkan platform Node.js dengan alternatif populernya seperti Golang.

Untungnya, Node.js mendukung pengaya C ++, pengikat Google V8 yang memungkinkan Anda untuk mengikat JavaScript dan C ++, dan memungkinkan Anda untuk memanggil mekanisme apa pun dari JavaScript, bahkan jika mekanisme ini disediakan oleh sesuatu selain platform Node.js.

Ini memungkinkan untuk memperluas dan meningkatkan kemampuan aplikasi JavaScript, memungkinkan Anda untuk mencapai tingkat kinerja baru. Ini memungkinkan program-program JavaScript untuk memeras segala yang mungkin dari mesin Google V8, tidak terbatas pada apa yang ditemukan oleh para pengembang Node.js cukup memadai.

Tentang μWebSockets.js


Awal bulan ini, saya merilis proyek baru - μWebSockets.js . GitHub digunakan sebagai hosting untuk kodenya, bukan npm, tetapi Anda dapat menginstalnya untuk Node.js menggunakan npm seperti ini:

npm install uNetworking/uWebSockets.js#v15.0.0 

Untuk bekerja dengan µWebSockets.js, Anda tidak memerlukan kompiler. Linux, macOS dan Windows didukung. Versi awal sistem adalah 15.0.0, penomoran versi dilakukan sesuai dengan aturan semantic versioning.

μWebSockets.js adalah server web alternatif untuk aplikasi backend yang ditulis dalam JS. Ini terdiri dari sekitar 6 ribu baris kode C dan C ++ dan secara signifikan mengungguli solusi terbaik yang ditulis dalam Golang. Jadi, pertukaran bitfinex.com telah mem-porting kedua API perdagangannya (REST dan WebSocket) ke μWebSockets.js dan secara bertahap memperkenalkannya ke dalam produksi. Paolo Ardoino dari Bitfinex mencatat bahwa ini adalah proyek yang hebat. Saya ingin mengatakan bahwa fakta bahwa saya memiliki kesempatan untuk merilis μWebSockets.js sepenuhnya karena dukungan yang diberikan kepada saya oleh BitMEX, Bitfinex dan Coinbase.

Fitur μWebSockets.js


μWebSockets.js adalah proyek baru yang dirilis di bawah lisensi Apache 2.0, yang merupakan kelanjutan dari apa yang dikenal sebagai "uws". Proyek ini adalah tumpukan lengkap untuk Google V8, mulai dari level kernel sistem operasi, sepenuhnya menggantikan fitur standar Node.js dan mewakili subsistem I / O yang stabil, aman, memenuhi standar, cepat dan ringan untuk Node.js. Inilah yang tampak seperti interaksi aplikasi JS dengan sistem operasi menggunakan μWebSockets.js.


Interaksi JS-aplikasi dengan OS menggunakan µWebSockets.js

Seperti yang Anda lihat, proyek ini terdiri dari beberapa lapisan. Setiap lapisan hanya bergantung pada lapisan sebelumnya. Arsitektur ini menyederhanakan identifikasi dan koreksi kesalahan, serta implementasi pekerjaan untuk memperluas solusi karena penerapan fitur-fitur baru di dalamnya.

Perlu dicatat bahwa lapisan µSockets sendiri terdiri dari tiga sublayers, yang merupakan mekanisme untuk bekerja dengan peristiwa dan dengan jaringan, serta alat untuk melindungi data. Hal ini memungkinkan, jika perlu, untuk mengganti bagian-bagian dari solusi, menambahkan implementasi alternatif dari fitur-fitur tertentu ke sistem, tanpa memenuhi kebutuhan untuk mengubah kode pada level yang lebih tinggi.

Sebagai contoh, jika Anda perlu mengganti OpenSSL dengan sesuatu, ubah saja file ssl.c dengan enam ratus baris kode menjadi apa yang Anda butuhkan. Namun, lapisan lain dari sistem bahkan tidak tahu apa itu SSL. Pendekatan ini, selain kenyamanan mengganti beberapa bagian sistem dengan yang lain, juga mengarah pada penyederhanaan proses deteksi kesalahan.


ΜMemasang sublapis bagian dalam

Arsitektur yang disajikan di sini sangat berbeda dari yang monolitik yang digunakan di Node.js, di mana dalam file kode sumber yang sama Anda dapat menemukan panggilan ke libuv, perintah untuk bekerja dengan sistem, dan panggilan ke OpenSSL dan V8. Dalam Node.js semua ini tercampur, tidak ada yang berangkat untuk mengisolasi masing-masing bagian dari platform ini. Ini sangat menyulitkan proses membuat perubahan besar pada Node.js.

Tentang pengembangan untuk μWebSockets.js


Berikut adalah contoh yang sangat disederhanakan dan disingkat dari bekerja dengan μWebSockets.js, yang tugas utamanya adalah menunjukkan kemampuan dasar sistem.

 /* SSL-   */ uWS.SSLApp({   key_file_name: 'misc/key.pem',   cert_file_name: 'misc/cert.pem',   passphrase: '1234' }).get('/hello', (res, req) => {   /*    */   res.end('Hello World!'); }).ws('/*', {   open: (ws, req) => {       console.log('A WebSocket connected via URL: ' + req.getUrl() + '!');   },   message: (ws, message, isBinary) => {       /* OK   false          *     */       let ok = ws.send(message, isBinary);   },   drain: (ws) => {       console.log('WebSocket backpressure: ' + ws.getBufferedAmount());   },   close: (ws, code, message) => {       console.log('WebSocket closed');   } }).listen(port, (token) => {   if (token) {       console.log('Listening to port ' + port);   } }); 

Dalam arti tertentu, kita dapat mengatakan bahwa µWebSockets.js menggunakan SSL dapat mem-bypass Gorilla WebSocket, sebuah implementasi dari protokol WebSocket on Go, tanpa SSL. Artinya, ternyata kode JS dapat bertukar pesan menggunakan SSL lebih cepat daripada, dalam kondisi tertentu, kode yang ditulis dalam Go tanpa SSL. Saya percaya bahwa ini adalah hasil yang sangat baik.

Implementasi Protokol WebSocket Cepat


Socket.IO, dalam banyak hal, dapat dianggap setara dengan Express secara real time. Kedua proyek ini muncul sejak lama, mudah untuk bekerja dengan mereka, mereka populer. Tetapi mereka, antara lain, juga lambat.


Berbagai implementasi WebSocket

Tugas-tugas yang dipecahkan oleh pengembang Socket.IO direduksi menjadi implementasi fungsi untuk mempublikasikan pesan dan berlangganan, hingga kemampuan untuk mengirim dan menerima pesan.

Pada saat yang sama, perlu dicatat penggunaan beberapa mekanisme cadangan untuk bekerja dengan protokol WebSocket, karena browser telah lama mendukung teknologi ini. Lalu lintas SSL tidak dapat diartikan oleh proksi perusahaan, ia melewati mereka dengan cara yang sama seperti lalu lintas HTTP, dan sebagai hasilnya, menggunakan protokol WebSocket melalui SSL tidak memblokir lalu lintas yang sesuai. Mekanisme cadangan untuk mendukung WebSocket dapat disediakan, tetapi tidak ada gunanya menggunakannya. Mereka hanya secara tidak masuk akal meningkatkan kompleksitas keputusan.

Salah satu tujuan dari μWebSockets.js adalah untuk memberikan pengembang fitur yang mirip dengan yang ditemukan di Socket.IO sehingga μWebSockets.js dapat sepenuhnya menggantikan Socket.IO tanpa memerlukan pembungkus tingkat yang lebih tinggi. . Ini dimungkinkan jika beberapa protokol non-standar khusus tidak digunakan.

Banyak perusahaan memiliki masalah dalam menerbitkan dan berlangganan pesan saat bekerja dengan WebSocket. Perlu dicatat bahwa dalam rilis yang dijelaskan dari μWebSockets.js fitur-fitur ini tidak banyak diperhatikan, tetapi sekarang pekerjaan serius sedang dilakukan pada mereka. Hasilnya akan sangat cepat (tes menunjukkan bahwa µWebSockets.js sudah lebih cepat dari Redis). Jadi tetap disini.

Ringkasan


Saat ini μWebSockets.js sedang berkembang, fitur baru ditambahkan ke proyek, kesalahan diperbaiki. Butuh beberapa waktu untuk menghilangkan kekurangan kecil yang merupakan ciri dari rilis pertama program baru. Ingatlah bahwa ini adalah proyek besar yang terdiri dari ribuan baris kode yang ditulis dalam C dan C ++, yang disimpan dalam tiga repositori. Di sinilah letak pembungkus JavaScript - uWebSockets.js. Berikut adalah server web yang ditulis dalam C ++ - uWebSockets. Dan di sini adalah pustaka dasar yang ditulis dalam C - uSockets.

Proyek tersebut digunakan oleh perusahaan, program-program yang digunakan untuk menciptakan beban besar pada subsistem I / O. Di perusahaan-perusahaan ini, stabilitas dan keamanan, yang sepenuhnya alami dan jelas, adalah karakteristik terpenting dari perangkat lunak yang mereka gunakan.

Pembaca yang budiman! Apakah Anda berencana untuk menggunakan μWebSockets.js dalam proyek Anda?

Source: https://habr.com/ru/post/id439976/


All Articles