11 Okt 2025·6 menit membaca

Worker pool vs goroutine-per-task di Go untuk pekerjaan latar belakang

Worker pool vs goroutine-per-task di Go: pelajari bagaimana masing-masing model memengaruhi throughput, penggunaan memori, dan backpressure untuk pemrosesan latar belakang dan workflow jangka panjang.

Worker pool vs goroutine-per-task di Go untuk pekerjaan latar belakang

Masalah apa yang kita selesaikan?

Sebagian besar layanan Go melakukan lebih dari sekadar menjawab permintaan HTTP. Mereka juga menjalankan pekerjaan latar belakang: mengirim email, mengubah ukuran gambar, menghasilkan faktur, menyinkronkan data, memproses event, atau membangun ulang indeks pencarian. Beberapa pekerjaan cepat dan independen. Yang lain membentuk workflow panjang di mana setiap langkah bergantung pada yang sebelumnya (membebankan kartu, menunggu konfirmasi, lalu memberi tahu pelanggan dan memperbarui pelaporan).

Saat orang membandingkan "Go worker pools vs goroutine-per-task", biasanya mereka mencoba menyelesaikan satu masalah produksi: bagaimana menjalankan banyak pekerjaan latar belakang tanpa membuat layanan menjadi lambat, mahal, atau tidak stabil.

Dampaknya terasa di beberapa tempat:

  • Latensi: pekerjaan latar belakang mengambil CPU, memori, koneksi database, dan bandwidth jaringan dari permintaan yang berhadapan dengan pengguna.
  • Biaya: konkurensi yang tidak terkendali mendorong Anda ke mesin yang lebih besar, kapasitas database lebih besar, atau tagihan antrean dan API yang lebih tinggi.
  • Stabilitas: lonjakan (impor, pengiriman marketing, gelombang retry) dapat memicu timeouts, crash OOM, atau kegagalan berantai.

Pertukaran nyata adalah kesederhanaan vs kontrol. Memunculkan goroutine per tugas mudah ditulis dan sering kali cukup ketika volume rendah atau terbatas secara alami. Worker pool menambahkan struktur: konkurensi tetap, batas yang lebih jelas, dan tempat alami untuk menaruh timeout, retry, dan metrik. Biayanya adalah kode tambahan dan keputusan tentang apa yang terjadi saat sistem sibuk (apakah tugas menunggu, ditolak, atau disimpan di tempat lain?).

Ini tentang pemrosesan latar belakang sehari-hari: throughput, memori, dan backpressure (bagaimana mencegah overload). Ini tidak mencoba mencakup semua teknologi antrean, engine workflow terdistribusi, atau semantik exactly-once.

Jika Anda membangun aplikasi lengkap dengan logika latar belakang menggunakan platform seperti AppMaster (appmaster.io), pertanyaan yang sama muncul cepat. Proses bisnis dan integrasi Anda tetap butuh batasan di sekitar database, API eksternal, dan penyedia email/SMS supaya satu workflow yang sibuk tidak memperlambat semuanya.

Dua pola umum dalam istilah sederhana

Goroutine-per-task

Ini pendekatan paling sederhana: setiap kali pekerjaan datang, jalankan goroutine untuk menanganinya. "Antrean" seringkali adalah apa pun yang memicu kerja, seperti penerima channel atau panggilan langsung dari handler HTTP.

Bentuk tipikalnya: terima pekerjaan, lalu go handle(job). Kadang channel masih terlibat, tetapi hanya sebagai titik serah, bukan pembatas.

Ini cenderung bekerja baik ketika pekerjaan sebagian besar menunggu I/O (panggilan HTTP, query DB, upload), volume tugas relatif kecil, dan lonjakan kecil atau dapat diprediksi.

Kelemahannya adalah konkurensi bisa tumbuh tanpa batas yang jelas. Itu bisa memicu lonjakan memori, membuka terlalu banyak koneksi, atau membebani layanan hilir.

Worker pool

