Bashscript : Watching The Watchers

Oke pemirsa berjumpa kembali dengan saya penulis yang tidak Anda tunggu-tunggu. Kali ini saya akan berbicara mengenai ‘Bashscript‘. Alat yang sederhana dan ampuh di UNIX. Kasusnya saat ini pada sanggar teknologi saya, kami bermain dengan Node.js untuk membuat engine crawler. Crawlers ini kami sebar di puluhan server, untuk mengumpulkan data. Server yang ada ini termasuk minim, memori kecil dan CPU tunggal. Kami menggunakan PM2 untuk managing/admin process di Node.js. PM2 sebenarnya sudah baik hati akan auto-restart bila salah satu process mati, bisa karena error atau kesalahan lainnya. Namun pada satu waktu daemon process PM2 ini menghabiskan banyak memori sehingga terjadi kegagalan di PM2, men-drop semua process dan tidak di-invoke kembali. Waini sangat pelik sekali, dalam reliability. Kami masih menginvestigasi memory leak dalam proses yang jalan dan optimasi memori, ini memakan waktu lama. Oleh karena itu muncul ide untuk memeriksa proses itu masih aktif atau tidak, bila mati akan dinyalakan kembali oleh PM2. Idenya sesederhana itu, tinggal memilih solusinya.

Solusinya kami memanfaatkan cronjob di UNIX, untuk menjalankan sebuah ‘proses monitoring’ secara berkala. Proses monitoring ini yang akan memeriksa proses yang seharusnya diawasi oleh PM2, apabila down atau hilang dari pengawasan PM2. Kami memilih membuat proses monitoring ini dengan bashscript karena dapat memanfaatkan fungsi Terminal pada UNIX dengan mudah. Idenya, akan melihat dahulu proses yang dimaksud masih terdapat tidak di OS, lalu meng-invoke ulang bila tidak ada. Semua dilakukan dengan command ala Terminal.

Untuk melihat prosesnya masih ada,

ps auxw | grep [proses]| wc -l

`ps auxw` ini akan mengeluarkan semua daftar proses, lalu di-pipeline dengan ‘grep‘ mencari proses yang diinginkan, setelah itu di-pipeline lagi ke ‘wc -l‘ untuk menghitung jumlah proses yang ada. Bila proses yang ada berjumlah 1, berarti proses itu tidak ada di OS. Kenapa ada 1, itu proses grepnya sendiri terhitung. Untuk meng-invoke ulang proses di PM2 

pm2 start --name 'nama-proses'

, bisa dilihat di dokumentasi PM2. Lalu memasukkan di cronjob dengan mengubah cronjob usernya melalui `crontab -e`, kita ingin menjalankan cron ini tiap menit maka kita tulis di cron, 

* * * * * ./script.sh >> cron.log

Tanda ‘*’ lima kali itu untuk tanda menjalankan tiap menit (baca nih dokumentasinya), dilanjutkan dengan skrip yang ingin dieksekusi, serta di akhir akan ditulis log pada sebuah file cron.log untuk menampung STDERR atau STDOUT-nya. Ternyata ada masalah dengan ide sederhana ini, cronjob dengan bash ini sedikit tricky.

Semoga ini memberi pencerahan bagi saya khususnya dan bagi Anda umumnya (iki kok kayak khotbah jumat template ucapannya).

Jadi karena cronjob ini mengeksekusi bash yang menjalankan PM2, ternyata PM2 ini tidak dikenali dalam cronjob. Karena tidak ada di env_path si cron ini. Gampangnya kita perlu menambahkan env_path dalam bashscript ini dengan

PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/home/user/.nvm/v0.10.36/bin

, di bagian terakhir dapat dilihat kami memasukkan path node yang dipakai untuk memasukkan `pm2` pada path. Berikut contoh kode kami secara penuh

#!/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/home/user/.nvm/v0.10.36/bin
if [[ "$(ps auxw | grep /appdir/crawler/index.js | wc -l)" -lt 2 ]] ; then
pm2 start /appdir/crawler/index.js --name 'crawler-media'
fi

Nah untuk memudahkan menuliskan cronjob itu agar tak perlu manual satu-satu menulis di crontab tiap kali deploy di server (kita ada puluhan server), kami membuat bashscript untuk membuat cronjob. Idenya kami menuliskan isi cronjob pada sebuah file, lalu file itu disalin pada crontab. Untuk memasukkan apa saja yang perlu ditulis, kami akan mengambil dari argumen command linenya. Kodenya seperti ini

#!/bin/bash
touch mycron
for ((i=1;i<=$#;i++));
do
echo "* * * * * ./${!i}.sh >> run.log" >> mycron
done;
#install new cron file
crontab mycron
rm mycron

Bisa dilihat kita membuat file ‘mycron’ dengan `touch` lalu mengambil tiap argumen `${!i}` (argumen ini nama script) untuk ditulis ke file. Setelah itu file disalin ke crontab dan hapus filenya. Sederhana kan ? Cronjob ini sangat berguna sekali untuk membuat proses yang perlu dieksekusi periodik. Mantap kan dengan bashcript membuat proses yang mengawasi proses dengan memanfaatkan cronjob.

Sekian dan salam olahraga jari !
Advertisements
Bashscript : Watching The Watchers