L
Cloud Architecture & Serverless • Literally Web ID

Arsitektur Serverless Berbasis Event-Driven di AWS Lambda

⏱️ 18 menit baca • 📅 14 Oct 2026 • 👁️ 1 views
Arsitektur Serverless Berbasis Event-Driven di AWS Lambda

1. Konteks Industri & Analisis Akar Masalah

Dalam lanskap arsitektur web modern, skalabilitas elastis dan efisiensi biaya operasional adalah dua metrik utama yang menentukan keberhasilan sistem skala besar. Tradisional infrastruktur berbasis monolitik atau bahkan mikroservis berbasis container yang berjalan di atas instance virtual machine (seperti AWS EC2 atau Droplet DigitalOcean) sering kali menghadapi tantangan mendasar: pemborosan sumber daya akibat idle capacity dan kerentanan terhadap lonjakan traffic mendadak (traffic spikes).

Sebelum adopsi arsitektur event-driven berbasis serverless, tim infrastruktur harus melakukan provisioning server web (Nginx/Apache), mengatur proses manajemen proses PHP-FPM, Node.js, atau Go, serta mengonfigurasi load balancer. Ketika terjadi lonjakan traffic—misalnya saat flash sale e-commerce atau pemrosesan batch log malam hari—server sering kali mengalami resource exhaustion (CPU throttling, memory leaks, atau koneksi database yang jenuh). Sebaliknya, pada jam sepi, infrastruktur tersebut tetap memakan biaya penuh meskipun tidak ada permintaan yang masuk.

Analisis akar masalah menunjukkan bahwa keterikatan antara siklus hidup aplikasi dengan siklus hidup server fisik/virtual adalah sumber utama inefisiensi. Arsitektur serverless (AWS Lambda) yang dikombinasikan dengan pola event-driven (Amazon SQS dan Amazon EventBridge) memutus keterikatan ini. Komputasi hanya terjadi saat ada event nyata yang masuk. Namun, transisi ini membawa tantangan baru: latensi cold start, kompleksitas manajemen state secara terdistribusi, pengelolaan dead letter queues (DLQ) untuk penanganan kegagalan asinkron, serta penerapan model keamanan least privilege yang ketat pada level IAM (Identity and Access Management).

Kondisi Sebelum (Monolitik / VM) Kondisi Sesudah (Serverless Event-Driven)
Biaya tetap (fixed cost) meskipun idle Bayar per eksekusi milidetik (pay-as-you-go)
Skalabilitas manual atau auto-scaling group yang lambat (menit) Skalabilitas instan otomatis dalam hitungan milidetik
Manajemen OS, patch keamanan, dan web server manual Fully managed oleh cloud provider (zero server maintenance)
Risiko connection pool exhaustion pada database Membutuhkan pola koneksi asinkron dan pembatasan konkurensi

2. Konsep Inti & Deep Dive Arsitektur

Arsitektur Event-Driven (EDA) memisahkan komponen penghasil event (event producer) dari komponen pemroses event (event consumer) menggunakan event router atau message broker. Dalam ekosistem AWS, komponen ini direpresentasikan oleh kombinasi Amazon EventBridge, Amazon SQS (Simple Queue Service), dan AWS Lambda.

Di balik layar, ketika event terjadi (misalnya, unggahan file ke S3 atau klik tombol di frontend yang memicu API Gateway), event dikirimkan ke EventBridge atau langsung masuk ke SQS Queue. AWS Lambda kemudian melakukan polling terhadap SQS atau di-trigger langsung oleh EventBridge untuk mengeksekusi kode fungsi secara paralel.

+------------------+       +-------------------+       +------------------+
|  Event Producer  | ----> |  Amazon SQS /     | ----> |    AWS Lambda    |
| (API/S3/Webhook) |       |  EventBridge      |       | (Async Execution)|
+------------------+       +-------------------+       +------------------+
                                                                |
                                                                v
                                                       +------------------+
                                                       | Database / Cache |
                                                       | (Aurora / Redis) |
                                                       +------------------+

Alur eksekusi asinkron memastikan bahwa event producer tidak harus menunggu proses bisnis selesai (non-blocking). Jika fungsi Lambda gagal mengeksekusi event, SQS secara otomatis akan memasukkan kembali pesan tersebut ke antrean berdasarkan parameter VisibilityTimeout, atau memindahkannya ke Dead Letter Queue (DLQ) setelah batas maxReceiveCount terlampaui.


3. Perbandingan Komparatif / Analisis Pendekatan

Memilih antara arsitektur tradisional berbasis server (Nginx + Node.js/Go di EC2) dan arsitektur Serverless Event-Driven memerlukan pemahaman mendalam tentang trade-off performa dan operasional.