Worker pool memulai sejumlah goroutine worker tetap dan memberi mereka pekerjaan dari antrean, biasanya buffered channel di memori. Setiap worker melakukan loop: ambil pekerjaan, proses, ulangi.

Perbedaan kuncinya adalah kontrol. Jumlah worker adalah batas konkurensi yang keras. Jika tugas datang lebih cepat daripada worker menyelesaikannya, tugas menunggu di antrean (atau ditolak jika antrean penuh).

Worker pool cocok ketika pekerjaan berat CPU (pemrosesan gambar, pembuatan laporan), ketika Anda butuh penggunaan sumber daya yang dapat diprediksi, atau ketika Anda harus melindungi database atau API pihak ketiga dari lonjakan.

Di mana antrean berada

Kedua pola bisa menggunakan channel in-memory, yang cepat tetapi hilang saat restart. Untuk pekerjaan yang "tidak boleh hilang" atau workflow panjang, antrean sering dipindah ke luar proses (tabel database, Redis, atau message broker). Dalam pengaturan itu, Anda masih memilih antara goroutine-per-task dan worker pool, tetapi sekarang mereka berjalan sebagai consumer antrean eksternal.

Sebagai contoh sederhana, jika sistem tiba-tiba perlu mengirim 10.000 email, goroutine-per-task bisa mencoba mengirim semuanya sekaligus. Pool bisa mengirim 50 sekaligus dan membuat sisanya menunggu dengan cara terkontrol.

Throughput: apa yang berubah dan apa yang tidak

Sering diharapkan ada perbedaan throughput besar antara worker pool dan goroutine-per-task. Sebagian besar waktu, throughput mentah dibatasi oleh hal lain, bukan oleh bagaimana Anda memulai goroutine.

Throughput biasanya mencapai batas pada sumber daya bersama yang paling lambat: database atau batas API eksternal, disk atau bandwidth jaringan, pekerjaan yang berat CPU (JSON/PDF/resize gambar), lock dan state bersama, atau layanan hilir yang melambat di bawah beban.

Jika sumber daya bersama adalah bottleneck, meluncurkan lebih banyak goroutine tidak menyelesaikan pekerjaan lebih cepat. Itu sebagian besar menciptakan lebih banyak waktu tunggu pada titik penyempitan yang sama.

Goroutine-per-task bisa unggul ketika tugas pendek, sebagian besar I/O-bound, dan tidak bersaing pada batas bersama. Startup goroutine murah, dan Go menjadwalkan banyak goroutine dengan baik. Dalam pola "fetch, parse, write satu baris", ini bisa menjaga CPU sibuk dan menyembunyikan latensi jaringan.

Worker pool unggul ketika Anda perlu membatasi sumber daya mahal. Jika setiap pekerjaan memegang koneksi DB, membuka file, mengalokasikan buffer besar, atau mengenai kuota API, konkurensi tetap menjaga layanan tetap stabil sambil masih mencapai throughput aman maksimum.

Latency (terutama p99) sering kali menunjukkan perbedaan. Goroutine-per-task bisa terlihat bagus pada beban rendah, lalu runtuh saat terlalu banyak tugas menumpuk. Pool memperkenalkan penundaan antrean (tugas menunggu worker bebas), tetapi perilakunya lebih stabil karena Anda menghindari gerombolan yang berebut batas yang sama.

Model mental sederhana:

  • Jika pekerjaan murah dan independen, lebih banyak konkurensi bisa meningkatkan throughput.
  • Jika pekerjaan dibatasi oleh batas bersama, lebih banyak konkurensi sebagian besar meningkatkan waktu tunggu.
  • Jika Anda peduli tentang p99, ukur waktu antrean terpisah dari waktu pemrosesan.

Penggunaan memori dan sumber daya

Banyak perdebatan worker-pool vs goroutine-per-task sebenarnya tentang memori. CPU seringkali bisa diskalakan. Kegagalan memori lebih tiba-tiba dan bisa mematikan seluruh layanan.

