L
Cloud Architecture & Serverless • Literally Web ID

Arsitektur Serverless Berbasis Event-Driven di AWS Lambda dan SQS

⏱️ 15 menit baca • 📅 19 Oct 2026 • 👁️ 2 views
Arsitektur Serverless Berbasis Event-Driven di AWS Lambda dan SQS

1. Konteks Industri & Analisis Akar Masalah

Dalam lanskap arsitektur sistem web modern berskala besar, menangani lonjakan beban (high concurrency) dan memastikan durabilitas data tanpa mengorbankan latensi adalah tantangan krusial bagi seorang Cloud Architect. Pendekatan monolitik tradisional dengan server web tunggal (seperti Nginx/Apache yang memproses permintaan secara sinkron dan langsung berinteraksi dengan basis data relasional seperti MySQL) sering kali mengalami bottleneck parah ketika dihadapkan pada trafik lonjakan mendadak (traffic spikes).

Skenario klasik di industri e-commerce, sistem logistik, atau layanan keuangan menunjukkan bahwa pemrosesan sinkron secara langsung memicu connection pool exhaustion, kegagalan HTTP 504 Gateway Time-out, dan hilangnya transaksi akibat kegagalan transaksional langsung. Sebelum penerapan arsitektur berbasis event dengan AWS Lambda dan SQS, infrastruktur tipikal mengandalkan antrian berbasis server fisik atau instance EC2 dengan Supervisor dan Redis/RabbitMQ. Pendekatan lama ini membawa beban operasional yang tinggi: tim infrastruktur harus mengelola auto-scaling groups (ASG) untuk worker, menangani patching sistem operasi, dan melakukan tuning kernel Linux untuk menangani ribuan koneksi TCP konkuren.

Sesudah penerapan arsitektur Serverless Event-Driven menggunakan AWS SQS (Simple Queue Service) sebagai buffer asinkron dan AWS Lambda sebagai compute engine, sistem mencapai pemisahan yang bersih (decoupling) antara produsen data (producers) dan konsumen data (consumers). SQS bertindak sebagai penyerap kejut (shock absorber) yang menampung jutaan pesan tanpa membebani backend, sementara Lambda melakukan scaling secara otomatis dari nol hingga ribuan eksekusi konkuren dalam milidetik tanpa ada satu pun server fisik yang perlu di-provision atau dipelihara oleh insinyur.

2. Konsep Inti & Deep Dive Arsitektur

Arsitektur event-driven berbasis SQS dan Lambda beroperasi dengan prinsip pemisahan total antara lapisan penerima permintaan (Ingress Layer) dan lapisan pemrosesan bisnis (Processing Layer).

+----------------+       +-------------------+       +-------------------+
|  Client Web/API| ----> | API Gateway / App | ----> |    Amazon SQS     | 
|  (Nginx/Go/PHP)|       |   (Producer)      |       |   (Standard/FIFO) |
+----------------+       +-------------------+       +-------------------+
                                                               |
                                                               v
                                                     +-------------------+
                                                     |    AWS Lambda     |
                                                     | (Event Consumer)  |
                                                     +-------------------+
                                                               |
                                                               v
                                                     +-------------------+
                                                     | Database / Storage|
                                                     |  (MySQL / S3 / Redis)
                                                     +-------------------+

