Membuat Sistem Antrian Tugas (Task Queue) dengan Laravel Queue dan AWS SQS

Ridwan Fajar
Serverless Indonesia
6 min readJun 12, 2020
Sebuah taman di Dapur Cartil dan pemandangan Gunung Wayang di Pangalengan, Caringin Tilu, Kecamatan Cimenyan, Kabupaten Bandung

Pendahuluan

Di dalam aplikasi web berskala besar, biasanya terdapat sebuah sistem yang mampu menangani workload dengan jumlah yang sangat masif. Hal tersebut dapat berupa load balancing di sisi aplikasi, master-slave replication di sisi database atau membagi beban web server ke server lain melalui sebuah antrian tugas (task queue).

Dengan menggunakan antrian tugas, beberapa bagian kode aplikasi web yang memiliki operasi high intensive, dapat dipecah dan diubah menjadi sebuah task yang nantinya akan di-invoke dari sisi aplikasi web. Dengan demikian response time suatu endpoint pun dapat menjadi lebih cepat karena bagian kode yang memiliki operasi high intensive sudah dipisahkan.

Contoh operasi high intensive antara lain:

  • pengiriman e-mail ke mail server
  • manipulasi gambar yang di-upload oleh client
  • konversi data dari database ke bentuk file tertentu
  • menggunakan service dari third-party
  • dan lainnya.

Konsep task queue di Laravel dapat dijalankan dengan beberapa macam broker. Diantaranya dapat menggunakan: MySQL, Redis, Beanstalkd dan AWS SQS.

Arsitektur Laravel Queue dengan menggunakan AWS SQS

Di artikel ini kita akan coba menjalankan konsep sederhana task queue di Laravel dengan menggunakan AWS SQS.

A. Menyiapkan Proyek Laravel

Di dalam artikel ini, diasumsikan ada sebuah proyek Laravel yang akan berisi sistem antrian tugas. Sistem tersebut akan menggunakan Laravel Queue dan AWS SQS sebagai broker-nya.

Kita akan coba membuat dua buah job yang akan dieksekusi ketika Laravel Queue menerima pesan dari broker. Berikut adalah snippet untuk job pertama dari file app/Jobs/ExampleJob.php yang berisi pesan hello world untuk Laravel Queue:

Sedangkan berikut ini adalah snippet untuk job yang menerima sebuah parameter bernama message . File tersebut berlokasi di app/Jobs/HelloWorldJob.php:

Dan berikut ini adalah file routes/web.php, yang berisi sebuah endpoint bernama /test-queue . Di dalamnya terdapat proses dispatch() dimana sebuah job akan dieksekusi setelah menerima pesan dari AWS SQS.

B. Menyiapkan AWS SQS

Untuk menggunakan AWS SQS di dalam Laravel Queue, maka kita harus membuat sebuah queue terlebih dahulu. Silahkan buka AWS Console kemudian pilih “SQS”. Maka akan muncul halaman seperti pada gambar berikut apabila belum pernah membuat queue sama sekali.

Tekan tombol “Get Started Now” untuk membuat queue baru.

Ilustrasi B.1 — Mulai membuat queue di AWS SQS

Begitu menekan tombol tersebut, Anda akan diberikan form seperti pada gambar berikut ini:

Ilustrasi B.2 — Form untuk membuat queue di AWS SQS

Di kolom “Queue Name”, Anda dapat mengisikan nama queue yang diinginkan.

Ilustrasi B.3 — Menentukan nama saat pembuatan queue di AWS SQS

Lanjut dengan scroll sedikit ke bawah, Anda dapat memilih jenis queue yang tersedia yaitu “Standard Queue” dan “FIFO Queue”. Di artikel ini akan dipilih “Standard Queue”.

Ilustrasi B.4 — Memilih jenis queue di AWS SQS

Form untuk membuat queue terhitung cukup sederhana. Karena konfigurasinya akan dilakukan lebih lanjut setelah proses pembuatan queue atau dengan menekan tombol “Configure Queue”. Bila sudah nama queue dan tipe queue yang akan dibuat sudah sesuai, silahkan tekan tombol “Quick Create Queue”.

Ilustrasi B.5 — menyelesaikan pembuatan queue

Bila berhasil, Anda dapat melihat halaman daftar queue beserta queue yang baru saja dibuat. Di halaman ini cukup banyak informasi yang tersedia untuk menggunakan queue di AWS SQS ke dalam aplikasi web kita.

Ilustrasi B.6 — Queue berhasil dibuat di AWS SQS

Dengan mengklik kanan salah satu queue, Anda dapat melihat pop-up menu dimana Anda dapat mengelola queue lebih lanjut seperti:

  • mengirim pesan
  • melihat pesan yang masuk
  • melakukan konfigurasi lanjut suatu queue
  • menghapus queue
  • menghubungkan queue ke SNS Topic atau Lambda Function
Ilustrasi B.7 — Menu untuk mengelola queue di AWS SQS

Dengan demikian, cara integrasi AWS SQS ke Laravel Queue cukup mudah. Beberapa environment variables berikut harus ditambahkan ke dalam file .env agar Laravel Queue dapat berjalan diatas AWS SQS:

QUEUE_DRIVER=sqs
QUEUE_CONNECTION=sqs
SQS_KEY=<aws_access_key_id>
SQS_SECRET=<aws_secret_access_key>
SQS_QUEUE=laravel-test-queue
SQS_REGION=ap-southeast-1
SQS_PREFIX=https://sqs.ap-southeast-1.amazonaws.com/<aws_user_id>