Goroutine murah, tetapi tidak gratis. Masing-masing memulai dengan stack kecil yang tumbuh saat memanggil fungsi lebih dalam atau menahan variabel lokal besar. Ada juga bookkeeping scheduler dan runtime. Sepuluh ribu goroutine bisa baik. Seratus ribu bisa mengejutkan jika masing-masing menyimpan referensi ke data pekerjaan besar.

Biaya tersembunyi yang lebih besar seringkali bukan goroutine itu sendiri, tetapi apa yang dipertahankannya tetap hidup. Jika tugas datang lebih cepat daripada selesai, goroutine-per-task membuat backlog tak terbatas. "Antrean" bisa implisit (goroutine menunggu lock atau I/O) atau eksplisit (buffered channel, slice, batch in-memory). Bagaimanapun, memori tumbuh seiring backlog.

Worker pool membantu karena mereka memaksa batas. Dengan worker tetap dan antrean terbatas, Anda mendapatkan batas memori nyata dan mode kegagalan yang jelas: setelah antrean penuh, Anda blok, menurunkan beban, atau menaruh beban kembali ke hulu.

Perkiraan cepat:

  • Peak goroutine = worker + pekerjaan dalam proses + pekerjaan "menunggu" yang Anda buat
  • Memori per pekerjaan = payload (bytes) + metadata + apa pun yang direferensikan (request, JSON yang didekode, baris DB)
  • Memori backlog puncak ~= pekerjaan menunggu * memori per pekerjaan

Contoh: jika setiap pekerjaan menahan payload 200 KB (atau mereferensikan objek grafik 200 KB) dan Anda membiarkan 5.000 pekerjaan menumpuk, itu sekitar 1 GB hanya untuk payload. Bahkan jika goroutine gratis secara ajaib, backlog tidak akan gratis.

Backpressure: menjaga sistem agar tidak meleleh

Frontend yang menghormati batasan
Bangun portal pelanggan dan alat internal yang memicu pekerjaan tanpa membebani backend Anda.
Buat Portal

Backpressure itu sederhana: saat pekerjaan datang lebih cepat daripada Anda bisa menyelesaikannya, sistem mendorong kembali dengan cara terkontrol alih-alih menumpuk secara diam-diam. Tanpa itu, Anda tidak hanya menjadi lebih lambat. Anda mendapat timeout, pertumbuhan memori, dan kegagalan yang sulit direproduksi.

Biasanya Anda menyadari kurangnya backpressure ketika lonjakan (impor, email, ekspor) memicu pola seperti memori naik dan tidak turun, waktu antrean tumbuh sementara CPU tetap sibuk, lonjakan latensi untuk permintaan tak terkait, retry menumpuk, atau error seperti "too many open files" dan habisnya pool koneksi.

Alat praktis adalah channel terbatas: batasi berapa banyak pekerjaan yang bisa menunggu. Producer akan terblok saat channel penuh, yang memperlambat pembuatan pekerjaan di sumbernya.

Blok tidak selalu pilihan yang tepat. Untuk pekerjaan opsional, pilih kebijakan eksplisit agar overload dapat diprediksi:

  • Drop tugas bernilai rendah (misalnya notifikasi duplikat)
  • Batch banyak tugas kecil menjadi satu penulisan atau satu panggilan API
  • Delay pekerjaan dengan jitter untuk menghindari lonjakan retry
  • Defer ke antrean persisten dan kembalikan respons cepat
  • Shed load dengan error jelas saat sudah overload

Rate limiting dan timeout juga alat backpressure. Rate limiting membatasi seberapa cepat Anda mengenai dependensi (penyedia email, database, API pihak ketiga). Timeout membatasi berapa lama worker bisa terjebak. Bersama-sama, mereka menghentikan dependensi yang lambat menjadi outage penuh.

Contoh: pembuatan laporan akhir bulan. Jika 10.000 permintaan datang sekaligus, goroutine tak terbatas bisa memicu 10.000 render PDF dan upload. Dengan antrean terbatas dan worker tetap, Anda merender dan retry dengan kecepatan aman.