Alur Kerja di Balik Layar (Under the Hood)

  1. Injeksi Event (Producer): Klien mengirimkan request ke aplikasi web backend (misalnya menggunakan Nginx sebagai reverse proxy yang meneruskan ke aplikasi Node.js, Go, atau PHP). Aplikasi tersebut memvalidasi payload, lalu mempublikasikan pesan ke Amazon SQS menggunakan SDK AWS. Respons dikembalikan ke klien secara instan (sub-100ms) tanpa menunggu proses berat selesai.
  2. Buffer & Penampungan (SQS): SQS menyimpan pesan secara aman di beberapa zona ketersediaan (Multi-AZ). Pesan ini berada dalam status tersembunyi (invisible) jika sedang diproses, atau tersedia untuk diambil oleh konsumen.
  3. Polling & Polling Batch (Lambda Event Source Mapping): Layanan internal AWS Lambda secara otomatis melakukan polling terhadap antrian SQS. Lambda membaca pesan dalam bentuk batch (hingga 10 pesan atau ukuran batch maksimum yang dikonfigurasi) dan memicu fungsi handler.
  4. Eksekusi Komputasi (Lambda Execution Environment): Lambda menginisialisasi lingkungan eksekusi (atau menggunakan wadah yang sudah hangat / warm start), menjalankan kode bisnis untuk memproses batch pesan, dan berinteraksi dengan penyimpanan persistensi seperti Aurora MySQL, Redis, atau Amazon S3.
  5. Acknowledge & Penghapusan: Jika fungsi Lambda mengeksekusi seluruh batch tanpa melempar eksepsi (exception), AWS Lambda secara otomatis mengirimkan sinyal penghapusan (DeleteMessage) ke SQS untuk pesan-pesan tersebut. Jika terjadi kegagalan, pesan dikembalikan ke antrian untuk dicoba ulang (retry).

3. Perbandingan Komparatif / Analisis Pendekatan

Untuk memahami nilai strategis dari arsitektur ini, mari kita bandingkan dengan pendekatan tradisional berbasis Worker EC2 dan Message Broker konvensional.

Parameter Perbandingan Tradisional (EC2 + Redis/RabbitMQ + Supervisor) Serverless Modern (AWS Lambda + SQS)
Model Manajemen Infrastruktur Manajemen manual (OS patching, kernel tuning, security groups) Sepenuhnya dikelola AWS (Managed Service / Serverless)
Skalabilitas Mengandalkan Auto Scaling Group (ASG) dengan latensi menit Skala instan dalam milidetik berdasarkan jumlah pesan di SQS
Biaya Saat Idle Membayar penuh instance EC2 24/7 meskipun tanpa trafik Biaya nol saat tidak ada eksekusi (Pay-per-execution)
Manajemen Kegagalan & Retry Harus membangun logika retry dan poison pill handling sendiri Didukung bawaan via Visibility Timeout, DLQ, dan Event Source Mapping
Keterbatasan Komputasi Dibatasi oleh spesifikasi instance (vCPU, RAM tetap) Dibatasi oleh timeout maksimal Lambda (15 menit) & alokasi memori
Kompleksitas Jaringan Memerlukan konfigurasi VPC, NAT Gateway, dan port forwarding Terintegrasi secara mulus dengan AWS IAM dan VPC Endpoint

[!WARNING] Batasan eksekusi tunggal AWS Lambda maksimal adalah 15 menit. Jika proses asinkron Anda membutuhkan waktu lebih lama dari batas ini, Anda harus memecah tugas menjadi sub-tugas yang lebih kecil atau beralih menggunakan AWS Step Functions.

4. Prasyarat Sistem & Persiapan Lingkungan

Sebelum mulai merancang infrastruktur kode (Infrastructure as Code / IaC) atau kode fungsi, pastikan lingkungan pengembangan dan produksi Anda memenuhi standar berikut:

  • Akun AWS & Hak Akses: Akses administratif atau peran IAM dengan izin penuh untuk mengelola AWS Lambda, SQS, IAM, dan CloudWatch.
  • Perangkat Lunak Lokal:
    • AWS CLI versi 2.x terinstal dan terkonfigurasi dengan profil yang valid.
    • Node.js (v18.x atau v20.x LTS) atau Go (v1.21+) sebagai runtime bahasa pemrograman.
    • Terraform (v1.6+) atau AWS SAM CLI untuk otomatisasi deployment.
  • Konektivitas Jaringan & DNS: Jika Lambda perlu mengakses basis data internal seperti MySQL yang berjalan di private subnet, pastikan VPC, Subnet, dan Security Groups telah dikonfigurasi dengan VPC Endpoint untuk SQS guna menghindari lalu lintas keluar melalui NAT Gateway.

