5 Tips Untuk Mempercepat Kinerja Node Js - CRUDPRO

5 Tips Untuk Mempercepat Kinerja Node Js

Node.js dikenal sebagai environtment JavaScript server-side I/O dan single-threaded yang berarti memiliki thead tunggal dengan banyak loop atau proses yang tidak terhingga dan terus menerus yang berfungsi sebagai controller menggunakan mesin v8 (mesin JavaScript kinerja tinggi open source Google). Arsitektur event-driven Node.js adalah teknologi hebat untuk aplikasi realtime, terutama aplikasi obrolan dan streaming. Sisi client dan server-side ditulis dalam JavaScript, yang membuat proses sinkronisasi utas tunggal lebih tepat dan lebih cepat.

Karena Node.js sangat produktif, kami sangat membutuhkan cara untuk mengoptimalkan Node.js. Pada artikel ini, saya akan menunjukkan lima cara untuk membuat Node.js lebih cepat dan lebih optimal.

1.Cache aplikasi Anda dengan Redis

Apa itu caching? Proses caching menggunakan Redis sebagai versi Memcached yang lebih kompleks. Redis selalu menyajikan dan memodifikasi data di memori utama server. Dampaknya sistem cepat mendapatkan data yang dibutuhkan.

Ini juga mengurangi waktu yang diperlukan untuk membuka halaman web dan mempercepat situs Anda. Redis berfungsi untuk membantu dan meningkatkan kinerja pemuatan dari database relasional atau NoSQL dengan membuat cache dalam memori yang baik untuk mengurangi latensi akses.

Dengan Redis, Anda dapat menggunakan SET dan GET untuk menyimpan cache. Selain itu, Redis dapat menangani tipe data yang kompleks seperti List,Sets, dan ordered data structures.

Bandingkan dua Kode di Node.js. Berikut ini adalah kasus ketika mencoba mendapatkan data dari GoogleBook API tanpa menempatkan Redis di endpoint.

Node.js tanpa Redis:

Dan sekarang, tempatkan Redis di endpoint ini. Jika Anda mengalami masalah saat menggunakan Redis, Anda dapat membaca dokumentasi Redis selengkapnya di Node.js.

Node.js dan Redis:

Seperti yang Anda lihat, kode di atas menjelaskan bahwa Redis menyimpan data cache dengan nilai kunci unik yang Anda tentukan menggunakan fungsi ini.

client.setex (isbn, 3600, JSON.stringify(book));

Kemudian gunakan fungsi berikut untuk mendapatkan data yang di-cache.

client.get(isbn, (err, result) => {
     if (result) {
       res.send (result);
     } else {
       getBook (req, res);
     }
   });

Ini adalah hasil dari pengujian kedua kode. Jika Anda tidak menggunakan Redis sebagai cache, dibutuhkan setidaknya 908,545 ms

Waktu respons tanpa Redis

Sangat berbeda ketika Node.js menggunakan Redis. Lihat ini. Ini sangat cepat dan hanya membutuhkan 0,621 ms untuk mendapatkan data pada endpoint yang sama.

Waktu respons di Redis

2. Pastikan Queri dioptimalkan

Pada dasarnya, proses yang dimunculkan oleh database dalam sebuah query memiliki dampak yang besar terhadap kinerja.

Ketika endpoint menghasilkan data yang dipanggil oleh sistem. query yang buruk dapat sangat memperlambat proses menampilkan data.

Misalnya, jika Anda memiliki data di MongoDB, masalahnya adalah jika Anda memiliki 4 juta baris data, Anda dapat menemukan satu kata kunci data yang diinginkan tanpa menggunakan skema indeks yang secara signifikan dapat memperlambat proses query.

Anda dapat menggunakan MongoDB untuk menganalisis cara kerja proses query. Anda dapat menambahkan query berikut: explain("executionStats") untuk menganalisis dan mengambil data pengguna dari collaction.

> db.user.find({email: '[email protected]'}).explain("executionStats")

Lihat ini. Sebelum kami buat index, request respons saat mencari data.

> db.user.find({email:'[email protected]'}).explain("executionStats")
{
 "queryPlanner" : ...
  },
  "winningPlan" : {
   "stage" : "COLLSCAN",
   "filter" : {
    "email" : {
     "$eq" : "[email protected]"
    }
   },
   "direction" : "forward"
  },
  "rejectedPlans" : [ ]
 },
 "executionStats" : {
  "executionSuccess" : true,
  "nReturned" : 1,
  "executionTimeMillis" : 0,
  "totalKeysExamined" : 0,
  "totalDocsExamined" : 1039,
  "executionStages" : {
   ...   
    },
   ...
  }
 },
 "serverInfo" : {
  ...
 },
 "ok" : 1
}
>

