Deploy aman untuk worker pool dengan jobserver bukan sekadar memastikan proses baru hidup, tetapi memastikan total konkurensi sistem tetap sesuai kapasitas nyata host. Pada sistem yang memakai pola jobserver seperti Robust Jobserver, kegagalan paling berbahaya saat deploy biasanya bukan proses crash, melainkan oversubscription: worker baru ikut menarik slot, worker lama belum benar-benar berhenti, lalu CPU, memori, atau I/O melonjak sampai antrean justru makin lambat.
Solusi produksinya adalah menggabungkan beberapa lapisan: distribusi slot yang benar, drain worker lama sebelum terminasi, health check yang memverifikasi kemampuan mengambil dan melepas token secara benar, metrik yang fokus pada effective concurrency dan backlog, serta rollback yang bisa menghentikan ekspansi concurrency dalam hitungan menit. Artikel ini menggunakan Robust Jobserver sebagai konteks teknis, tetapi fokus utamanya adalah praktik operasional di produksi.
Memahami risiko oversubscription saat deploy
Pada worker pool biasa, menambah replika sering dianggap aman karena antrean akan terbagi. Pada arsitektur berbasis jobserver, asumsi itu hanya aman jika semua worker menghormati sumber slot yang sama. Jika saat deploy ada proses baru yang:
- memulai worker sebelum koneksi ke jobserver siap,
- menggunakan fallback concurrency lokal yang tidak dibatasi,
- gagal mewariskan atau membaca handle jobserver dengan benar,
- atau worker lama belum melepas token saat shutdown,
maka total eksekusi paralel bisa melebihi kapasitas yang direncanakan. Dampaknya sering muncul sebagai gejala yang tampak saling bertentangan: jumlah worker aktif naik, tetapi throughput turun; antrean menumpuk; latensi job memanjang; host kehabisan CPU, RAM, file descriptor, atau bandwidth disk.
Secara operasional, anggap jobserver sebagai sumber kebenaran tunggal untuk izin eksekusi. Deploy aman berarti memastikan tidak ada jalur eksekusi yang menghindari mekanisme itu.
Prinsip desain deploy aman untuk worker pool dengan jobserver
1. Slot harus terpusat, bukan direplikasi per instance
Jika setiap instance worker membuat limiter sendiri, Anda tidak lagi punya pool global. Dengan jobserver, token mewakili kapasitas bersama. Worker hanya boleh menjalankan job setelah berhasil memperoleh token, dan harus selalu mengembalikannya setelah selesai, termasuk saat terjadi error.
Catatan: Dalam konteks produksi, masalah utama biasanya bukan algoritme queue, melainkan konsistensi lifecycle token: kapan diambil, kapan dikembalikan, dan apa yang terjadi saat proses mati di tengah pekerjaan.
2. Startup harus fail-closed
Jika worker gagal terhubung ke jobserver, perilaku paling aman adalah tidak memproses job sama sekali. Jangan gunakan fallback seperti "jalan dengan concurrency default" saat jobserver tidak tersedia, kecuali Anda benar-benar memahami dampaknya dan punya pembatas keras di level lain.
Prinsip fail-closed ini sangat penting saat deploy, karena bug konfigurasi kecil—misalnya variabel lingkungan untuk endpoint jobserver salah—bisa membuat rilis baru berjalan tanpa batas concurrency global.
3. Shutdown harus drain, bukan kill langsung
Sebelum instance lama dihentikan, lakukan mode drain:
- hentikan pengambilan job baru,
- biarkan job aktif selesai atau timeout dengan aman,
- pastikan semua token dikembalikan,
- baru terminasi proses.
Jika orchestrator mengirim sinyal terminasi terlalu cepat, worker lama bisa mati sambil masih memegang token atau meninggalkan pekerjaan setengah jalan. Itu bisa memicu dua masalah sekaligus: kapasitas logis jobserver salah, dan antrean butuh retry yang menambah beban.
4. Deploy bertahap lebih aman daripada ganti serentak
Rolling deploy dengan batch kecil memudahkan deteksi anomali concurrency. Kalau semua worker diganti sekaligus, lonjakan akibat bug token handling akan terjadi pada skala penuh sebelum tim sempat bereaksi.
Arsitektur rilis yang direkomendasikan
Urutan deploy yang aman
- Freeze perubahan kapasitas: jangan ubah jumlah replika dan batas slot pada saat yang sama.
- Canary kecil: rilis 1 instance atau persentase kecil lebih dulu.
- Verifikasi startup: pastikan instance baru benar-benar terhubung ke jobserver dan tidak mulai bekerja tanpa token.
- Drain instance lama: hentikan pengambilan job baru pada batch yang akan diganti.
- Pantau metrik concurrency efektif: jangan hanya melihat proses hidup.
- Lanjutkan bertahap jika backlog, latensi, dan resource host tetap normal.
- Rollback cepat jika ada sinyal oversubscription atau throughput turun.
Contoh lifecycle worker
on_startup():
connect_to_jobserver_or_fail()
mark_readiness(false)
warm_dependencies()
verify_token_roundtrip()
mark_readiness(true)
worker_loop():
while not draining:
token = acquire_token()
job = fetch_job()
if job is None:
release_token(token)
sleep(backoff)
continue
try:
process(job)
finally:
release_token(token)
on_sigterm():
draining = true
mark_readiness(false)
stop_fetching_new_jobs()
wait_for_inflight_jobs_until(timeout)
exit()Contoh di atas sengaja menekankan satu hal: readiness tidak boleh aktif sebelum verifikasi akses jobserver selesai. Worker yang hanya "hidup" tetapi belum bisa mengambil dan melepas token dengan benar belum layak menerima trafik pekerjaan.
Health check yang relevan untuk jobserver
Health check standar seperti "proses hidup" terlalu dangkal untuk sistem ini. Anda butuh pemisahan yang jelas antara liveness, readiness, dan kondisi drain.
Liveness check
Tujuannya mendeteksi proses macet total. Cukup jawab sehat jika event loop utama, thread worker, atau loop polling internal masih berfungsi. Jangan hubungkan liveness langsung ke backlog queue atau beban host sesaat, karena itu bisa memicu restart berulang saat terjadi lonjakan sementara.
Readiness check
Readiness harus menjawab pertanyaan: apakah instance ini aman untuk ikut memproses job sekarang? Minimal, readiness sebaiknya memverifikasi:
- konfigurasi jobserver valid,
- koneksi ke jobserver sudah siap,
- worker tidak dalam mode drain,
- dependensi penting tersedia jika memang dibutuhkan sebelum kerja,
- startup selesai dan tidak ada kegagalan fatal pada inisialisasi pool.
Jika memungkinkan, tambahkan verifikasi ringan bahwa worker dapat melakukan operasi token yang aman, misalnya uji internal pada startup, bukan pada setiap probe agar tidak menambah beban atau mengganggu slot produksi.
Drain state check
Pada banyak insiden, masalah datang karena instance lama masih dianggap siap padahal sedang dimatikan. Karena itu, saat menerima sinyal shutdown:
- ubah readiness menjadi gagal secepat mungkin,
- tetap biarkan proses hidup selama menyelesaikan job aktif,
- ekspos metrik
draining=1atau status serupa agar operator tahu instance sedang keluar dari pool.
Metrik inti yang wajib dipantau
Untuk deploy aman untuk worker pool dengan jobserver, metrik paling penting bukan jumlah pod atau proses, tetapi hubungan antara slot, job aktif, antrean, dan resource host.
Metrik konkurensi dan slot
- Configured slot capacity: kapasitas slot global yang diharapkan.
- Acquired tokens: jumlah token yang sedang dipegang semua worker.
- In-flight jobs: jumlah job yang sedang dieksekusi.
- Workers ready vs workers draining.
- Token acquire latency: waktu tunggu untuk mendapat slot.
Hubungan antar metrik ini memberi sinyal penting. Misalnya:
- Acquired tokens jauh melebihi kapasitas yang diharapkan → indikasi oversubscription atau bug accounting.
- Workers ready naik, tetapi in-flight jobs melonjak lebih cepat dari slot global → worker kemungkinan melewati jobserver.
- Acquire latency tinggi, tetapi CPU host masih rendah → bisa jadi token bocor atau worker lama belum melepas slot.
Metrik antrean dan throughput
- Queue depth: jumlah job menunggu.
- Queue age: umur job tertua di antrean.
- Job throughput: job selesai per satuan waktu.
- Job failure/retry rate.
- Processing latency: durasi eksekusi job.
Queue depth saja sering menyesatkan. Yang lebih berguna untuk mendeteksi gangguan layanan adalah queue age dan throughput. Saat deploy menyebabkan oversubscription, throughput bisa turun meskipun jumlah worker aktif naik, karena host mengalami kontensi berat.
Metrik resource host
- CPU usage dan CPU throttling jika ada pembatas.
- Memory usage, page fault, dan tekanan OOM.
- Disk I/O latency dan saturation.
- Network error atau retransmit jika job tergantung layanan jaringan.
- Open files / file descriptor jika worker banyak membuka koneksi atau file.
Jangan melihat metrik aplikasi tanpa konteks host. Insiden oversubscription hampir selalu terlihat jelas di resource host sebelum terlihat di logika bisnis.
Alert yang benar-benar berguna saat rilis
Alert terbaik untuk skenario ini menggabungkan gejala kapasitas dan dampak layanan. Contoh sinyal yang layak dipakai:
- Queue age meningkat terus selama beberapa menit setelah deploy.
- Throughput turun signifikan setelah rilis, meskipun jumlah worker siap bertambah.
- Acquired tokens mendekati atau melebihi kapasitas yang direncanakan secara tidak wajar.
- CPU atau memory host melonjak berbarengan dengan kenaikan in-flight jobs.
- Retry rate naik segera setelah batch deploy baru aktif.
- Jumlah instance draining tidak turun dalam batas waktu yang wajar, indikasi shutdown macet.
Praktik baik: pasang anotasi deployment pada dashboard dan sistem alert. Saat grafik menunjukkan throughput turun, Anda ingin langsung tahu apakah itu bertepatan dengan rilis tertentu.
Skenario insiden: deploy sukses tetapi concurrency worker melonjak
Ini skenario yang sering membingungkan tim: deployment platform melaporkan sukses, semua pod sehat, tetapi beberapa menit kemudian antrean menumpuk dan host kehabisan resource.
Gejala awal
- Jumlah worker/pod baru naik sesuai rencana.
- Readiness terlihat hijau.
- CPU host mendadak tinggi dan stabil di level atas.
- Queue depth dan queue age mulai naik.
- Throughput turun atau tidak naik sesuai penambahan worker.
- Retry job meningkat.
Penyebab yang umum
- Worker versi baru memproses job sebelum handshake ke jobserver selesai.
- Bug pada pewarisan file descriptor atau handle komunikasi jobserver, sehingga child process tidak memakai pool yang sama.
- Fallback concurrency lokal aktif saat jobserver tidak terdeteksi.
- Graceful shutdown terlalu singkat; worker lama dan baru aktif bersamaan terlalu lama.
- Token tidak dikembalikan pada jalur error tertentu.
Langkah respons cepat
- Hentikan rollout agar batch tambahan tidak memperparah kondisi.
- Rollback versi baru atau skala turun instance baru lebih dulu.
- Aktifkan drain pada instance yang dicurigai bermasalah jika rollback penuh butuh waktu.
- Turunkan laju konsumsi queue sementara jika sistem memungkinkan, untuk mencegah host jatuh total.
- Periksa dashboard slot dan in-flight jobs: cocokkan acquired tokens, workers ready, dan queue throughput.
- Lihat log startup/shutdown untuk tanda worker memulai tanpa koneksi jobserver atau gagal melepas token.
Pada tahap ini, target utama bukan langsung mencari akar masalah sedetail mungkin, tetapi mengembalikan concurrency efektif ke batas aman. Setelah stabil, baru lakukan analisis lebih dalam.
Desain rollback cepat yang realistis
Rollback cepat untuk worker pool tidak cukup hanya mengganti image ke versi lama. Anda perlu memastikan kapasitas eksekusi ikut kembali terkendali.
Elemen rollback yang disarankan
- Rollback artefak: kembalikan versi worker ke rilis sebelumnya.
- Scale control: kemampuan skala turun cepat untuk replika baru.
- Drain switch: sakelar konfigurasi atau sinyal untuk menghentikan pengambilan job baru.
- Concurrency cap darurat: pembatas keras di level worker atau orchestrator jika ada bug jobserver.
- Feature flag untuk menonaktifkan jalur eksekusi baru yang memengaruhi lifecycle token.
Urutan rollback yang aman
- Pause rollout.
- Nonaktifkan readiness atau aktifkan drain pada batch terbaru.
- Scale down instance baru jika terbukti menjadi sumber lonjakan concurrency.
- Deploy kembali versi sebelumnya.
- Verifikasi queue age, throughput, dan resource host kembali membaik.
- Biarkan sistem stabil sebelum menghapus bukti observability atau merestart hal lain.
Kesalahan umum saat rollback adalah merestart terlalu banyak komponen sekaligus. Akibatnya jejak penyebab asli hilang, dan sistem malah mengalami flapping.
Checklist pencegahan sebelum rilis
Sebelum deploy
- Pastikan worker gagal start jika koneksi ke jobserver tidak valid.
- Uji bahwa readiness baru hijau setelah startup lengkap dan verifikasi akses jobserver selesai.
- Pastikan sinyal shutdown mengubah readiness menjadi gagal sebelum drain dimulai.
- Verifikasi semua jalur error mengembalikan token.
- Pastikan tidak ada fallback concurrency lokal yang aktif diam-diam.
- Tentukan batas waktu drain yang lebih panjang dari durasi job normal.
- Siapkan dashboard rilis: slot, in-flight jobs, queue age, throughput, CPU, memori.
- Siapkan perintah rollback dan siapa yang berwenang mengeksekusinya.
Verifikasi saat canary
- Instance baru hanya mulai bekerja setelah readiness aktif.
- Jumlah acquired tokens tetap konsisten dengan kapasitas global.
- Tidak ada lonjakan retry atau error startup.
- CPU dan memori host tidak menunjukkan perubahan pola yang tidak wajar.
Sesudah rilis
- Bandingkan throughput sebelum dan sesudah deploy.
- Periksa queue age, bukan hanya queue depth.
- Pastikan instance draining benar-benar turun ke nol.
- Verifikasi tidak ada token yang tampak "tertahan" lebih lama dari pola normal.
Contoh sinyal observability yang berguna
Anda tidak harus memakai nama metrik tertentu, tetapi sinyal berikut sangat membantu:
jobserver_tokens_capacity
jobserver_tokens_acquired
worker_jobs_inflight
worker_state_ready
worker_state_draining
worker_token_acquire_seconds
queue_depth
queue_oldest_job_age_seconds
jobs_processed_total
jobs_failed_total
host_cpu_usage
host_memory_usageDengan sinyal itu, Anda bisa membuat panel diagnosis cepat:
- Panel 1: capacity vs acquired tokens vs inflight jobs.
- Panel 2: queue depth vs oldest job age vs throughput.
- Panel 3: worker ready vs draining vs deploy marker.
- Panel 4: CPU, memory, I/O host.
Jika setelah deploy grafik acquired tokens dan inflight jobs naik tajam sementara throughput turun dan CPU penuh, Anda hampir pasti sedang melihat oversubscription atau kontensi berat.
Debugging singkat saat throughput turun atau antrean menumpuk
- Bandingkan slot teoritis dan aktual: apakah jumlah pekerjaan aktif masuk akal terhadap kapasitas slot?
- Cek startup log worker baru: adakah pesan koneksi jobserver gagal, fallback, atau retry panjang?
- Cek shutdown log worker lama: adakah job yang tidak selesai atau token yang tidak sempat dikembalikan?
- Lihat distribusi durasi job: apakah semua job melambat karena host penuh, atau hanya tipe job tertentu?
- Periksa resource bottleneck utama: CPU, memori, disk, atau koneksi ke dependensi.
- Bandingkan versi lama dan baru pada jalur pengambilan token, concurrency internal, dan lifecycle proses.
Sering kali akar masalah ada pada perubahan kecil seperti urutan inisialisasi, penanganan sinyal, atau mode fallback. Karena itu, log startup dan shutdown layak diperlakukan sebagai data utama, bukan pelengkap.
Postmortem ringan setelah insiden
Jika insiden berhasil dipulihkan, buat postmortem ringan yang fokus pada pembelajaran operasional. Tidak perlu panjang, tetapi harus menjawab hal berikut:
- Apa gejala pertama yang terlihat?
- Kapan deploy dimulai dan kapan dampak muncul?
- Metrik apa yang paling cepat menunjukkan masalah?
- Apa penyebab teknis paling mungkin?
- Kontrol apa yang gagal? Misalnya readiness terlalu longgar atau drain terlalu singkat.
- Apa perbaikan pencegahan? Contohnya menambah fail-closed startup, alert queue age, atau cap concurrency darurat.
Format sederhana seperti ini biasanya cukup:
Ringkasan:
Deploy worker versi baru menyebabkan oversubscription dan kontensi host.
Dampak:
Throughput turun, queue age meningkat, retry bertambah.
Deteksi:
Dashboard menunjukkan inflight jobs naik di atas pola normal, CPU host penuh.
Akar masalah:
Worker baru menandai readiness sebelum verifikasi koneksi jobserver selesai.
Mitigasi:
Rollback batch terbaru, aktifkan drain, scale down instance baru.
Tindak lanjut:
- Ubah startup menjadi fail-closed
- Tambah alert queue age + acquired tokens
- Perketat graceful shutdownPenutup
Pada sistem worker pool yang berbagi slot eksekusi, deployment yang terlihat sukses di platform belum tentu aman di tingkat concurrency. Kunci deploy aman untuk worker pool dengan jobserver adalah menjaga satu sumber kebenaran kapasitas, memastikan startup fail-closed, menerapkan drain yang benar saat shutdown, memantau metrik slot dan backlog secara ketat, serta menyiapkan rollback yang benar-benar menurunkan concurrency efektif dengan cepat.
Kalau Anda hanya mengambil satu aturan dari artikel ini, ambil yang ini: worker baru tidak boleh memproses job sebelum terbukti terhubung dan patuh pada jobserver, dan worker lama tidak boleh dimatikan sebelum berhenti mengambil job serta melepas semua slot yang dipegang. Sebagian besar insiden oversubscription saat deploy bermula dari pelanggaran terhadap dua aturan tersebut.
Komentar
0 komentar
Masuk ke akun kamu untuk ikut berkomentar.
Belum ada komentar
Jadilah yang pertama ikut berdiskusi!