Cara membangun worker pool langkah demi langkah

Validasi asumsi konkurensi
Uji batasan worker dan perilaku job lebih awal dengan backend nyata dan endpoint nyata.
Buat Prototipe

Worker pool membatasi konkurensi dengan menjalankan sejumlah worker tetap dan memberi mereka pekerjaan dari antrean.

1) Pilih limit konkurensi yang aman

Mulailah dari apa yang dikerjakan tugas Anda.

  • Untuk pekerjaan berat CPU, jaga worker dekat jumlah core CPU Anda.
  • Untuk pekerjaan I/O-heavy (DB, HTTP, storage), Anda bisa lebih tinggi, tetapi hentikan saat dependensi mulai timeout atau throttle.
  • Untuk pekerjaan campuran, ukur dan sesuaikan. Rentang awal yang wajar seringkali 2x sampai 10x jumlah core CPU, lalu tuning.
  • Hormati batas bersama. Jika pool DB adalah 20 koneksi, 200 worker hanya akan berebut 20 itu.

2) Pilih antrean dan tetapkan ukurannya

Buffered channel umum karena sudah built-in dan mudah dipahami. Buffer adalah peredam kejut Anda untuk lonjakan.

Buffer kecil memperlihatkan overload lebih cepat (sender terblok lebih awal). Buffer besar meratakan spike tetapi bisa menyembunyikan masalah dan meningkatkan memori serta latensi. Ukur buffer dengan sengaja dan putuskan apa yang terjadi saat penuh.

3) Buat setiap tugas bisa dibatalkan

Operkan context.Context ke setiap job dan pastikan kode job menggunakannya (DB, HTTP). Ini cara Anda berhenti dengan bersih saat deploy, shutdown, dan timeout.

func StartPool(ctx context.Context, workers, queueSize int, handle func(context.Context, Job) error) chan<- Job {
    jobs := make(chan Job, queueSize)
    for i := 0; i < workers; i++ {
        go func() {
            for {
                select {
                case <-ctx.Done():
                    return
                case j := <-jobs:
                    _ = handle(ctx, j)
                }
            }
        }()
    }
    return jobs
}

(Kode di atas tidak diterjemahkan dan tetap utuh.)

4) Tambahkan metrik yang benar-benar akan Anda gunakan

Jika Anda hanya melacak beberapa angka, jadikan ini prioritas:

  • Kedalaman antrean (berapa jauh tertinggal)
  • Waktu sibuk worker (seberapa jenuh pool)
  • Durasi tugas (p50, p95, p99)
  • Rasio error (dan hitungan retry jika Anda melakukan retry)

Itu cukup untuk menyetel jumlah worker dan ukuran antrean berdasarkan bukti, bukan tebakan.

Kesalahan umum dan jebakan

Kebanyakan tim tidak kena dampak karena memilih pola yang "salah". Mereka kena karena default kecil yang berubah menjadi outage saat traffic melonjak.

Saat goroutine berlipat ganda

Jebakan klasik adalah memunculkan satu goroutine per job saat lonjakan. Beberapa ratus baik-baik saja. Ratusan ribu bisa membanjiri scheduler, heap, log, dan soket jaringan. Bahkan jika tiap goroutine kecil, total biaya bertambah, dan pemulihan butuh waktu karena pekerjaan sudah berjalan.

Kesalahan lain adalah menganggap buffered channel besar sebagai "backpressure." Buffer besar hanyalah antrean tersembunyi. Itu bisa memberi waktu, tetapi juga menyembunyikan masalah sampai Anda mencapai dinding memori. Jika Anda butuh antrean, ukur dengan sengaja dan putuskan apa yang terjadi saat penuh (blok, drop, retry nanti, atau persist ke storage).

Bottleneck tersembunyi

Banyak pekerjaan latar belakang bukan CPU-bound. Mereka dibatasi oleh sesuatu di hilir. Jika Anda mengabaikan batas itu, producer cepat membanjiri consumer lambat.

