GH GambleHub

Giden kutusu deseni

Outbox, bir etki alanı hizmetinin bir iş değişikliği ve ilgili olayı bir yerel işlemde deposuna yazdığı mimari bir kalıptır. Olayın harici veri yoluna/kuyruğa yayınlanması, 'dış kutu' tablosunu okuyan ve kayıtları aktaran ayrı bir güvenli işlem (yayıncı) tarafından eşzamansız olarak gerçekleştirilir. Bu yaklaşım,'önce veritabanına, sonra otobüse "yarışını ortadan kaldırır ve arıza durumunda bile güvenilir teslimat sağlar.

1) Ne zaman başvurulur

Sığdır:
  • Bağlamlar arası olaylara sahip mikro hizmetler ve modüler monolitler.
  • "Devletin sabit olması ↔ olayın kaybedilememesi" sağlanmalıdır.
  • Bize idempotans ve kontrollü yeniden teslimat lazım.
Uygun değil:
  • Çeşitli kaynaklar üzerindeki zorlu küresel işlemler kritiktir (açık sözleşmelerle TTK/destanlardan daha iyidir).
  • Gerçeğin adanmış bir kaynağı yoktur (olayın üretildiği yerde durum depolanmaz).

2) Hedefler ve özellikler

Atomik yazma: etki alanı kaydı + giden kutusu - bir işlemde.
En az bir kez yayın: tekrara izin veriyoruz, kaybı hariç tutuyoruz.
Tüketici idempotence: abone tarafında alır karşı koruma.
Tam olarak bir kez etkili: outbox + idempotent consumer + dedup kombinasyonu ile elde edilir.
Net telemetri - Ticari işlemleri ve olayları ilişkilendirin.

3) Veri şeması (örnek)

sql
-- Domain table (example: orders)
CREATE TABLE orders (
id       UUID PRIMARY KEY,
tenant_id    TEXT NOT NULL,
status     TEXT NOT NULL,
total_amount  NUMERIC(12,2) NOT NULL,
updated_at   TIMESTAMP NOT NULL DEFAULT now()
);

-- Outbox
CREATE TABLE outbox (
id       UUID PRIMARY KEY,        -- event_id aggregate_type TEXT NOT NULL,          -- 'order'
aggregate_id  UUID NOT NULL,          -- order_id tenant_id    TEXT NOT NULL,
type      TEXT NOT NULL,          -- 'OrderCreated'
payload JSONB NOT NULL, -- serialized headers event JSONB NOT NULL DEFAULT '{}':: jsonb,
occurred_at TIMESTAMP NOT NULL, -- time in domain transaction available_at TIMESTAMP NOT NULL, -- earliest publish time (backoff)
published_at TIMESTAMP, - is filled by the attempts INT NOT NULL DEFAULT 0,
error      TEXT
);

CREATE INDEX ON outbox (available_at) WHERE published_at IS NULL;
CREATE INDEX ON outbox (tenant_id, available_at) WHERE published_at IS NULL;

4) Uygulama katmanı

pseudo begin tx domainChange () # INSERT/UPDATE in domain table insert into outbox (event) # event with aggregate/tenant commit tx keys

İşlem başarılı olursa, giden kutusundaki olayın var olduğu garanti edilir. Uygulama bir taahhütten sonra düşerse, yayıncı yetişir.

5) Yayıncı (okuyucu - yayıncı)

Görevler:
  • Periyodik olarak yayınlanmamış olayları okuyun ('published _ at IS NULL've' available _ at <= now () '), gruplar.
  • Otobüs/sıraya yayınlamaya çalışın; Başarılı olursa, 'published _ at' işaretini işaretleyin.
  • Hata durumunda - 'girişimleri' artırın, gelecek için 'available _ at' koyun (üstel geri alma), 'hata' yazın.
  • Kiracılar/anahtarlar üzerindeki sınırlara saygı gösterin (adalet), ürünü engellemeyin.
Sözde kod:
pseudo loop:
events = select from outbox where published_at is null and available_at <= now()
order by occurred_at limit BATCH_SIZE for update skip locked

for e in events:
try:
broker. publish(topicFor(e), serialize(e. payload), headers(e))
markPublished(e. id, now())
except Retryable:
backoff = computeBackoff(e. attempts)
reschedule(e. id, now()+backoff, attempts+1, last_error)
except NonRetryable:
moveToDLQ (e) or markError (e) # by sleep (POLL_INTERVAL) policy
💡 'FOR UPDATE SKIP LOCKED' yayıncı rekabetini ortadan kaldırır.

