Pengenalan NodeJS

Halo teman teman, saya yakin NodeJS tentu sudah ga asing lagi. NodeJS mulai populer terutama di kalangan web programer, menurut saya sendiri NodeJS cukup menarik karena memakai javascript sehingga tidak harus belajar bahasa baru :). Saya coba bertanya dengan beberapa teman programer tentang NodeJS komentarnya cukup beragam, ada yang suka ada yang nggak, beberapa seperti ini komentarnya :

“Javascript ga cocok untuk jalan di server”

“Callback nya bikin kode mbundet seperti spagetti”

Anggapan diatas mungkin tidak salah tapi belum tentu benar *njuk piye kuwi. Mari kita selidiki lebih lanjut ;).

Serba Serbi NodeJS

Seperti kita ketahui NodeJS berjalan di dalam single thread, dan untuk pemograman multi thread nya dapat menggunakan library pihak ketiga seperti thread_a_gogo. NodeJS menggunakan event loop dalam operasinya, yang berarti tiap event akan di simpan dalam sebuah pool kemudian ditangani menggunakan event handler yang biasa disebut callback. Keuntungannya adalah bisa meningkatkan efisiensi server. Semisal program NodeJS kita melakukan request ke database maka NodeJS tidak perlu menunggu query tersebut selesai utk melanjutkan eksekusi perintah selanjutnya, karena tiap request terdapat callback yang nanti akan dieksekusi setelah mendapat kan response (Non Blocking).

Operasi I/O seperti query database, akses ram, disk, atau network merupakan operasi dengan latency nya cukup tinggi, maka event loop menjadi sangat efektif karena bisa memanfaatkan waktu idle antara request dan response untuk mengeksekusi operasi selanjutnya.

Misal di PHP yg juga single thread jika terdapat operasi I/O maka dia akan blocking sehingga perintah selanjutnya harus menunggu sampai operasi tersebut selesai. Karena itu PHP membutuhkan web server untuk menangani request yang simultan. Misalnya menggunakan web server Apache.

Dalam Apache untuk menangani simultan request bisa dengan beberapa pendekatan (bisa dilihat di file konfigurasi : httpd-mpm.conf). Jika konfigurasi yang aktif adalah prefork MPM maka tiap http request dari client akan dihandle oleh process yang terpisah. Jika yang aktif adalah worker MPM maka tiap request akan dihandle oleh thread yang terpisah (membutuhkan PHP lib yang thread safe). Selain itu ada konfigurasi yang lain seperti winNT MPM dan event MPM. Namun intinya tiap request akan dihandle bisa menggunakan process atau thread yang berbeda, sehingga setiap request dapat ditangani secara simultan.

Jadi berbeda dengan NodeJS yang menggunakan event loop, walaupun single thread masih bisa menerima request simultan tanpa bantuan web server pihak ketiga. Jika ditambahkan bisa aja, sebagai load balancer biar tambah oke.

Betulkah Javascript tidak cocok untuk jalan di server?

Anggapan ini kurang tepat, walaupun tadi dibahas diatas bahwa tiap operasi dalam NodeJS adalah non blocking namun ini tidak berlaku untuk operasi yang CPU intensive seperti resize image, image filtering, komputasi data dan lain lain. Operasi CPU akan tetap melakukan blocking sehingga NodeJS akan menunggu operasi tersebut selesai baru melanjutkan operasi yang lain. Walaupun untuk operasi yang I/O intensive NodeJS sangat efisien. Btw, bahasa pemograman lain pun bersifat sama tidak hanya NodeJS.

Untuk lebih jelasnya kita coba program berikut ini. Kode di bawah merupakan script http server menggunakan NodeJS,

var http = require('http');

http.createServer(function(req, res) {
	process.stdout.write(".");
	res.writeHead(200, {'Content-Type' : 'text/html'});
	res.end();
}).listen(9000, '127.0.0.1');