Jebakan umum:

  • Tidak ada pembatalan atau timeout, sehingga worker bisa terblokir selamanya pada request API atau query DB
  • Jumlah worker dipilih tanpa memeriksa batas nyata seperti koneksi DB, I/O disk, atau kuota pihak ketiga
  • Retry yang memperkuat beban (retry segera pada 1.000 job yang gagal)
  • Satu lock bersama atau transaksi tunggal yang menserialize semuanya, sehingga "lebih banyak worker" hanya menambah overhead
  • Kurangnya visibilitas: tidak ada metrik untuk kedalaman antrean, umur job, hitungan retry, dan utilisasi worker

Contoh: ekspor malam hari memicu 20.000 tugas "kirim notifikasi." Jika setiap tugas mengenai database dan penyedia email, mudah melampaui pool koneksi atau kuota. Pool 50 worker dengan timeout per tugas dan antrean kecil membuat batas terlihat. Satu goroutine per tugas plus buffer raksasa membuat sistem terlihat baik sampai tiba-tiba tidak lagi.

Contoh: ekspor dan notifikasi yang lonjakan

Ubah data menjadi otomatisasi
Desain data Anda dengan model yang mengutamakan PostgreSQL dan jaga logika pekerjaan dekat dengannya.
Buat Backend

Bayangkan tim support yang butuh data untuk audit. Satu orang klik tombol "Export", lalu beberapa rekan melakukan hal yang sama, dan tiba-tiba Anda punya 5.000 job ekspor dibuat dalam semenit. Setiap ekspor membaca dari database, memformat CSV, menyimpan file, dan mengirim notifikasi (email atau Telegram) saat siap.

Dengan pendekatan goroutine-per-task, sistem terasa cepat untuk sesaat. Semua 5.000 job mulai hampir sekaligus, dan terlihat antrean cepat habis. Lalu biayanya muncul: ribuan query DB bersamaan berebut koneksi, memori naik karena job menahan buffer bersamaan, dan timeout menjadi umum. Job yang seharusnya cepat terjebak di belakang retry dan query yang lambat.

Dengan worker pool, awalnya lebih lambat tetapi keseluruhan run lebih tenang. Dengan 50 worker, hanya 50 ekspor melakukan pekerjaan berat sekaligus. Penggunaan DB tetap dalam kisaran yang dapat diprediksi, buffer lebih sering digunakan ulang, dan latensi lebih stabil. Perkiraan waktu selesai total juga lebih mudah: kurang lebih (jobs / workers) * durasi rata-rata job, ditambah overhead.

Perbedaan kunci bukan bahwa pool ajaib lebih cepat. Melainkan mereka menghentikan sistem menyakiti dirinya sendiri saat lonjakan. Run terkontrol 50-sekaligus sering selesai lebih cepat daripada 5.000 job yang saling berkompetisi.

Tempat menerapkan backpressure tergantung apa yang ingin Anda lindungi:

  • Di lapisan API, tolak atau tunda request ekspor baru saat sistem sibuk.
  • Di antrean, terima request tetapi enqueue job dan drain pada laju yang aman.
  • Di worker pool, batasi konkurensi untuk bagian yang mahal (baca DB, pembuatan file, pengiriman notifikasi).
  • Per resource, bagi menjadi batas terpisah (mis. 40 worker untuk ekspor tapi hanya 10 untuk notifikasi).
  • Pada panggilan eksternal, rate-limit email/SMS/Telegram agar Anda tidak diblokir.

Checklist cepat sebelum deploy

Bangun pekerjaan latar belakang yang lebih aman
Modelkan alur kerja latar belakang dengan batasan yang jelas, lalu hasilkan kode Go siap produksi.
Coba AppMaster