6) Idempotency ve veri tekilleştirme

Tüketici tarafında (Inbox/Idempotency store):
sql
CREATE TABLE inbox (
consumer_name  TEXT,
event_id    UUID,
processed_at  TIMESTAMP NOT NULL,
PRIMARY KEY (consumer_name, event_id)
);

Algoritma: Bir olayı alırken, önce 'gelen kutusuna' INSERT 'yazmayı deneyin; Önemli bir çatışma varsa, olay zaten ele alındı - no-op. Sırada iş mantığı var.

Yayıncı tarafında: Başlıklarda 'Idempotency-Key' (örneğin, 'event _ id'), böylece bus/broker/proxy kopyaları filtreleyebilir.

7) Düzen ve nedensellik

'Agregate _ id'ile yerel düzen,' ocured _ at 'sıralanarak ve "anahtarla" yayınlanarak sağlanır.
Bölümlemeli log-veriyolları için - 'agregate _ id'/' tenant _ id' anahtarıyla bölümleme, böylece bir toplamın olayları aynı bölümlemede olur.
Sipariş kritikse, çapraz akışlı tek tuşlu yayıncı yarışlarından kaçının.

8) CDC (Veri Yakalama Değişikliği)

Etkin bir yayıncı yerine CDC'yi kullanabilirsiniz: Motor, veritabanı işlem günlüğünü okur ve 'giden kutusu' satırlarını otobüse çevirir. artıları - veritabanı üzerinde minimum yük, tam sıra, yoklama yok. Dezavantajları - operasyonun komplikasyonu ve DBMS'nin özelliklerine bir bağ. Her iki yaklaşım da geçerlidir; Yetkinliklere ve SLO'ya göre seçim yapın.

9) Hatalar, DLQ ve Redrive

Retryable (ağ, limitler) - 'girişimleri' artırın, 'available _ at'i erteleyin (üstel geri dönüş + jitter).
Geri alınamaz (geçersiz şema/sözleşme) - zengin meta verilerle DLQ/Dead-Letter Topic'e aktarılır.
Güvenli Redrive: Gruplar, Oran Sınırı, Planın Doğrulanması, Üretim Trafiğinin Altındaki Öncelik.

10) Çok kiracılık ve limitler

Gerekli etiketler: 'tenant _ id', 'plan', 'bölge' - 'giden kutusunda. Başlıklar.
Kiracı başına adalet: Yayıncı, yayınların "pencerelerini've girişimlerin sınırlarını kiracılara dağıtır.
Yerleşim: çıkış kutusunu etki alanı verileriyle aynı bölgede saklamak; Bölgeler arası yayın - yalnızca toplamlar/özetler.

11) Güvenlik ve uyumluluk

Kiracı/bölge politikasında yük/başlıklarda PII baskısı.
Veri yolu yabancı ise yükün imzası/şifrelenmesi.
Tüm durum geçişlerini denetleyin: oluşturulan, yayınlanan, hata, yeniden yazma.

12) Gözlemlenebilirlik

Metrikler:
  • Yayın gecikmesi ('şimdi - occurred_at' p50/p95/p99).
  • Başarı oranı, hata oranı, neden dağılımı.
  • Giden kutusu boyutu (yayınlanmamış sayısı), yeniden dener/sn
  • Kiracı başına grafikler verim ve gecikme.
İzleme:
  • Korelasyon 'event _ id'/' aggregate _ id'/' saga _ id'; "db-tx", "yayınla", "yeniden dene".
  • Ek açıklamalar: 'girişim', 'backoff _ ms', 'dlq = true'.
Günlükler:
  • Başarı için kısa kayıtlar; Hata/redrave başına tüm ayrıntılar.

13) Test ve kaos

Atomisite testi: Yayınlanmadan önce bir etki alanı işlemi yaptıktan sonra yapay olarak "düşüş" - olay daha sonra serbest bırakılmalıdır.
Yinelenen test: Aynı olayı birkaç kez yayınlıyoruz - tüketici tam olarak bir efekt (gelen kutusu) gerçekleştiriyor.
Sipariş testi: bir agrega ile olayların toplu - dizi/idempotans kontrolü.
Kaos: komisyoncu hatası, veritabanı gecikmesinde artış, bölünmüş beyin yayıncıları, saat eğriliği.