Dari hasil JSON di atas, ada dua poin penting yang bisa dianalisis:

  • nReturned: Menampilkan 1 untuk menunjukkan bahwa query cocok dan mengembalikan satu dokumen.
  • totalDocsExamined: MongoDB memindai 1039 data dokumen (yang mencari semua dokumen) dan mendapatkan satu data yang diinginkan.

Ini adalah saat Anda mencoba menambahkan email indeks ke collaction pengguna Anda.

> db.getCollection("user").createIndex({ "email": 1 }, { "name": "email_1", "unique": true })
{
 "createdCollectionAutomatically" : false,
 "numIndexesBefore" : 1,
 "numIndexesAfter" : 2,
 "ok" : 1
}

Hasil analisis query setelah menambahkan email indeks:

> db.user.find({email: '[email protected]'}).explain("executionStats")
{
 "queryPlanner" : ...,
  "winningPlan" : {
   "stage" : "FETCH",
   "inputStage" : {
    "stage" : "IXSCAN",
    "keyPattern" : {
     "email" : 1
    },
    "indexName" : "email_1",
    "isMultiKey" : false,
    "isUnique" : true,
    ...
   }
  },
  "rejectedPlans" : [ ]
 },
 "executionStats" : {
  "executionSuccess" : true,
  "nReturned" : 1,
  "executionTimeMillis" : 0,
  "totalKeysExamined" : 1,
  "totalDocsExamined" : 1,
  ...
   }
  }
 },
 "serverInfo" : {
  ...
}

Pada titik totalDocsExamined, Anda dapat melihat bahwa MongoDB hanya mencari satu data yang relevan. Hal ini membuat proses query lebih cepat dan efisien. Keuntungan menambahkan indeks ke MongoDB adalah: Menambahkan indeks juga membantu mengurutkan data dalam collaction.

3. Gunakan log untuk melihat semua skrip yang error

Mengapa logging itu penting? Yang pertama adalah Anda perlu memastikan bahwa program aplikasi Anda berjalan dengan benar tanpa kesalahan fatal. Setiap kali Anda menemukan sesuatu yang aneh di program Anda, inilah saatnya untuk mencari tahu kode mana yang menyebabkan kesalahan. Anda dapat menggunakan logging untuk melacak aktivitas dan lalu lintas proses API.

Proses logging yang sering digunakan orang adalah menggunakan console.log("log output") secara default. Ini memasukkan beberapa log ke dalam standar keluaran (stdout) dan membuat console.error ("log error") juga menjadi standar kesalahan (stderr). Namun, kami menyarankan untuk menggunakan modul logging yang lebih umum dan efisien seperti Winston, Morgan, Buyan.

Berikut adalah contoh cara login menggunakan Winston. Secara umum, Winston memiliki empat tingkat kustom yang dapat Anda gunakan: error, warn, info, verbose, debug, silly, dan banyak lagi.

Beberapa fitur yang tersedia di Winston:

  • Anda dapat menggunakan beberapa transportasi dari jenis yang sama
  • Pembuatan profil sederhana
  • Mendukung query log
  • Dimungkinkan untuk catch dan mencatat log uncaughtException
  • Atur level pesan log

Pertama, Anda perlu menginstal Winston dan memasukkan Winston ke dalam proyek baru atau yang dikembangkan. Untuk melakukannya, jalankan perintah berikut:

npm install winston --save

Ini adalah konfigurasi dasar Winston yang kami gunakan:

const winston = require('winston');
let logger = new winston.Logger({
transports: [
new winston.transports.File({
level: 'verbose',
timestamp: new Date(),
filename: 'filelog-verbose.log',
json: false,
}),
new winston.transports.File({
level: 'error',
timestamp: new Date(),
filename: 'filelog-error.log',
json: false,
})
]
});
logger.stream = {
write: function(message, encoding) {
logger.info(message);
}
};

Dari kode di atas, Anda dapat melihat bahwa Anda menggunakan beberapa konfigurasi transport dengan dua tingkat verbose dan error.

4. Terapkan HTTP/2

HTTP/2, biasa disebut sebagai SPDY, adalah standar protokol web terbaru yang dikembangkan oleh kelompok kerja HTTP IETF. HTTP/2 membuat penjelajahan web lebih cepat, mudah, dan penggunaan bandwidth lebih rendah. Ini berfokus pada kinerja, terutama untuk memecahkan masalah yang masih terjadi di versi HTTP/1.x sebelumnya. Anda sekarang dapat melihat beberapa halaman web populer seperti Google, Facebook, dan YouTube yang menerapkan protokol HTTP/2 di halaman web mereka.