Parameter / Metrik EC2 / VM + Nginx + Node.js AWS Lambda + SQS + EventBridge
CPU & Memory Dedicated, konstan, dibayar per jam Dinamis, diatur per fungsi (128MB - 10GB)
Latency (First Request) Sangat rendah (jika warm), stabil Tinggi saat Cold Start, rendah saat Warm
Scalability Terbatas pada kapasitas instance (vertikal/horizontal) Otomatis tak terbatas (dibatasi account concurrency)
Maintenance OS patching, tuning Nginx, SSL cert renewal Zero management, otomatis di-handle AWS
Cost Efficiency Buruk untuk traffic fluktuatif (mahal di idle) Sangat tinggi (biaya 0 jika tidak ada eksekusi)

[!WARNING] Jangan menggunakan AWS Lambda untuk beban kerja komputasi real-time yang membutuhkan koneksi persisten jangka panjang (seperti server WebSocket tradisional), karena batasan maksimum timeout Lambda adalah 15 menit.


4. Prasyarat Sistem & Persiapan Lingkungan

Sebelum membangun infrastruktur ini, pastikan Anda telah menyiapkan perangkat dan akses berikut di lingkungan lokal dan AWS:

  1. AWS CLI (Versi 2.x ke atas) yang telah dikonfigurasi dengan kredensial administrator atau power user.
  2. Terraform (Versi 1.5+) atau AWS CDK untuk Infrastructure as Code (IaC).
  3. Node.js 20.x atau Go 1.22+ sebagai runtime bahasa pemrograman untuk AWS Lambda.
  4. jq utility untuk memparsing JSON di terminal.

Verifikasi instalasi AWS CLI:

aws --version
aws sts get-caller-identity

5. Panduan Implementasi Langkah demi Langkah

Berikut adalah implementasi lengkap menggunakan konfigurasi Terraform untuk membangun arsitektur Event-Driven: SQS Queue -> AWS Lambda -> Logging/Database.

Buat direktori proyek dan file main.tf:

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

provider "aws" {
  region = "us-east-1"
}

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

# 2. Utama SQS Queue dengan integrasi DLQ
resource "aws_sqs_queue" "main_queue" {
  name                       = "order-processing-queue"
  visibility_timeout_seconds = 30
  message_retention_seconds  = 345600 # 4 hari
  redrive_policy = jsonencode({
    deadLetterTargetArn = aws_sqs_queue.dlq.arn
    maxReceiveCount     = 3
  })
}

# 3. IAM Role untuk Lambda Execution
resource "aws_iam_role" "lambda_exec" {
  name = "order_lambda_exec_role"

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

# 4. IAM Policy untuk akses SQS dan CloudWatch Logs
resource "aws_iam_policy" "lambda_sqs_policy" {
  name = "lambda_sqs_policy"
  policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Effect = "Allow"
        Action = [
          "sqs:ReceiveMessage",
          "sqs:DeleteMessage",
          "sqs:GetQueueAttributes"
        ]
        Resource = aws_sqs_queue.main_queue.arn
      },
      {
        Effect = "Allow"
        Action = [
          "logs:CreateLogGroup",
          "logs:CreateLogStream",
          "logs:PutLogEvents"
        ]
        Resource = "arn:aws:logs:*:*:*"
      }
    ]
  })
}

resource "aws_iam_role_policy_attachment" "attach_sqs" {
  role       = aws_iam_role.lambda_exec.name
  policy_arn = aws_iam_policy.lambda_sqs_policy.arn
}

# 5. Paket Kode Lambda (Node.js)
data "archive_file" "lambda_zip" {
  type        = "zip"
  source_dir  = "${path.module}/lambda"
  output_path = "${path.module}/lambda.zip"
}

resource "aws_lambda_function" "order_processor" {
  filename         = data.archive_file.lambda_zip.output_path
  function_name    = "OrderProcessorFunction"
  role             = aws_iam_role.lambda_exec.arn
  handler          = "index.handler"
  source_code_hash = data.archive_file.lambda_zip.output_base64sha256
  runtime          = "nodejs20.x"
  timeout          = 15
  memory_size      = 256
}

# 6. Event Source Mapping (Penghubung 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
}

output "queue_url" {
  value = aws_sqs_queue.main_queue.url
}

Buat folder lambda/ dan file lambda/index.js:

exports.handler = async (event) => {
    console.log("Menerima batch pesan SQS:", JSON.stringify(event, null, 2));
    
    for (const record of event.Records) {
        try {
            const messageBody = JSON.parse(record.body);
            console.log(`Memproses order ID: ${messageBody.orderId}`);
            
            // Simulasi proses bisnis (misal: simpan ke database / panggil payment gateway)
            if (messageBody.fail === true) {
                throw new Error("Simulasi kegagalan sistem pembayaran");
            }
            
        } catch (error) {
            console.error(`Gagal memproses pesan ${record.messageId}:`, error.message);
            // Melempar error agar SQS melakukan retry atau masuk ke DLQ
            throw error;
        }
    }
    
    return { status: "Success", processedRecords: event.Records.length };
};

Terapkan infrastruktur menggunakan Terraform:

terraform init
terraform apply -auto-approve