Verifikasi konfigurasi AWS CLI Anda dengan perintah terminal:

aws sts get-caller-identity

5. Panduan Implementasi Langkah demi Langkah

Berikut adalah implementasi lengkap menggunakan Terraform untuk memprovisikan infrastruktur SQS (beserta Dead Letter Queue), IAM Roles yang aman dengan prinsip Least Privilege, dan fungsi AWS Lambda.

A. Definisi Infrastruktur Terraform (main.tf)

terraform {
  required_version = ">= 1.6.0"
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"
    }
  }
}

provider "aws" {
  region = "ap-southeast-1"
}

# 1. Dead Letter Queue (DLQ) untuk menampung pesan gagal
resource "aws_sqs_queue" "dead_letter_queue" {
  name                      = "order-processing-dlq"
  message_retention_seconds = 1209600 # 14 hari
}

# 2. SQS Utama dengan Redrive Policy ke DLQ
resource "aws_sqs_queue" "main_queue" {
  name                       = "order-processing-queue"
  visibility_timeout_seconds = 30
  message_retention_seconds  = 345600 # 4 hari
  receive_wait_time_seconds  = 20     # Long polling

  redrive_policy = jsonencode({
    deadLetterTargetArn = aws_sqs_queue.dead_letter_queue.arn
    maxReceiveCount     = 3
  })
}

# 3. IAM Role untuk AWS Lambda
resource "aws_iam_role" "lambda_exec_role" {
  name = "order_processor_lambda_role"

  assume_role_policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Action = "sts:AssumeRole"
        Effect = "Allow"
        Principal = {
          Service = "lambda.amazonaws.com"
        }
      }
    ]
  })
}

# 4. IAM Policy untuk Logging, SQS Read/Delete, dan VPC Access
resource "aws_iam_policy" "lambda_sqs_policy" {
  name = "lambda_sqs_execution_policy"

  policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Effect = "Allow"
        Action = [
          "logs:CreateLogGroup",
          "logs:CreateLogStream",
          "logs:PutLogEvents"
        ]
        Resource = "arn:aws:logs:*:*:*"
      },
      {
        Effect = "Allow"
        Action = [
          "sqs:ReceiveMessage",
          "sqs:DeleteMessage",
          "sqs:GetQueueAttributes"
        ],
        Resource = aws_sqs_queue.main_queue.arn
      }
    ]
  })
}

resource "aws_iam_role_policy_attachment" "attach_sqs_policy" {
  role       = aws_iam_role.lambda_exec_role.name
  policy_arn = aws_iam_policy.lambda_sqs_policy.arn
}

# 5. Paket Kode Lambda (Asumsi file zip sudah tersedia)
resource "aws_lambda_function" "order_processor" {
  filename      = "lambda_function.zip"
  function_name = "OrderProcessorFunction"
  role          = aws_iam_role.lambda_exec_role.arn
  handler       = "index.handler"
  runtime       = "nodejs20.x"
  timeout       = 25
  memory_size   = 512

  environment {
    variables = {
      ENV = "production"
    }
  }
}

# 6. Event Source Mapping (Hubungkan SQS ke Lambda)
resource "aws_lambda_event_source_mapping" "sqs_trigger" {
  event_source_arn                   = aws_sqs_queue.main_queue.arn
  function_name                      = aws_lambda_function.order_processor.arn
  batch_size                         = 10
  maximum_batch_window_in_seconds    = 5
  function_response_types            = ["ReportBatchItemFailures"]
}

B. Kode Handler AWS Lambda (index.js)

/**
 * AWS Lambda Handler untuk memproses pesan dari SQS secara batch.
 * Menggunakan pendekatan Partial Batch Response (ReportBatchItemFailures)
 * agar pesan yang gagal saja yang dikembalikan ke antrian.
 */
