Closed Model vs Open Model — Konsep Paling Penting di Tingkat Lanjut
VU mengirim request -> menunggu balasan
-> sleep -> mengirim lagi
Bila server MELAMBAT,
VU otomatis mengirim LEBIH SEDIKIT request.
Beban yang sampai ke server ikut turun.Iterasi baru dimulai setiap X milidetik,
tidak peduli iterasi sebelumnya selesai atau belum.
Bila server MELAMBAT,
laju request TETAP.
Antrean menumpuk — persis seperti dunia nyata.Menggunakan constant-vus untuk menjawab pertanyaan "apakah sistem kami sanggup 500 request/detik?" adalah kesalahan konseptual, bukan sekadar kesalahan teknis.
Alasannya: dalam closed model, ketika server mulai melambat, VU Anda otomatis memperlambat diri (karena menunggu balasan). Server jadi "terlindungi" dari beban penuh dan hasilnya terlihat baik-baik saja. Fenomena ini disebut coordinated omission — Anda kehilangan justru momen terburuknya.
Yang benar: untuk target throughput, gunakan constant-arrival-rate atau ramping-arrival-rate.
Tujuh Executor k6
| Executor | Model | Mengendalikan | Dipakai untuk |
|---|---|---|---|
shared-iterations | Tertutup | Total iterasi dibagi ke semua VU | Menghabiskan sejumlah data uji |
per-vu-iterations | Tertutup | Iterasi per VU | Tiap VU melakukan N tugas |
constant-vus | Tertutup | Jumlah VU tetap | Simulasi N pengguna bersamaan |
ramping-vus | Tertutup | VU naik-turun bertahap | Load & stress test umum |
constant-arrival-rate | Terbuka | Iterasi per detik tetap | Menguji target throughput/RPS |
ramping-arrival-rate | Terbuka | RPS naik bertahap | Breakpoint test |
externally-controlled | Tertutup | Dikendalikan lewat API saat berjalan | Eksplorasi manual |
Menulis Skenario
export const options = {
scenarios: {
// Skenario 1: beban dasar yang konstan
pengunjung_biasa: {
executor: 'constant-vus',
vus: 50,
duration: '10m',
exec: 'jelajahKatalog', // nama fungsi yang dijalankan
tags: { tipe: 'browsing' },
},
// Skenario 2: transaksi dengan laju terkendali, dimulai belakangan
checkout: {
executor: 'constant-arrival-rate',
rate: 30, // 30 iterasi …
timeUnit: '1s', // … per detik
duration: '10m',
preAllocatedVUs: 50, // VU disiapkan di awal
maxVUs: 200, // batas atas bila server melambat
startTime: '2m', // mulai 2 menit setelah tes dimulai
exec: 'lakukanCheckout',
tags: { tipe: 'transaksi' },
},
// Skenario 3: lonjakan mendadak di tengah tes
flash_sale: {
executor: 'ramping-arrival-rate',
startRate: 10,
timeUnit: '1s',
preAllocatedVUs: 100,
maxVUs: 1000,
startTime: '5m',
stages: [
{ duration: '30s', target: 500 }, // 10 -> 500 rps
{ duration: '2m', target: 500 },
{ duration: '30s', target: 10 },
],
exec: 'serbuFlashSale',
},
},
};
// Setiap skenario memanggil fungsi yang berbeda
export function jelajahKatalog() { /* … */ }
export function lakukanCheckout() { /* … */ }
export function serbuFlashSale() { /* … */ }preAllocatedVUs vs maxVUs — Wajib Dipahami
Pada executor arrival-rate, k6 butuh VU untuk mengeksekusi iterasi. Bila semua VU sedang sibuk menunggu respons, iterasi baru tidak bisa dimulai dan tercatat sebagai dropped_iterations.
preAllocatedVUs— VU yang disiapkan sebelum tes mulai. Menyiapkan VU butuh waktu, jadi jangan terlalu sedikit.maxVUs— batas atas bila k6 perlu menambah VU saat berjalan (karena server melambat).
VU dibutuhkan ≈ target_rps × durasi_iterasi_detik
Contoh: target 100 rps, satu iterasi memakan 2 detik (termasuk sleep) → butuh ± 200 VU. Set preAllocatedVUs: 200 dan maxVUs: 400 untuk memberi ruang bila server melambat 2×.