6. Bedah Kode & Penjelasan Detail Baris Kunci

  • visibility_timeout_seconds = 30: Parameter krusial pada SQS. Mengatur berapa lama pesan disembunyikan dari antrean setelah diambil oleh Lambda, agar tidak diproses ulang oleh worker lain. Nilai ini harus lebih besar dari durasi maksimum eksekusi fungsi Lambda.
  • redrive_policy: Mekanisme pengaman (circuit breaker). Jika pesan gagal diproses sebanyak maxReceiveCount (3 kali), pesan dipindahkan secara otomatis ke Dead Letter Queue (aws_sqs_queue.dlq) untuk diinvestigasi manual.
  • batch_size = 10: Menginstruksikan AWS Lambda untuk mengambil hingga 10 pesan sekaligus dari SQS dalam satu pemanggilan fungsi, menghemat jumlah eksekusi dan meningkatkan throughput.

7. Skenario Produksi & Studi Kasus Dunia Nyata

Dalam skenario Flash Sale dengan 50.000 pesanan per menit, arsitektur tradisional akan mengalami kegagalan koneksi database karena lonjakan thread secara simultan.

Dengan arsitektur Serverless Event-Driven:

  1. Gateway API menerima HTTP Request, langsung menulis payload ke Amazon SQS, dan mengembalikan status 202 Accepted ke klien dalam waktu < 20 milidetik.
  2. SQS bertindak sebagai penyerap kejut (shock absorber), menampung seluruh lonjakan beban tanpa membuat server down.
  3. AWS Lambda melakukan auto-scaling secara instan membaca SQS, memproses pesanan secara paralel, dan menulis ke Aurora Serverless v2 dengan koneksi yang dikelola oleh AWS RDS Proxy untuk menghindari kehabisan koneksi (connection pool exhaustion).

8. Common Pitfalls, Anti-Patterns & Solusi

  1. Anti-Pattern: Mengabaikan Cold Start pada VPC
    • Masalah: Menghubungkan fungsi Lambda ke VPC privat tradisional tanpa konfigurasi Hyperplane ENI dapat menyebabkan cold start melonjak hingga 5-10 detik.
    • Solusi: Pastikan runtime AWS Lambda menggunakan arsitektur modern berbasis AWS Nitro yang secara otomatis mengelola ENI caching, atau gunakan Provisioned Concurrency untuk fungsi kritikal.
  2. Kesalahan Fatal: Tidak Menangani Partial Batch Failures dari SQS
    • Masalah: Jika 1 dari 10 pesan dalam batch gagal diproses dan Lambda melempar exception, seluruh 10 pesan akan di-retry oleh SQS, menyebabkan duplikasi proses.
    • Solusi: Aktifkan konfigurasi ReportBatchItemFailures pada event source mapping dan kembalikan array ID pesan yang gagal saja.

9. Benchmark, Metrik Kinerja & Tuning Performa

Pengujian beban (load testing) dapat dilakukan menggunakan tool open-source seperti k6 untuk mengirim ribuan HTTP Request ke API Gateway yang memicu SQS.

Contoh skrip k6 (load-test.js):

import http from 'k6/http';
import { check, sleep } from 'k6';

export const options = {
    stages: [
        { duration: '1m', target: 500 }, // Naikkan ke 500 virtual users dalam 1 menit
        { duration: '3m', target: 500 }, // Pertahankan beban
        { duration: '1m', target: 0 },   // Turunkan kembali
    ],
};

export default function () {
    const url = 'https://api.yourdomain.com/orders';
    const payload = JSON.stringify({
        orderId: `ord-${Math.random()}`,
        items: [{ sku: 'PROD-A', qty: 2 }],
    });

    const params = { headers: { 'Content-Type': 'application/json' } };
    const res = http.post(url, payload, params);
    
    check(res, { 'status is 202': (r) => r.status === 202 });
    sleep(1);
}

Tuning lanjutan:

  • Gunakan arsitektur ARM64 (AWS Graviton2) untuk fungsi Lambda guna mendapatkan peningkatan rasio harga-performa hingga 34% dibanding x86_64.
  • Sesuaikan alokasi memori Lambda (minimal 512MB atau 1024MB) karena alokasi memori berbanding lurus dengan alokasi daya CPU di AWS Lambda.

10. Checklist Penerapan Produksi & Kesimpulan

  • Pastikan prinsip Least Privilege diterapkan pada setiap IAM Role Lambda.
  • Konfigurasikan Dead Letter Queue (DLQ) atau SqsQueueDestination untuk menangani poison messages.
  • Aktifkan CloudWatch Alarms untuk memantau metrik Errors, Throttles, dan ApproximateNumberOfMessagesVisible pada SQS.
  • Gunakan AWS X-Ray untuk distributed tracing guna melacak alur event lintas layanan.

Dengan menerapkan arsitektur serverless berbasis event-driven menggunakan AWS Lambda, SQS, dan EventBridge secara tepat, sistem web Anda tidak hanya mampu diskalakan secara elastis tanpa batas, tetapi juga memiliki ketahanan operasional tinggi dengan biaya infrastruktur yang sangat efisien.

🏷️ Tags: #Aws #Serverless #Sqs #Lambda #Eventbridge