exports.handler = async (event) => {
    let batchItemFailures = [];

    for (const record of event.Records) {
        try {
            console.log(`Memproses Pesan ID: ${record.messageId}`);
            const payload = JSON.parse(record.body);
            
            // Simulasi pemrosesan bisnis inti (misal: simpan ke MySQL / panggil API pembayaran)
            await processBusinessLogic(payload);
            
            console.log(`Sukses memproses pesan: ${record.messageId}`);
        } catch (error) {
            console.error(`Gagal memproses pesan ${record.messageId}:`, error.message);
            // Catat ID pesan yang gagal dalam batch
            batchItemFailures.push({ itemIdentifier: record.messageId });
        }
    }

    return { batchItemFailures };
};

async function processBusinessLogic(data) {
    // Validasi sederhana payload pesanan
    if (!data.orderId || !data.amount) {
        throw new Error("Payload tidak valid: orderId dan amount wajib diisi.");
    }
    
    // Simulasi latensi database
    await new Promise(resolve => setTimeout(resolve, 100));
    return true;
}

6. Bedah Kode & Penjelasan Detail Baris Kunci

Mari kita bedah beberapa komponen paling krusial dari implementasi di atas untuk memahami desain tingkat lanjut:

  1. Redrive Policy & DLQ (maxReceiveCount = 3): Parameter ini menentukan bahwa jika sebuah pesan gagal diproses sebanyak 3 kali (misalnya karena gangguan koneksi database temporer atau bug logika), SQS akan secara otomatis memindahkan pesan tersebut ke Dead Letter Queue (order-processing-dlq). Hal ini mencegah poison pill (pesan korup yang terus-menerus gagal) memblokir antrian utama tanpa batas waktu (infinite retry loop).

  2. Long Polling (receive_wait_time_seconds = 20): Mengaktifkan long polling pada SQS mengurangi jumlah empty receives (panggilan API yang menghasilkan antrian kosong), yang secara drastis memangkas biaya operasional AWS dan mempercepat respons ketika pesan baru masuk.

  3. Partial Batch Response (ReportBatchItemFailures): Secara default, jika satu pesan saja gagal dalam sebuah batch berisi 10 pesan, Lambda akan menganggap seluruh batch gagal dan mencoba ulang seluruh 10 pesan tersebut. Dengan mengaktifkan function_response_types = ["ReportBatchItemFailures"] dan mengembalikan array batchItemFailures, AWS Lambda hanya akan menghapus pesan yang sukses dan mengembalikan pesan yang benar-benar gagal ke antrian SQS.

7. Skenario Produksi & Studi Kasus Dunia Nyata

Studi Kasus: Flash Sale E-Commerce dengan 50.000 Request/Detik

Pada saat acara Flash Sale tengah malam, sebuah platform e-commerce menerima 50.000 transaksi pesanan per detik. Sistem dirancang dengan alur berikut:

  • Gateway Layer: Nginx di-deploy pada cluster AWS EC2 di depan, bertindak sebagai SSL Termination dan Rate Limiter.
  • Producer App: Aplikasi Go (Golang) menerima request HTTP POST dari klien, melakukan sanitasi data kilat, memasukkan payload ke SQS Standard Queue, dan langsung mengembalikan HTTP 202 Accepted ke pengguna dalam waktu 15 milidetik.
  • Queue Absorber: SQS menampung lonjakan jutaan pesan tersebut ke dalam buffer internal tanpa menurunkan performa.
  • Consumer Engine: AWS Lambda dikonfigurasi dengan Concurrency Limit yang disesuaikan dengan kapasitas maksimal koneksi database RDS MySQL (misalnya dibatasi maksimum 500 concurrent executions). Lambda membaca batch pesan dan melakukan bulk insert atau transaksi terisolasi ke database.

[!TIP] Gunakan SQS Standard untuk throughput yang hampir tak terbatas jika urutan pemrosesan pesan tidak mutlak diperlukan. Jika urutan mutlak diperlukan (misalnya mutasi saldo akun bank), gunakan SQS FIFO dengan Message Group ID.