Mengapa ini lebih baik daripada HTTP/1.x?

  • Multiplexing:
  • Multiplexing memungkinkan beberapa request dan pesan tanggapan untuk mengambil sumber daya secara bersamaan pada satu koneksi TCP.

  • Kompresi header:
  • Setiap request melalui HTTP berisi informasi header. Dalam HTTP/1.1, satu sesi mengulang banyak header dan menggandakan informasi yang sama. Overhead ini cukup besar. HTTP/2 push sisa header dan menghapus header tambahan, memaksa semua header HTTP dikirim dalam format terkompresi.

  • Push server:
  • Dengan HTTP/1.1, Anda harus menunggu client mengirim koneksi. Dengan server push, server dapat menghindari penundaan pengiriman data dengan "push" respons yang diklaim client perlu untuk menyimpan data dalam cache. Ini mengurangi jumlah request dan secara otomatis mengurangi waktu pemuatan halaman.

    Format biner:

    HTTP/1.1 mengirimkan data dalam format teks, dan HTTP/2 mengirimkan data dalam format biner. Protokol biner lebih efisien dalam menganalisis dan mengurangi kesalahan daripada versi protokol teks sebelumnya.

    Node.js saat ini mendukung dan menyediakan implementasi HTTP/2 dari inti Node.js. API ini sangat mirip dengan API HTTPS node.js standar. Untuk memulai dengan HTTP/2, Anda dapat membuat server HTTP/2 di Node.js menggunakan baris kode berikut:

    Untuk mengimplementasikan protokol Transport Layer Security (TLS) dan Secure Sockets Layer (SSL) yang dibangun di atas OpenSSL. Anda dapat membuat sertifikat SSL yang ditandatangani sendiri dari mana Anda dapat menghasilkan server.key dan server.crt.

    Dukungan HTTP/2 masih eksperimental, jadi Node.js harus dimulai dengan baris perintah --expose-http2.

    $ node --expose-http2 node-http2.js
    

    Kemudian periksa apakah situs web Anda menggunakan protokol HTTP/2 terbaru.

    HTTP2 dengan Node.js

    Dari gambar di atas, Anda dapat melihat bahwa situs web menggunakan protokol HTTP/2.

    5. Clustering Node.js

    Secara default, Node.js berjalan dalam satu theread pada single-core prosesor. Itu juga tidak menggunakan beberapa inti yang mungkin tersedia di sistem. Tapi sekarang, dengan cluster Node.js, mudah untuk membuat proses child di mana semuanya berbagi port server. Ini berarti bahwa cluster dapat menangani sejumlah besar request pada sistem multi-core. Dan secara otomatis, ini akan meningkatkan kinerja server Anda.

    Module cluster Node.js

    Node.js mengimplementasikan module cluster inti yang memungkinkan aplikasi Anda berjalan di banyak inti. Proses parent/master module cluster dicabangkan oleh sejumlah proses child/worker dan dapat mengirim pesan dan berkomunikasi dengan mereka melalui komunikasi IPC. Lihatlah gambar gif kode kecil di bawah ini.

    Ketika saya menjalankan node, sepertinya Node.js saat ini menggunakan 4 workers menggunakan cluster.

    Node.js cluster

    Anda sekarang dapat mengakses tautan http:localhost:3000/cluster di tab dan browser lain. Ada ID worker yang berbeda untuk setiap tab.

    Pengelompokan atau Clustering Node.js dengan PM2

    PM2 adalah manajer proses produksi untuk aplikasi Node.js dengan penyeimbang beban bawaan. Ini memungkinkan Anda untuk menjaga aplikasi Anda tetap hidup selamanya, memuat ulang tanpa downtime, dan memfasilitasi tugas administrasi sistem umum. Salah satu fitur hebatnya adalah penggunaan otomatis Cluster API Node. PM2 memungkinkan Anda untuk menjalankan aplikasi Anda sebagai beberapa proses tanpa mengubah kode Anda. Sebagai contoh, berikut ini adalah kode sederhana yang dibuat menggunakan express.

    Menggunakan perintah berikut, PM2 akan secara otomatis menghasilkan pekerja sebanyak inti CPU. Mulai perintah untuk mengaktifkan cluster menggunakan PM2 dan jalankan perintah berikut:

    pm2 start  app.js -i 0
    

    Sekarang Anda dapat melihat bagaimana cluster PM2 telah berkembang di semua CPU yang tersedia.

    Secara keseluruhan, cluster PM2 adalah alat yang ampuh yang dapat meningkatkan konkurensi dan kinerja keseluruhan Node.js secara signifikan. Ini lebih mudah daripada menggunakan modul cluster yang ada di Node.js Core.

    Semoga artikel ini dapat bermanfaat :)