Topik temu duga representatif

Bagaimanakah anda mereka bentuk peti keluar transaksional (transactional outbox) untuk ketekalan pangkalan data dan mesej?

BackendSukar
Pasukan Editorial Offer.ccDiterbitkan Dikemas kini

Soalan

Perkhidmatan pesanan mesti mengemas kini pangkalan datanya dan menerbitkan peristiwa dalam satu permintaan, tetapi pangkalan data dan broker tidak boleh berkongsi transaksi teragih. Reka bentuk transactional outbox dan terangkan tingkah laku geganti, mesej pendua, pengisihan, pemulihan, dan pembersihan.

1. Soalan

Apabila pesanan dibuat, perkhidmatan pesanan mesti melakukan komit pada keadaan dan menerbitkan peristiwa OrderCreated untuk pengguna inventori dan pemberitahuan. Pangkalan data dan broker tidak mempunyai komit dua fasa (two-phase commit) yang dikongsi. Reka bentuk transactional outbox supaya ranap sistem proses tidak menghilangkan peristiwa secara senyap, sementara penghantaran pendua dan tunggakan geganti kekal terkawal.

2. Kekangan dan penjelasan

  • Data pesanan dan jadual outbox berkongsi satu pangkalan data transaksional tempatan.
  • Broker menyediakan penghantaran sekurang-kurangnya sekali (at-least-once delivery), tanpa pengisihan global atau penghantaran transaksional.
  • Ketekalan akhirnya (eventual consistency) boleh diterima; pengguna inventori mestilah idempoten.
  • Terangkan pengisihan mengikut agregat, sama ada pengisihan rentas agregat diperlukan, dan tetingkap pengekalan/pemadaman.

3. Pendekatan teras

Tulis perubahan pesanan dan satu baris outbox dalam transaksi pangkalan data yang sama. Baris tersebut membawa event_id unik, kunci agregat, jenis peristiwa, jujukan, muatan, masa penciptaan, dan keadaan terbitan. Komit yang berjaya menjadikan kedua-dua data perniagaan dan peristiwa yang belum selesai tahan lama; pengembalian (rollback) tidak mendedahkan kedua-duanya, sekali gus menghapuskan tetingkap penulisan dwi di peringkat aplikasi.

Geganti bebas melakukan pengundian (polling) atau melanggan outbox, menerbitkan ke broker, dan kemudian menandakan baris tersebut sebagai dihantar. Jika proses terhenti antara pengesahan penerimaan (acknowledgement) broker dan kemas kini status, peristiwa tersebut boleh diterbitkan semula. Oleh itu, pengguna menyahduplikasi mengikut event_id dan bukannya menganggap penghantaran tepat sekali (exactly-once delivery).

4. Pelaksanaan rujukan

text
createOrder(command):
  begin transaction
  order = insert orders(...)
  event = insert outbox(
    event_id=uuid(), aggregate_id=order.id,
    aggregate_version=order.version, type="OrderCreated",
    payload=serialize(order), status="pending"
  )
  commit
  return order.id

relayBatch():
  rows = select pending outbox rows
         order by aggregate_id, aggregate_version, created_at
         for update skip locked limit BATCH_SIZE
  for row in rows:
    try:
      broker.publish(key=row.aggregate_id, id=row.event_id, body=row.payload)
      mark_sent(row.event_id)  // conditional update
    except transient_error:
      increment_attempts_and_schedule_retry(row.event_id)

consume(message):
  begin transaction
  inserted = insert processed_messages(message.id) on conflict do nothing
  if inserted:
    apply_business_change(message)
  commit

5. Kebolehpercayaan dan ketepatan

Jika transaksi perniagaan dikomit tetapi geganti ranap sebelum penerbitan, baris yang belum selesai akan ditemui melalui imbasan kemudian. Jika penerbitan berjaya tetapi kemas kini status ranap, pusingan seterusnya akan menerbitkannya semula. Oleh itu, semantik hujung-ke-hujung adalah sekurang-kurangnya sekali; jadual penyahduplikasian pengguna atau kunci keidempotensian perniagaan mesti berkongsi transaksi dengan kemas kini perniagaan pengguna.

Pengisihan mengikut agregat boleh menggunakan versi monotonik dan pemetakan mengikut kunci agregat; jangan menjanjikan pengisihan global merentas agregat. Medan SELECT ... FOR UPDATE SKIP LOCKED atau pajakan (lease) menghalang berbilang geganti daripada menuntut baris yang sama, tetapi ia tidak menggantikan keidempotensian pengguna. Indeks keadaan, masa percubaan semula, dan masa penciptaan, kemudian arkibkan atau padamkan baris lama dengan selamat untuk mengehadkan pertumbuhan jadual.

6. Tindakan susulan dan perangkap

  • Memadamkan baris serta-merta selepas penerbitan "berjaya" boleh mewujudkan jurang yang tidak boleh dipulihkan jika pengesahan penerimaan hilang; kekalkan keadaan penghantaran atau simpan rekod audit terlebih dahulu.
  • Had masa tamat pengesahan penerimaan broker tidak membuktikan bahawa broker terlepas mesej tersebut, jadi percubaan semula mesti bertolak ansur dengan pendua.
  • Menulis ke pangkalan data terlebih dahulu dan kemudian memanggil broker di dalam pengendalian ralat aplikasi masih mempunyai perlumbaan penulisan dwi; try/catch tidak dapat menjadikannya atomik.
  • Jika outbox dan jadual perniagaan tidak boleh berkongsi sempadan transaksi, gunakan CDC, pemesejan transaksional, atau takrifkan semula jaminan ketekalan.

7. Bacaan lanjut

Bandingkan geganti pengundian dengan geganti CDC: pengundian lebih mudah digunakan tetapi menambah imbasan dan kependaman, manakala CDC mengurangkan kependaman dengan kos tangkapan log dan kebergantungan operasi. Bincangkan mesej beracun (poison messages), penundaan eksponen (exponential backoff), baris gilir surat mati (dead-letter queues), pemantauan usia tertunda, dan keserasian skema pengguna.

8. Mata pemarkahan temu duga

Boleh mengesan tetingkap penulisan dwi

Calon harus menerangkan sebab transaksi tempatan biasa tidak boleh mengomitkan kemas kini pangkalan data dan penghantaran broker bersama-sama, kemudian meletakkan perubahan pesanan dan baris outbox dalam satu transaksi.

Boleh menerangkan sekurang-kurangnya sekali dan keidempotensian

Mereka harus menerangkan tetingkap ranap geganti yang mewujudkan pendua dan membuat pengguna menyahduplikasi mengikut ID peristiwa dalam transaksi yang sama seperti kemas kini perniagaannya.

Boleh mengendalikan pengisihan dan kebersamaan

Mereka harus membezakan susunan mengikut agregat daripada susunan global dan menerangkan cara kunci petak, versi, kunci (locks), atau pajakan mengehadkan tuntutan serentak.

Boleh merangkumi sempadan operasi

Mereka harus mencadangkan penundaan percubaan semula, surat mati, amaran tunggakan, pembersihan arkib, dan evolusi skema dan bukannya hanya berhenti pada definisi jadual.

Sumber awam

Soalan berkaitan