8. Common Pitfalls, Anti-Patterns & Solusi

  1. Anti-Pattern: Mengabaikan Dead Letter Queue (DLQ)

    • Masalah: Tanpa DLQ, pesan yang gagal diproses karena kesalahan sintaks akan terus menerus dicoba ulang tanpa batas, menghabiskan kuota eksekusi Lambda dan memenuhi log CloudWatch.
    • Solusi: Selalu pasang DLQ dan atur alarm CloudWatch pada metrik ApproximateNumberOfMessagesVisible di DLQ agar tim DevOps langsung mendapatkan notifikasi PagerDuty/Slack jika ada pesan yang masuk ke DLQ.
  2. Pitfall: Koneksi Database Habis (Database Connection Exhaustion)

    • Masalah: Karena Lambda melakukan scaling secara masif (misalnya 1.000 instance berjalan bersamaan), setiap instance Lambda yang baru diinisialisasi akan membuka koneksi baru ke MySQL, yang langsung melampaui batas max_connections database.
    • Solusi: Gunakan AWS RDS Proxy di antara Lambda dan database untuk melakukan connection pooling secara efisien.
  3. Anti-Pattern: Menempatkan Inisialisasi Klien di Dalam Handler Lambda

    • Masalah: Membuat koneksi database atau memuat konfigurasi di dalam fungsi handler (exports.handler) akan dieksekusi pada setiap pemanggilan, memperlambat latensi (cold start).
    • Solusi: Inisialisasi klien SDK, koneksi database, atau variabel global di luar fungsi handler agar dapat digunakan kembali pada pemanggilan berikutnya (warm start).

9. Benchmark, Metrik Kinerja & Tuning Performa

Untuk menguji ketahanan sistem yang telah dibangun, Anda dapat menggunakan alat pengujian beban seperti k6 atau Apache Bench (ab) untuk menghujani API Producer.

Parameter Tuning Penting:

  • Batch Size: Mulai dari 5 hingga 10 untuk beban standar. Jika payload sangat kecil dan pemrosesan sangat cepat (misalnya hanya menulis ke log), tingkatkan batch size hingga 10 untuk efisiensi biaya komputasi Lambda.
  • Memory Allocation: Jangan pelit mengalokasikan memori pada AWS Lambda. Di arsitektur AWS Nitro saat ini, alokasi memori berbanding lurus dengan alokasi daya vCPU. Meningkatkan memori dari 128MB ke 512MB sering kali justru menurunkan total durasi eksekusi secara drastis, sehingga biaya total eksekusi menjadi lebih murah.
  • Reserved Concurrency: Batasi jumlah maksimum eksekusi konkuren Lambda jika database hilir Anda memiliki kapasitas terbatas, guna mencegah Cascading Failure.

10. Checklist Penerapan Produksi & Kesimpulan

Sebelum merilis arsitektur Serverless Event-Driven ini ke lingkungan produksi, pastikan Anda telah mencentang seluruh daftar periksa berikut:

  • SQS Utama telah dikonfigurasi dengan Dead Letter Queue (DLQ).
  • Kebijakan IAM menerapkan prinsip Least Privilege (hanya izin SQS receive/delete yang diperlukan).
  • AWS RDS Proxy atau Connection Pooler telah diaktifkan untuk mencegah lonjakan koneksi database.
  • CloudWatch Alarms telah dipasang untuk memantau metrik ApproximateAgeOfOldestMessage di SQS dan Errors di Lambda.
  • Timeout Lambda telah disesuaikan dengan durasi maksimum pemrosesan bisnis (disarankan tidak lebih dari 30 detik untuk operasi standar).
  • Pengujian beban (load testing) telah dilakukan untuk memastikan perilaku sistem saat terjadi lonjakan trafik.

Dengan merancang arsitektur berbasis event menggunakan AWS SQS dan Lambda secara tepat, Anda tidak hanya mengeliminasi beban manajemen infrastruktur server fisik, tetapi juga membangun sistem yang sangat resilien, tahan banting, dan efisien dari segi biaya operasional.

🏷️ Tags: #Nginx #High Concurrency #Performance #Sysadmin #Web Server