C. Menguji Sistem Antrian Tugas

C.1. Menjalankan single worker

Di dalam sistem antrian tugas, harus terdapat producer dan consumer. Dalam konteks Laravel Queue, producer adalah aplikasi web Laravel sendiri. Sedangkan consumer adalah Laravel Jobs dimana sebuah class akan berisi sejumlah kode untuk menerima pesan dari AWS SQS dan memproses pesan tersebut sesuai tugasnya.

Sebagai ilustrasi, proyek Laravel yang dibuat sebelumnya memiliki sebuah endpoint bernama /test-queue . Kemudian dari endpoint tersebut akan dijalankan dua buah jobs yaitu ExampleJob dan HelloWorldJob .

Ilustrasi C.1 — Respon endpoint yang berhasil meminta eksekusi queue

Kemudian masih di direktori aplikasi yang sama, kita buka terminal untuk menjalankan worker atau Laravel Jobs dengan perintah php artisan queue:work .

Bila berhasil, maka berikut ini adalah tampilan dari Laravel Queue yang berhasil dicoba di localhost . Laravel Queue pada ilustrasi dibawah ini berjalan diatas queue yang telah dibuat sebelumnya di AWS SQS.

Ilustrasi C.2 — Contoh output pemrosesan queue oleh Laravel Queue Worker

Kita dapat uji dengan memanggil beberapa kali endpoint /test-queue dengan menggunakan Apache Benchmark misal dengan perintah ab -n 100 0 -c 100 . Kemudian buka AWS SQS Console dan klik kanan pada queue laravel-test-queue agar muncul popup menu.

Kemudian klik “View / Delete Messages” untuk melihat pesan — pesan yang masuk ke AWS SQS dari Laravel Queue yang dikirim melalui endpoint /test-queue . Hasilnya dapat Anda lihat pada ilustrasi C.3 berikut ini.

Ilustrasi C.3 — Contoh pesan yang dilewatkan ke AWS Queue dari Laravel

Anda dapat melihat detail pesan yang masuk pada AWS SQS dengan mengklik salah satu pesan, kemudian akan muncul pesan detail seperti pada gambar berikut ini:

Ilustrasi C.4 — Contoh detail pesan yang dikrimkan ke AWS SQS dari Laravel Queue

Demikianlah contoh Laravel Queue dengan satu worker dan menggunakan AWS SQS. Berikutnya kita akan mencoba menjalankan Laravel Queue dengan multiple workers.

C.2. Menjalankan multiple workers

Hampir sama dengan demo sebelumnya, kita akan mencoba menjalan beberapa worker sebanyak 3 worker. Namun kita memerlukan library ramsey/uuid untuk menunjukkan bahwa Laravel Queue dapat mendistribusikan message secara bergiliran ke setiap worker.

Mari kita tambahkan library ramsey/uuid ke dalam proyek laravel kita:

$ composer require ramsey/uuid

Sekarang kita ubah kode bagian routes/web.php dengan menambahkan library ramsey/uuid dan juga melewatkan UUID tersebut ke HelloWorldJob:

Lalu ubah kode di HelloWorldJob.php menjadi seperti pada snippet berikut ini agar dapat mencatat tanggal pengiriman pesan saat pesan diproses di dalam queue:

Kita akan coba buka dua terminal baru di direktori yang sama kemudian jalankan php artisan queue:work di kedua terminal baru tersebut.

Bila Anda memanggil endpoint /test-queue sebanyak 10 kali per satu detik, maka secara bergiliran ketiga worker akan memproses pesan dari AWS SQS tanpa memprosesnya secara berulang di worker yang berlainan. Sehingga dipastikan bahwa suatu pesan akan diproses maksimal satu kali dalam satu worker saja.

Sebagai contoh silahkan lihat proses invokasi terhadap endpoint /test-queue yang dilakukan dari command line dengan menggunakan script queue-test.sh . Berikut adalah source code dari script testing tersebut:

Sedangkan berikut ini adalah hasil eksekusi dari script testing diatas:

Ilustrasi C.5 — menjalankan multiple workers di Laravel Queue dengan AWS SQS

Tampak pada gambar diatas, setiap pesan yang dikirim per detiknya, diproses maksimal oleh satu worker dan tidak dikerjakan oleh worker lain. Seperti itulah fungsi dari multi worker di Laravel Queue yang dapat menambah penyelesaian job yang lebih cepat.

Kesimpulan

Sebuah aplikasi berskala besar, seyogyanya harus memiliki sistem task queue / message queue / jobs queue atau sejenisnya yang dapat mendistribusikan request dengan komputasi besar ke server lain yang terpisah dari web application server.

Dengan demikian kecepatan request dan response dapat ditingkatkan menjadi lebih cepat tanpa harus menurunkan kualitas layanan kepada client. Selain itu dengan menggunakan AWS SQS, kita dapat menjalankan Laravel Queue lebih mudah dan robust karena AWS SQS memilik data retensi hingga 7 hari lamanya. Selain itu terdapat skema pengamanan terhadap failed processing di AWS SQS.

Terima kasih kepada Fajri Abdillah dan Tajhul Faijin Aliyudin yang berkenan untuk me-review artikel ini

--

--