Görev Kuyrukları ve Dengeleme
1) Neden görev kuyrukları
İş kuyruğu/iş kuyruğu, üreticileri ve sanatçıları zaman ve hıza göre ayırır:- Zirveleri yumuşatır: ön ve ağır alt sistemler arasındaki tampon.
- SLA'yı stabilize eder: yük sınıflarının öncelikleri ve izolasyonu.
- Hata toleransını basitleştirir: retrays, DLQ, re-staging.
- Yatay olarak ölçeklenir: API'yi değiştirmeden çalışanlar ekleyin.
Tipik etki alanları: ödeme işlemleri, bildirimler, rapor/medya oluşturma, ETL/ML postprocessing, harici API'lerle entegrasyon.
2) Model ve temel kavramlar
Producer: görevi yayınlar (payload + metadata: idempotency key, priority, deadline).
Kuyruk/konu: tampon/görev günlüğü.
Worker: bir görevi alır, işler, onaylar (ack) veya bir hatayla geri döner.
Görünürlük Zaman Aşımı/Kiralama: Işlem süresi boyunca "kiralama" görevleri, sonra - otomatik yeniden teslim.
DLQ (Dead Letter Queue): Denemelerin/ölümcül hataların sınırından sonra görevleri "gömme".
Oran Sınırı/Eşzamanlılık: işçi başına/kuyruk başına/kiracı başına tüketim sınırları.
- Çekme: işçinin kendisi görevi ister (yükü dozlar).
- Push: Broker kabartmaları; Zayıf işçileri "doldurmaya" karşı koruma gerekir.
3) Teslimat ve onay semantiği
En fazla bir kez: retrays yok; Daha hızlı, ama muhtemel kayıp.
En az bir kez (çoğu kuyruk için varsayılan): kopyalar mümkündür - işleyici idempotency gereklidir.
Etkili bir şekilde tam bir kez: uygulama düzeyinde elde edilir (idempotency, dedup, transactions/outbox). Bir komisyoncu yardımcı olabilir, ancak "sihirli mermi'değil.
- Ack/Nack: net sonuç.
- Requeue/Retry: с backoff + jitter.
- Zehirli mesaj - DLQ'ya gönder.
4) Dengeleme ve planlama
4. 1 Dizi ve algoritmalar
FIFO: Basit ve tahmin edilebilir.
Öncelik Kuyruğu: öncelik sınıfları (P0... P3).
WRR/WSR (Weighted Round-Robin/Random): Sınıflar arasında CPU payları/transput.
WFQ/DRR (ağlardaki "adil" kuyruklara benzer şekilde): kiracı/istemci başına düşen paylar.
Deadline/EDF: Son teslim tarihi olan görevler için.
Adil Paylaşım: "Gürültülü komşuların" sınırlandırılması (kiracı başına kotalar).
4. 2 İşleme akışları
Tek uçuş/Birleştirme: Yinelenen temel görevleri birleştirin.
Eşzamanlılık sınırları: görev türüne/tümleştirmeye (harici API'ler) göre paralellik konusunda katı sınırlar.
4. 3 Geo ve Shardening
Shards by key (tenant/id) - verilerin lokalitesi, parçalar içinde sabit düzen.
Yapışkan önbellekler/kaynaklar: "ekli" duruma sahip işçilere karma yönlendirme.
5) Retrai, backoff ve DLQ
Üstel geri dönüş + jitter: 'temel 2 ^ girişim ± rastgele'.
Görev başına maksimum deneme ve toplam son tarih (ölme süresi).
Hataların sınıflandırılması: 'geri alınabilir' (ağ/limit), 'geri alınamaz' (doğrulama/iş yasağı).
Park/Gecikme Kuyruğu: ertelenmiş görevler (örneğin, 15 dakika sonra tekrarlayın).
DLQ politikası: "zehirli" mesajın nerede ve hangi koşullar altında alındığını belirttiğinizden emin olun; Bir yeniden işlemci sağlayın.
6) Idempotency ve veri tekilleştirme
Görevde Idempotency-Key; Son N tuşları için TTL ile mağaza (Redis/DB):- seen ^ skip/merge/result-cache.
- Doğal anahtarlar: Rastgele UUID'ler yerine 'order _ id/ payment_id' kullanın.
- Giden kutusu - görevin gerçeğini ve durumunu bir ticari işlemle bir veritabanı işleminde kaydedin.
- Tam olarak bir kez mavi: Anahtarla 'UPPERT', veritabanında queue + idempotency içinde'en az bir kez "sürümü.
7) Çok kiracılık ve SLA sınıfları
Sıraları/akışları sınıfa göre ayırın: 'kritik', 'standart', 'toplu'.
Kiracı başına kotalar ve öncelikler (Altın/Gümüş/Bronz).
İzolasyon: P0 altındaki işçi havuzlarını adamak; arka plan - ayrı bir küme/düğümlerde.
Kabul kontrolü: Son teslim tarihlerinde işleyebileceğinizden fazlasını kabul etmeyin.
8) Otomatik alım işçileri
Ölçeklendirme metrikleri: kuyruk derinliği, varış oranı, işlem süresi, SLA son tarihleri.
KEDA/Yatay Pod Autoscaler: SQS/Tavşan/Kafka gecikme derinliği tetikleyicileri.
Sınırlayıcı faktörler: Harici oran limitleri API'leri, veritabanı (arka ucu yok etmeyin).
9) Teknoloji seçenekleri ve desenleri
9. 1 RabbitMQ/AMQP
Borsalar: doğrudan/konu/fanout; Ack/tl/DLQ (dead-letter exchange) с kuyruklar.
Prefetch (QoS) "işçide kaç görev olduğunu" düzenler.
ini x-dead-letter-exchange=dlx x-dead-letter-routing-key=jobs.failed x-message-ttl=60000
9. 2 SQS (ve analogları)
Görünürlük Zaman Aşımı, DelaySeconds, RedrivePolicy (DLQ).
Idempotence - uygulamada (dedup tablosu).
Limitler: butches 1-10 mesaj; idempotent çürüklere odaklanın.
9. 3 Kafka/NATS JetStream
Büyük ölçekli boru hatları için: yüksek verim, tutma/yeniden oynatma.
Günlükler üzerinde görev kuyruğu: bir görev = bir mesaj; Anahtar kontrolü başına bir işçi/konu bölümleme yoluyla.
Retrai: bireysel konular/backoff ile konu-ekleri.
9. 4 Redis kuyrukları (Sidekiq/Resque/Bull/Kereviz-Redis)
Çok düşük gecikme; Tek uçuş için stabilite (RDB/AOF), yeniden deneme tuşları ve kilit tuşlarını izleyin.
Uzun süreli retansiyon için değil, "hafif" görevler için uygundur.
9. 5 Çerçeveler
Kereviz (Python), Sidekiq (Ruby), RQ/BullMQ (Node), Huey/Resque - hazır retrays, programlar, ara katman, metrikler.
10) Yönlendirme ve dengeleme şemaları
Yuvarlak Robin: Eşit olarak ancak görevlerin "ciddiyetini" dikkate almaz.
Ağırlıklı RR: işçi kapasitesi/havuzuna göre dağılım.
Adil/Geri basınç bilincine sahip: Çalışan sadece hazır olduğunda yeni bir görev alır.
Öncelikli şeritler: sınıf başına ayrı kuyruklar; İşçiler sırayla okumak [P0>...> Pn] varsa.
Hash-routing: 'hash (key) % shards' - durum bilgisi içeren/önbelleğe alınmış işlemler için.
11) Zaman aşımları, son tarihler ve SLA'lar
Görev başına zaman aşımı: Işin dahili "kiralanması" (işçi kodunda) ≤ komisyoncunun Görünürlük Zaman Aşımı.
Küresel son tarih: görev T zaman sonra mantıklı değil - NACK DLQ.
Bütçeye duyarlı: Son tarih yaklaştığında çalışmayı azaltın (brownout) (kısmi sonuçlar).
12) Gözlemlenebilirlik ve yönetim
12. 1 Metrikler
'eue _ depth', 'arrival _ rate', 'service _ rate', 'lag' (Kafka), 'invisible _ messages' (SQS).
'Başarısız/başarısız/emekli _ toplam', 'retry _ girişimleri', 'dlq _ in _ total', 'processing _ time _ ms {p50, p95, p99}'.
'empotency _ hit _ rate', 'dedup _ drops _ total', 'poison _ total'.
12. 2 Günlükleri/izleme
Korelasyon: 'job _ id', 'correlation _ id', veri tekilleştirme anahtarı.
Olaylar olarak 'retry/backoff/dlq' işaretleyin; Span initial request'ten bağlanma.
12. 3 Panolar/uyarılar
Tetikleyiciler: derinlik> X, p99> SLO, DLQ büyümesi, sıkışmış görevler (görünürlük süresi dolmuş> N), kısayol tuşları.
13) Güvenlik ve uyumluluk
Kiracı izolasyonu: bireysel kuyruklar/anahtar alanları, ACL'ler, kotalar.
Taşıma ve/veya "dinlenme sırasında" şifreleme.
Yükte PII minimizasyonu; Ham PII yerine hash/ID.
Sırlar: Görev gövdesine belirteçler koymayın, kasa/refs kullanın.
14) Anti-desenler
Idempotency olmadan Retrai - çift işlemler/para "iki kez".
Bir dev kuyruk'her şey için "- hiçbir izolasyon, öngörülemeyen gecikmeler.
DLQ olmadan sonsuz retrai - sonsuz "zehirli" görevler.
Görünürlük Zaman aşımı <işlem süresi - basamaklı kopyalar.
Kuyrukta büyük yük - ağ/bellek basıncı; Bir nesne storunda saklamak ve bir bağlantıyı aktarmak daha iyidir.
Geri basınç olmadan itme modeli - işçiler boğulur.
Kritik ve toplu görevleri bir işçi havuzunda karıştırmak.
15) Uygulama kontrol listesi
- Görevleri SLA (P0/P1/P2) ve hacme göre sınıflandırın.
- İstenilen semantik ve tutma ile bir broker/çerçeve seçin.
- Tasarım anahtarları, öncelikleri ve yönlendirme (hash/shards/priority lanes).
- Backoff + jitter retrays ve DLQ politikasını etkinleştirin.
- Idempotency (anahtarlar, upsert, TTL ile deadstore) uygulayın.
- Görev başına, görünürlük ve genel son tarih zaman aşımlarını ayarlayın.
- Eşzamanlılığı ve oranı entegrasyonlara/kiracılara göre sınırlayın.
- Sigortalarla derinlik/gecikme otomatik ölçekleme.
- Metrikler/izleme/uyarılar; "Storm've DLQ taşması üzerine runbooks.
- Başarısızlıklar için testler: işçinin düşmesi, "zehirli" mesaj, aşırı yük, uzun görevler.
16) Örnek Yapılandırmalar ve Kod
16. 1 Kereviz (Redis/Tavşan) - temel akış
python app = Celery("jobs", broker="amqp://...", backend="redis://...")
app.conf.task_acks_late = True # ack после выполнения app.conf.broker_transport_options = {"visibility_timeout": 3600}
app.conf.task_default_retry_delay = 5 app.conf.task_time_limit = 300 # hard timeout
@app.task(bind=True, autoretry_for=(Exception,), retry_backoff=True, retry_jitter=True, max_retries=6)
def process_order(self, order_id):
if seen(order_id): return "ok" # идемпотентность do_work(order_id)
mark_seen(order_id)
return "ok"
16. 2 RabbitMQ - DLQ/TTL
ini x-dead-letter-exchange=dlx x-dead-letter-routing-key=jobs.dlq x-message-ttl=600000 # 10 минут x-max-priority=10
16. 3 Kafka - Seviyeye göre Retrays
orders -> orders.retry.5s -> orders.retry.1m -> orders.dlq
(Zamanlayıcı/cron-tüketici yoluyla gecikmeli teslimat ile transfer.)
16. 4 NATS JetStream - tüketici с geri tepmesi
bash nats consumer add JOBS WORKERS --filter "jobs.email" \
--deliver pull --ack explicit --max-deliver 6 \
--backoff "1s,5s,30s,2m,5m"
17) SSS
S: Push karşı pull ne zaman seçilir?
C: Çekme doğal geri basınç ve "dürüst" dengeleme sağlar; İtme, düşük hızlarda ve minimum TTFB gerektiğinde daha kolaydır, ancak sınırlayıcılar gerektirir.
S: Bir sıcak anahtar nasıl önlenir?
A: Bileşik anahtarla parçala ('order _ id % N'), arabellek ve toplu işlem, anahtar başına limit gir.
S: "Tam olarak bir kez" mümkün mü?
A: Pratik olarak - idempotence ve işlem giden kutusu aracılığıyla. Tamamen "matematiksel" tam olarak-bir kez nadiren ulaşılabilir ve pahalıdır.
S: Büyük görev ekleri nerede saklanır?
A: Nesne depolamada (S3/GCS) ve görevde - bağlantı/kimlik; broker ve ağ üzerindeki baskıyı azaltır.
S: TTL/görünürlük nasıl seçilir?
C: Görünürlük ≥ p99 işlem süresi × stok 2-3 ×. TTL görevleri - daha az iş tarihi.
18) Toplam
Güçlü bir kuyruk sistemi, teslimat semantiği, öncelikler ve kısıtlamalar arasındaki dengedir. Anahtar ve yönlendirme tasarlayın, idempotency sağlayın, backoff ve DLQ ile yeniden ödeme yapın, SLA sınıflarına kaynak ayırın ve metrikleri izleyin. O zaman arka plan süreçleriniz öngörülebilir, istikrarlı ve ölçeklenebilir olacak - zirvelerin altında sürpriz olmayacak.