Sebelum menjalankan pekerjaan latar belakang di produksi, cek batas, visibilitas, dan penanganan kegagalan. Sebagian besar insiden bukan disebabkan oleh "kode lambat." Mereka muncul dari ketiadaan guardrail saat load melonjak atau dependensi menjadi flakey.

  • Tetapkan max konkurensi keras per dependensi. Jangan pilih satu angka global dan berharap cocok untuk semuanya. Batasi penulisan DB, panggilan HTTP keluar, dan pekerjaan berat CPU secara terpisah.
  • Buat antrean terbatas dan dapat diobservasi. Beri batas nyata pada job yang tertunda dan publikasikan beberapa metrik: kedalaman antrean, umur job tertua, dan kecepatan pemrosesan.
  • Tambahkan retry dengan jitter dan jalur dead-letter. Retry selektif, sebarkan retry, dan setelah N kegagalan pindahkan job ke dead-letter queue atau tabel "failed" dengan detail cukup untuk review dan replay.
  • Verifikasi perilaku shutdown: drain, cancel, resume dengan aman. Putuskan apa yang terjadi saat deploy atau crash. Buat job idempotent agar reprocessing aman, dan simpan progres untuk workflow panjang.
  • Lindungi sistem dengan timeout dan circuit breaker. Setiap panggilan eksternal perlu timeout. Jika dependensi down, gagal cepat (atau hentikan intake) daripada menumpuk pekerjaan.

Langkah praktis selanjutnya

Pilih pola yang cocok dengan bentuk beban sistem Anda pada hari normal, bukan hari sempurna. Jika pekerjaan datang dalam lonjakan (upload, ekspor, email blast), worker pool tetap dengan antrean terbatas biasanya default yang lebih aman. Jika pekerjaan steady dan masing-masing tugas kecil, goroutine-per-task bisa cukup, asalkan Anda tetap menegakkan batas di suatu tempat.

Pilihan yang menang biasanya yang membuat kegagalan terlihat membosankan. Pool membuat batas jelas. Goroutine-per-task membuat mudah lupa batas sampai lonjakan nyata pertama.

Mulai sederhana, lalu tambahkan batas dan visibilitas

Mulailah dengan sesuatu yang sederhana, tetapi tambahkan dua kontrol sejak awal: batas konkurensi dan cara melihat antrean dan kegagalan.

Rencana rollout praktis:

  • Definisikan bentuk beban: bursty, steady, atau campuran (dan seperti apa "peak").
  • Pasang batas keras pada pekerjaan yang sedang berjalan (ukuran pool, semaphore, atau channel terbatas).
  • Putuskan apa yang terjadi saat batas tercapai: blok, drop, atau kembalikan error jelas.
  • Tambahkan metrik dasar: kedalaman antrean, waktu di antrean, waktu pemrosesan, retry, dan dead letters.
  • Uji beban dengan lonjakan 5x perkiraan puncak dan pantau memori serta latensi.

Saat pool tidak cukup

Jika workflow bisa berjalan selama menit hingga hari, pool sederhana bisa kesulitan karena pekerjaan bukan hanya "lakukan sekali." Anda butuh state, retry, dan kemampuan melanjutkan. Itu biasanya berarti menyimpan progres, membuat langkah idempotent, dan menerapkan backoff. Juga bisa berarti memecah satu job besar menjadi langkah-langkah kecil agar Anda bisa resume dengan aman setelah crash.

Jika Anda ingin mengirimkan backend penuh dengan workflow lebih cepat, AppMaster (appmaster.io) bisa menjadi opsi praktis: Anda memodelkan data dan logika bisnis secara visual, dan itu menghasilkan kode Go nyata untuk backend sehingga Anda bisa menjaga disiplin yang sama seputar batas konkurensi, antrean, dan backpressure tanpa menyusun semuanya sendiri.

FAQ

Kapan saya harus menggunakan worker pool dibandingkan memulai goroutine untuk setiap tugas?

Gunakan worker pool sebagai default ketika pekerjaan bisa datang dalam lonjakan atau menyentuh batas bersama seperti koneksi DB, CPU, atau kuota API eksternal. Gunakan goroutine-per-task ketika volume terbatas, tugas singkat, dan Anda masih menerapkan batasan di suatu tempat (misalnya semaphore atau rate limiter).

