Skip to content

Background Jobs ve Uzun Süren İşlemler ​

Background job, kullanıcı request'inin latency bütçesine sığmayan veya tekrar denenebilir işi queue ve worker'lara devretme desenidir. Kullanıcıya yalnızca “başladı” demek yeterli değildir; iş kimliği, durum, tekrar deneme, ilerleme ve sonucun nasıl alınacağı da sözleşmenin parçasıdır.

Hızlı Karar ​

DurumYaklaşımDikkat
Kısa ve hemen sonuçlanan işSynchronous requestTimeout bütçesi
Uzun veya tekrar denenebilir işQueue + workerIdempotency ve DLQ
Düzenli tetiklenen işScheduler + durable job recordOverlap ve missed run
Kullanıcı ilerleme bekliyorJob status + progress eventPolling yükü ve notification

Üretim Kontrol Listesi ​

  • Problem: İş neden request path'inden ayrılıyor ve başarı ne zaman kesinleşiyor?
  • Çözüm: Job ID, state machine, retry, timeout, priority, progress ve ownership tanımlı mı?
  • Trade-off: Kullanıcı yanıtı hızlanır; eventual consistency ve worker operasyonu eklenir.
  • Hata durumu: Duplicate execution, stuck job, poison input, scheduler overlap ve worker kaybı ele alınmalı.
  • Ölçüm: Queue age, job duration, success/failure, retry, active workers ve completion SLO izlenmeli.
  • Güvenlik/maliyet: Job payload'ı minimize edilmeli; tenant authorization ve worker concurrency korunmalı.

Job Yaşam Döngüsü ​

Önerilen durumlar queued, running, succeeded, failed, retrying, cancelled ve expired olabilir. State transition yalnızca geçerli önceki durumdan yapılmalı; her değişiklikte version veya optimistic lock kullanılarak iki worker'ın aynı işi sahiplenmesi önlenmelidir.

Uzun iş başlatan endpoint 202 Accepted ve Location: /jobs/{id} dönebilir:

json
{
  "id": "job_123",
  "status": "running",
  "progress": { "completed": 40, "total": 100 },
  "statusUrl": "/api/jobs/job_123"
}

Status endpoint'i yetki kontrollü olmalı. Completion sonucu polling, webhook veya push notification ile teslim edilebilir; üçü için de event ID ve tekrar davranışı yazılmalıdır.

Worker Pool ve Scheduling ​

Worker concurrency, CPU ve I/O tipine göre ölçülür; sınırsız thread açmak throughput değil connection pool exhaustion üretir. Queue capacity bounded olmalı ve reject/backpressure politikası belirlenmelidir.

Spring @Scheduled veya durable scheduler kullanırken timezone, misfire, leader election, idempotent execution ve overlapping run kararı belgelenir:

java
@Scheduled(cron = "0 */5 * * * *", zone = "UTC")
public void enqueueDueJobs() {
    jobRepository.findDueJobs(Instant.now())
        .forEach(job -> queue.publish(new JobCommand(job.id())));
}

Scheduler yalnızca trigger üretmeli; iş durumu queue ve durable database'de tutulmalıdır. Birden fazla instance çalışıyorsa aynı job'ın iki kez enqueue edilmesine karşı unique claim veya distributed lock gerekir.

Retry, Priority ve SLA ​

Transient hata için sınırlı exponential backoff + jitter uygula. Permanent validation hatası tekrar denenmemeli; poison job quarantine/DLQ'ya alınmalıdır. Retry job'un yeni bir iş gibi görünmesine izin vermeden aynı idempotency key'i koru.

Priority queue, kritik işlerin bekleme süresini düşürebilir; düşük öncelikli işlerin starvation yaşamaması için aging veya ayrılmış capacity gerekebilir. Priority, tenant veya user tarafından sınırsız kontrol edilmemelidir.

Job SLA'sı submission-to-completion ve queue-wait bileşenlerine ayrılır. Worker sayısı artırılmadan önce downstream API/database budget'ı ve maliyet etkisi kontrol edilir.

Progress ve Bildirim ​

Progress yüzdesi yalnızca toplam iş birimi güvenilir biçimde biliniyorsa kullanılır. Aksi halde phase, completed, estimated ve updatedAt alanları daha dürüsttür. Çok sık progress event yayınlamak broker, database ve mobil client maliyetini artırır; throttling uygulanır.

İş tamamlandığında sonuç immutable artifact veya resource olarak saklanmalı; status endpoint'i her okumada pahalı işi yeniden çalıştırmamalıdır. Kullanıcıya dönen hata teknik stack trace değil, stable error code olmalıdır.

Dayanıklılık ve Operasyon ​

Worker restart, broker redelivery, database timeout, deploy sırasında graceful shutdown ve scheduler leader kaybı test edilmelidir. Stuck job için lease expiry, heartbeat ve operator replay/cancel prosedürü bulunmalıdır.

Mesaj semantiği için Mesajlaşma Desenleri, retry ve DLQ ayrıntıları için Asenkron İşlemler sayfasını kullan.

Eren Demir tarafından oluşturulmuştur.