kemudian coba melakukan test performance menggunakan Apache Benchmark (ab)

ab -c 4 -n 8 http://127.0.0.1:9000/

hasilnya adalah sebagai berikut :

ab_sc1

Kemudian bagaimana jika di dalam script tersebut kita tambahkan operasi yang CPU intensive, misal perhitungan fibonacci (jika kurang puas bisa diganti ops yg lebih uh yeah 😀 ).

var http = require('http');

function fibo (n) {
  return n > 1 ? fibo(n - 1) + fibo(n - 2) : 1;
}

http.createServer(function(req, res) {
	process.stdout.write(fibo(35).toString());
	process.stdout.write(".");
	res.writeHead(200, {'Content-Type' : 'text/html'});
	res.end();
}).listen(9000, '127.0.0.1');

coba ulangi melakukan test performance seperti sebelumnya, hasilnya sebagai berikut :

ab_sc2

Request Per Second nya turun drastis, karena operasi fibonacci melakukan blocking. Yang berarti request yang lain harus menunggu sampai operasi tersebut selesai.

Untuk mendesain program yang terdapat CPU intensive kita bisa menggunakan beberapa cara, misal menggunakan load balancer. Selain itu NodeJS mempunyai module yang bisa digunakan untuk membuat load balancer yaitu Cluster. Konsepnya mirip dengan Apache prefork MPM. Yaitu membuat child proses untuk menangani request yang datang. Namun sayangnya, saat ini module Cluster masih bersifat experimental jadi mungkin masih belum cocok untuk digunakan dalam produksi, tapi silahkan dicoba 🙂

Kemudian script tadi kita beri tambahan kode untuk load balancer menggunakan Cluster seperti berikut

var http = require('http');
var cluster = require('cluster');

function fibo (n) {
  return n > 1 ? fibo(n - 1) + fibo(n - 2) : 1;
}

if(cluster.isMaster) {

	var cpuCount = require('os').cpus().length;

    for (var i = 0; i < cpuCount; i += 1) {
        cluster.fork();
    }

} else {

	http.createServer(function(req, res) {
		process.stdout.write(fibo(35).toString());
		process.stdout.write(".");
		res.writeHead(200, {'Content-Type' : 'text/html'});
		res.end();
	}).listen(9000, '127.0.0.1');

}

kemudian kita coba test performanya menggunakan ab seperti sebelumnya, hasilnya sebagai berikut :

ab_sc3

Request per Secondnya meningkat 100% tergantung core CPU yg digunakan. Dalam percobaan ini menggunakan processor i3 (4 keping core).

Walaupun dari test diatas hasilnya bisa meningkat namun sebenarnya penggunaan process tersendiri untuk menangani request yg simultan menjadi kurang efisien, Karena process membutuhkan resource yang lebih tinggi terutama memori karena child process akan mengduplikasi memori milik parent. Karena itu kita bisa menggunakan thread yang menggunakan shared memori antar thread dalam process yang sama.

Multithreading dalam NodeJS membutuhkan library pihak ketiga, kita bisa menggunakan thread_a_gogo.

Spagetti Code, dan Callback Hell

Untuk hal ini akan dibuat artikel terpisah, biar ga terlalu panjang. yang akan membahas tentang control flow di NodeJS selain menggunakan callback langsung, yaitu menggunakan sebuah wrapper library untuk callback semacam Q.

semoga bermanfaat

8 Replies to “Pengenalan NodeJS”

  1. Cluster sepertinya sudah bukan eksperimental, lupa ngecek.. tapi terakhir pakai, mayan tangguh sih.. Kalo pakai PM2, kita bisa bikin fork dari sana, jadi clusteringnya dari PM2, gak perlu dari app kita.

      1. Ya, rada lengkap sih fiturnya PM2. Ada monitor dan juga web dashboard juga di situ. Start dan stop app juga bisa pakai .json.

Leave a Reply

Your email address will not be published. Required fields are marked *