Apa tradeoff sebenarnya antara goroutine-per-task dan worker pool?

Memulai goroutine per tugas cepat ditulis dan dapat memberikan throughput baik pada beban rendah, tetapi dapat menciptakan backlog tak terbatas saat lonjakan. Worker pool menambahkan batas konkurensi keras dan tempat yang jelas untuk menerapkan timeout, retry, dan metrik, sehingga perilaku produksi biasanya lebih dapat diprediksi.

Apakah worker pool akan mengurangi throughput dibandingkan goroutine-per-task?

Biasanya tidak banyak. Di kebanyakan sistem, throughput dibatasi oleh bottleneck bersama seperti database, API eksternal, I/O disk, atau langkah-langkah yang berat CPU. Menambah goroutine tidak akan melewati batas itu; mereka malah meningkatkan waktu tunggu dan kontensi.

Bagaimana pola ini memengaruhi latency (khususnya p99)?

Goroutine-per-task sering memiliki latency lebih baik pada beban rendah, lalu memburuk tajam pada beban tinggi karena semua hal bersaing sekaligus. Pool bisa menambah delay antrean, tetapi cenderung menjaga p99 lebih stabil dengan mencegah thundering herd pada dependensi yang sama.

Mengapa goroutine-per-task bisa menyebabkan lonjakan memori?

Biaya terbesar biasanya bukan goroutine itu sendiri, melainkan backlog. Jika tugas menumpuk dan masing-masing mempertahankan payload besar atau objek besar, memori dapat naik cepat. Worker pool dengan antrean terbatas mengubahnya menjadi batas memori yang jelas dan perilaku overload yang dapat diprediksi.

Apa itu backpressure, dan bagaimana saya menambahkannya di Go?

Backpressure berarti Anda melambatkan atau menghentikan penerimaan kerja baru saat sistem sudah sibuk, daripada membiarkan pekerjaan menumpuk secara diam-diam. Antrean terbatas adalah bentuk sederhana: ketika penuh, producer akan terblok atau Anda mengembalikan error, yang mencegah memori dan koneksi meluap.

Bagaimana saya memilih jumlah worker yang tepat?

Mulailah dari batas nyata. Untuk pekerjaan berat CPU, mulai mendekati jumlah core CPU. Untuk pekerjaan I/O-heavy, Anda bisa lebih tinggi, tetapi berhenti menambah ketika database, jaringan, atau API pihak ketiga mulai timeout atau throttle, dan pastikan menghormati ukuran pool koneksi.

Seberapa besar antrean/buffer pekerjaan sebaiknya?

Pilih ukuran yang meredam lonjakan normal tetapi tidak menyembunyikan masalah selama berjam-jam. Buffer kecil cepat menunjukkan overload; buffer besar bisa meningkatkan memori dan membuat pengguna menunggu lebih lama sebelum kegagalan terlihat. Tentukan sebelumnya apa yang terjadi saat antrean penuh: blok, tolak, buang, atau simpan ke tempat lain.

Bagaimana saya mencegah worker terjebak selamanya?

Gunakan context.Context untuk setiap pekerjaan dan pastikan panggilan database dan HTTP menghormatinya. Tetapkan timeout pada panggilan eksternal, dan buat perilaku shutdown eksplisit supaya worker bisa berhenti bersih tanpa meninggalkan goroutine menggantung atau pekerjaan setengah jadi.

Metode metrik apa yang harus saya pantau untuk pekerjaan latar belakang?

Pantau kedalaman antrean, waktu tunggu di antrean, durasi tugas (p50/p95/p99), dan jumlah error/retry. Metrik ini memberi tahu apakah Anda perlu lebih banyak worker, antrean lebih kecil, timeout lebih ketat, atau rate limiting lebih kuat terhadap dependensi.

Mudah untuk memulai
Ciptakan sesuatu yang menakjubkan

Eksperimen dengan AppMaster dengan paket gratis.
Saat Anda siap, Anda dapat memilih langganan yang tepat.

Memulai