Skala: dari satu container ke banyak
Menambah container hanya membantu kalau aplikasimu benar-benar stateless dan kemacetannya memang di CPU aplikasi. Kalau tidak, kamu cuma memindahkan beban ke database dan membuat semuanya lebih buruk.
Intisari
- Stateless adalah syarat, bukan bonus. Sesi, cache, dan berkas unggahan harus di luar container.
- Skala horizontal melipatgandakan koneksi database โ hitung ulang
MaxOpenConnsuntuk jumlah task maksimum (Fase 4). - Kemacetan di database tidak diselesaikan dengan menambah task; ia diperburuk.
- Ukur p95/p99, bukan rata-rata, dan skalakan berdasarkan metrik yang mewakili beban sungguhan.
- Urutan yang benar: perbaiki kueri โ CDN โ cache โ baru tambah task.
Daftar periksa stateless
| Keadaan | Kalau di dalam container | Harus di |
|---|---|---|
| Sesi | Pengguna ter-logout acak | Redis (Fase 6) |
| Cache | Hit rate turun, jawaban tidak konsisten | Redis (kecuali sengaja berlapis) |
| Berkas unggahan | Hilang saat task berganti | S3 |
| Rate limit | Batas efektif ร jumlah task | Redis |
| Job terjadwal | Berjalan N kali | Satu service khusus, atau lock terdistribusi |
| Antrean di memori | Pekerjaan hilang saat deploy | SQS / Postgres (Fase 5) |
| Log ke berkas | Hilang saat task berhenti | stdout โ CloudWatch |
| Penghitung di memori | Angka berbeda per task | Metrik teragregasi |
Uji kelayakan sebelum menyalakan autoscaling: jalankan dua instans aplikasimu di laptop di port berbeda, taruh di belakang proksi sederhana, dan pakai selama satu jam. Setiap perilaku aneh yang muncul โ logout mendadak, hitungan yang tidak konsisten, unggahan yang hilang โ adalah keadaan yang masih tertinggal di dalam proses.
Vertikal versus horizontal
| Gejala | Yang membantu |
|---|---|
| CPU aplikasi mentok, database santai | Tambah task |
| Memori mentok | Task lebih besar, atau kurangi alokasi |
| Database CPU mentok | Perbaiki kueri, tambah index, read replica โ bukan tambah task |
| Menunggu I/O dari API luar | Concurrency + timeout; task tidak membantu |
| Pool database antre | Kueri lebih cepat, atau pool lebih besar โ hati-hati batas RDS |
| Satu endpoint lambat | Perbaiki endpoint itu |
Menambah task saat database yang jadi kemacetan memperburuk keadaan. Sepuluh task berarti sepuluh kali koneksi dan sepuluh kali kueri masuk ke database yang sudah kewalahan โ dan p95-nya makin buruk, bukan membaik. Selalu periksa dulu di mana kemacetannya sebenarnya.
Aritmetika yang harus dihitung ulang
Setiap task menambah:
MaxOpenConns koneksi ke database โ batasi (Fase 4)
MaxIdleConnsPerHost koneksi ke tiap API โ hormati rate limit mereka
1 set koneksi Redis
1 goroutine cron kalau kamu menjalankannya di service web โ BAHAYA
Contoh: naik dari 4 ke 20 task
koneksi DB : 4ร20 = 80 โ 20ร20 = 400 โ melebihi batas RDS
panggilan API: kuota 1000/menit dibagi 20, bukan 4
job cron : berjalan 20 kali per jadwal โ duplikasi email, invoice
Jalankan penjadwal di service ECS-nya sendiri dengan desiredCount: 1, atau pakai
EventBridge Scheduler yang memanggil satu run-task. Menjalankan cron di dalam service web adalah bug
yang tidak terlihat sampai hari pertama autoscaling menaikkan jumlah task.
Autoscaling berdasarkan metrik yang benar
| Metrik pemicu | Cocok kalau |
|---|---|
| CPU rata-rata (target ~60%) | Beban memang CPU-bound โ titik awal yang wajar |
| Permintaan per target (ALB) | Lebih baik untuk beban I/O-bound |
| p95 latensi | Bagus, tapi bereaksi terlambat |
| Kedalaman antrean SQS | Yang benar untuk worker |
| Memori | Hampir tidak pernah โ memori tinggi biasanya kebocoran, bukan beban |
Setelan yang menghindari osilasi:
scale out : cepat (1 menit cooldown) โ telat menambah berarti pengguna menunggu
scale in : lambat (5โ10 menit cooldown) โ terlalu cepat mengurangi = naik-turun terus
minimum : โฅ 2 task, di AZ berbeda โ satu task berarti tidak ada redundansi
maksimum : dibatasi kapasitas DATABASE, bukan oleh anggaran saja
Menguji beban dengan benar
# Ramai sederhana
hey -z 60s -c 50 https://staging.contoh.id/produk
# Skenario berurutan mendekati perilaku nyata
k6 run skenario.js
| Kesalahan uji beban | Akibatnya |
|---|---|
| Menguji satu URL saja | Semuanya kena cache; hasilnya tidak berarti |
| Menguji dengan 10 baris data | Semua kueri cepat; index tidak teruji |
| Menguji dari laptop | Jaringanmu yang jadi batas, bukan aplikasinya |
| Melihat rata-rata | Menyembunyikan pengguna yang menunggu lama |
| Tanpa tahap pemanasan | Pool dan cache masih dingin |
| Menguji di lingkungan yang lebih kecil | Hasilnya tidak bisa diekstrapolasi |
Yang dicari dari uji beban bukan angka maksimum, melainkan titik belok: beban di mana p95 mulai naik lebih cepat daripada trafik. Di bawah titik itu sistemmu sehat; di atasnya ia sedang mengantre. Angka itulah yang jadi dasar menyetel batas autoscaling.
Urutan yang benar
- Ukur. pprof, trace, dan
pg_stat_statementsโ jangan menebak. - Perbaiki kueri. Index dan N+1 hampir selalu pengungkit terbesar (Fase 4).
- Pindahkan ke CDN. Untuk halaman publik, ini mengalahkan semuanya.
- Cache. Redis untuk yang mahal dan sering dibaca.
- Pindahkan pekerjaan ke antrean. Keluarkan dari siklus permintaan.
- Baru tambah task โ setelah stateless dan setelah aritmetika koneksi dihitung.
- Baru pikirkan arsitektur. Enam langkah di atas menyelesaikan sebagian besar kasus.
Latihan: jalankan dua instans aplikasimu di belakang satu proksi, lalu login dan klik-klik
selama beberapa menit. Catat setiap perilaku aneh โ itu daftar keadaan yang masih tersimpan di dalam
proses. Lalu jalankan hey -z 60s -c 50 dengan kenaikan konkurensi bertahap dan temukan titik
belok p95-mu.
Rangkuman ini sengaja dipangkas ke bagian yang dipakai di roadmap. Buka sumber aslinya saat kamu butuh detail lengkap atau referensi parameter.