14) Yapılandırma şablonları (örnek)

yaml outbox:
poll_interval_ms: 200 batch_size: 200 order_by: occurred_at backoff:
strategy: exponential_full_jitter initial_ms: 250 max_ms: 10_000 max_attempts: 20 fairness:
per_tenant_parallelism: 4 per_key_serial: true

publisher:
rate_limit_per_sec: 500 headers:
idempotency_key: event_id schema_version: v3 dlq:
enabled: true topic: myapp. events. dlq include_metadata:
- error
- attempts
- source_table
- tenant_id
- aggregate_id

15) Sagalar ve geri çekilmelerle entegrasyon

Giden kutusu - saga adımları için "güvenlik taşıma": yerel işlem efekt ve komut/olay yazar; yayın - güvenilir ve dozlu.
Tekrarlama ve geri alma politikaları 'Retry-After've Devre Kesici ile tutarlı olmalıdır; "Retray fırtınası'ndan kaçının.

16) Tipik hatalar

Etki alanı durumu işledikten sonra bir olay yazarlar - düşme sırasında kayıp mümkündür.
'Outbox'ta dizin/arşiv yok - yayınlama gecikmesi artar.
'SKIP LOCKED' olmadan veya sharding olmadan yayıncı - rekabet ve engelleme.
Tüketiciler arasında idempotency eksikliği - kopyalar ve yan etkiler.
DLQ/günlüklerde maskelemeden PII karıştırma.
Adil olmayan tek bir küresel yayıncılık kuyruğu - "gürültülü'bir kiracı herkesi yavaşlatır.
Gecikme izleme eksikliği - gizli bozulma.

17) Hızlı strateji seçimi

Başlangıç seviyesi: Veritabanından yoklama, 100-500 parti, tam jitter backoff, tüketiciler için gelen kutusu.
Yüksek yük: İşlem günlüğünden CDC, 'tenant _ id/aggregate _ id'ile sharding, kiracı tarafından WFQ.
Toplama göre katı düzen: anahtar başına seri yayın (mutex), konunun bir anahtarla bölünmesi.
Uyumluluk/PII: yük şifreleme, DLQ sürümü, bölgesel giden kutusu.

18) Satış öncesi kontrol listesi

  • Etki alanı değişiklikleri ve 'outbox'olarak yazılması aynı işlemde gerçekleşir.
  • Yayıncı toplu işler, 'SKIP LOCKED' kullanır, jitter ve limitlerle geri çekilir.
  • Tüketiciler idempotent (tablo 'gelen kutusu'/deadup log).
  • DLQ ve Secure Release yapılandırılmıştır.
  • p95/p99 eşiklerinde gecikme/hata ve uyarı metrikleri.
  • Anahtar sırası garantilidir (partiler/diziler).
  • Arşiv/saklama 'dış kutu've yayınlanan kayıtları temizleyin.
  • PII politikaları ve devlet geçiş denetimi.
  • Commit ve yayınlama, kopyalar ve sipariş arasındaki testleri bırakın.
  • Olay sözleşmesi belgeleri (şemalar/sürümler/uyumluluk).

Sonuç

Giden kutusu deseni, "DB ↔ veri yolu'nun" kırılgan "demetini güvenilir bir boru hattına dönüştürür: atomik durum fiksasyonu, garantili ('en az bir kez" olsa da) yayın, idempotent aboneler ve kontrollü redrave. Uygun telemetri, limitler ve şema disiplini ile, dağıtılmış işlemlerin karmaşıklığını azaltarak ve sistemin çökmelere ve pik yüklere karşı direncini artırarak pratik tam olarak bir kez davranış sağlar.

Contact

Bizimle iletişime geçin

Her türlü soru veya destek için bize ulaşın.Size yardımcı olmaya her zaman hazırız!

Telegram
@Gamble_GC
Entegrasyona başla

Email — zorunlu. Telegram veya WhatsApp — isteğe bağlı.

Adınız zorunlu değil
Email zorunlu değil
Konu zorunlu değil
Mesaj zorunlu değil
Telegram zorunlu değil
@
Telegram belirtirseniz, Email’e ek olarak oradan da yanıt veririz.
WhatsApp zorunlu değil
Format: +ülke kodu ve numara (örneğin, +90XXXXXXXXX).

Butona tıklayarak veri işlemenize onay vermiş olursunuz.