Topik temu duga representatif

Temu Duga Reka Bentuk Sistem: Mereka Bentuk Sistem Penempahan Tiket Permintaan Tinggi

Reka bentuk sistemSukar
Pasukan Editorial Offer.ccDiterbitkan Dikemas kini

Soalan

Reka bentuk sistem penempahan tiket permintaan tinggi untuk acara dengan 50,000 tempat duduk yang ditetapkan. Dua juta pengguna tiba dalam lima minit pertama jualan, dengan lonjakan trafik pinggir mencecah 50,000 permintaan sesaat. Benarkan kemasukan sehingga 10,000 pembeli peta tempat duduk serentak dan kendalikan 2,000 percubaan pegangan serta 1,000 pengesahan pembayaran sesaat pada waktu puncak. Pegangan tempat duduk bertahan selama lima minit. Terangkan ruang menunggu maya, API, model data, mesin keadaan tempat duduk dan pesanan, ketekalan, penamatan tempoh pegangan, kegagalan pembayaran, penskalaan, dan pengesahan, sambil menjamin bahawa satu tempat duduk dijual paling banyak sekali sahaja.

Kehendak Soalan dan Konteks Berkaitan

Reka bentuk sistem penempahan tiket untuk konsert, acara sukan atau pameran berpermintaan tinggi. Satu acara mempunyai 50,000 tempat duduk yang ditetapkan. Dua juta pengguna tiba dalam lima minit pertama jualan, dan trafik pinggir memuncak pada 50,000 permintaan sesaat. Sistem ini membenarkan tidak lebih daripada 10,000 pembeli peta tempat duduk serentak dan mengendalikan sehingga 2,000 percubaan pegangan serta 1,000 pengesahan pembayaran sesaat. Tempoh pegangan berlangsung selama lima minit; tempat duduk yang dipegang tetapi tidak dibeli mesti boleh dijual semula.

Andaikan penyedia pembayaran menyokong pengesahan (authorization) dan pengambilan (capture) yang berasingan. Sasaran p99 peta tempat duduk adalah di bawah 500 milisaat, penciptaan pegangan di bawah 300 milisaat, dan pembacaan status pesanan di bawah 200 milisaat. Jumlah ketibaan, sasaran kependaman, tempoh pegangan, dan kadar pembayaran ialah andaian temu duga, bukan tanda aras yang diterbitkan untuk mana-mana syarikat tiket. Peraturan ketepatan teras ialah satu tempat duduk pada satu acara hanya milik paling banyak satu pesanan jualan yang sah. Apabila ketersediaan merosot, perkhidmatan boleh menjeda kemasukan atau menolak pegangan; ia tidak boleh meneka inventori dan terus menjual.

Skop merangkumi pelayaran acara, ruang menunggu maya, peta tempat duduk, pegangan atomik pelbagai tempat duduk, daftar keluar (checkout), pengesahan pra-pengeluaran, tamat tempoh, dan pemulihan. Penciptaan acara, penetapan harga dinamik, jualan semula sekunder, perakaunan bayaran balik, dan sistem pengesanan bot yang lengkap berada di luar skop, tetapi jawapan hendaklah mentakrifkan cara ia memenuhi sempadan inventori dan pembayaran. Bahan reka bentuk sistem awam 2026 masih membentangkan penempahan tiket sebagai masalah gabungan keserentakan dan lonjakan pengguna. Bahan awam Ticketmaster juga menerangkan aliran sebenar di mana pembeli memasuki ruang menunggu maya dan mencapai pemilihan tempat duduk serta daftar keluar pada kadar yang terkawal.

Perkara yang Dinilai oleh Penemu Duga

Isyarat pertama ialah sama ada calon memisahkan keadilan giliran daripada ketepatan inventori. Ruang menunggu maya melindungi pelayan asal (origin) dan mengawal kemasukan ke dalam jualan. Ia tidak boleh menghalang dua pembeli yang dibenarkan masuk daripada meminta tempat duduk yang sama. Transaksi inventori berwibawa mesti menyediakan pengecualian mutlak (final exclusion).

Isyarat kedua ialah perbezaan antara kunci baris (row lock) pangkalan data dan pegangan perniagaan (business hold). Kunci baris PostgreSQL berada di dalam transaksi pendek dan dilepaskan apabila transaksi berakhir. Mengekalkan sambungan dan transaksi dibuka selama lima minit semasa pembeli memasukkan butiran dan membayar adalah tidak selamat. Makna perniagaan yang lebih panjang mestilah keadaan tahan lama dengan hold_id dan expires_at.

Isyarat ketiga ialah peralihan keadaan yang peka terhadap masa dan percubaan semula. Pekerja pembersihan tamat tempoh yang tertangguh tidak boleh melepaskan tempat duduk yang kini dipegang oleh pembeli baharu atau yang telah dijual. Tamat masa klien tidak boleh mencipta pegangan atau pembayaran kedua. Setiap peralihan memeriksa keadaan semasa, pemilik, versi, dan tarikh akhir, manakala kunci keidempotenan (idempotency key) mendapatkan semula hasil asal.

Isyarat keempat ialah sempadan pembayaran yang betul. Pengesahan mungkin berjaya manakala pengesahan tempatan gagal; transaksi jualan mungkin dilakukan (commit) manakala responsnya hilang; pengambilan mungkin berjaya sebelum webhooknya tiba. Jawapan yang kukuh mengekalkan rekod pesanan dan operasi pembayaran serta menumpu (converge) melalui carian, webhook, dan penyelarasan. Mereka tidak menganggap respons yang hilang sebagai kegagalan.

Akhir sekali, kapasiti dan pengesahan mesti menangani kekangan utama (bottleneck) yang sebenar. CDN, caching, dan replika bacaan boleh menyerap pelayaran. Operasi tulis tempat duduk untuk satu acara hangat masih harus berada pada satu shard berwibawa transaksional. Memecahkan tempat duduk satu acara merentasi shard tulis terlalu awal menukar pegangan tiga tempat duduk biasa kepada transaksi teragih.

Soalan untuk Dijelaskan Sebelum Menjawab

  • Adakah tempat duduk ditetapkan atau kemasukan am (general admission)? Tempat duduk yang ditetapkan memerlukan keadaan eksklusif bagi setiap tempat duduk. Kemasukan am lebih baik dimodelkan sebagai kuantiti yang tersedia bagi setiap peringkat tiket dengan pengurangan bersyarat yang tidak boleh menjadi negatif.
  • Adakah permintaan berbilang tempat duduk mesti bersifat semua-atau-tiada (all-or-nothing)? Kehendak soalan ini memerlukan pegangan semua-atau-tiada untuk satu hingga enam tempat duduk. Kejayaan separa mengubah penetapan harga, tingkah laku pelepasan, dan pengalaman pembeli.
  • Apakah dasar keadilan barisan giliran? FIFO memberi ganjaran kepada ketibaan yang lebih awal; pelepasan rawak mengurangkan kesan perbezaan rangkaian skala milisaat. Dasar tersebut mesti didedahkan dan kekal stabil dan bukannya berubah di pertengahan jualan sambil masih mendakwa keadilan mengikut urutan.
  • Bolehkah pengesahan pembayaran dan pengambilan dipisahkan? Jika ya, sahkan (authorize), sahkan tempat duduk, kemudian ambil (capture). Pengambilan serta-merta memerlukan pampasan apabila wang diambil tetapi pengesahan tempat duduk gagal.
  • Apakah had tiket bagi setiap akaun? Kuatkuasakannya pada kedua-dua pengesahan pegangan dan pesanan. Sekatan berasaskan penyemak imbas sahaja mudah dipintas.
  • Bolehkah beberapa rantau menulis pada acara yang sama? Reka bentuk asas menetapkan satu lokasi tulis (write home) bagi setiap acara dan menyediakan pelayaran serta giliran di tempat lain. Operasi tulis berbilang rantau serentak memerlukan konsensus rentas rantau atau inventori yang diperuntukkan lebih awal dan mengubah kedua-dua kependaman dan tingkah laku kegagalan.
  • Berapa barukah peta tempat duduk perlu dikemas kini? Jika kependaman beberapa saat boleh diterima, gunakan syot kilat (snapshot) ditambah perubahan (deltas). Setiap keadaan AVAILABLE yang dipaparkan kekal sebagai nasihat sehingga transaksi pegangan berjaya.
  • Bagaimana jika pegangan tamat tempoh semasa pengesahan pembayaran masih berjalan? Tentukan tempoh tangguh PAYMENT_PENDING terhad yang tunggal. Jangan perbaharui selama-lamanya atau jual semula semasa hasil pembayaran tidak diketahui.

Rangka Kerja Jawapan 30 Saat

“Saya akan mengekalkan dua juta ketibaan dalam ruang menunggu maya berskop acara dan mengeluarkan token kemasukan bertandatangan jangka pendek hanya pada kadar yang disokong oleh shard inventori, penyedia pembayaran, dan pengeluar tiket. Pelayaran dan peta tempat duduk menggunakan CDN, caching, dan delta berversi; operasi tulis pegangan pergi ke shard pangkalan data berwibawa tunggal bagi acara tersebut. Transaksi pendek mengunci tempat duduk yang dipilih dalam susunan terisih dan menulis satu hold_id dengan tamat tempoh lima minit masa pangkalan data hanya jika setiap tempat duduk tersedia atau tamat tempoh. Tiada kunci pangkalan data kekal terbuka semasa daftar keluar. Barisan tertangguh mempercepatkan pembersihan tamat tempoh, tetapi pelepasan masih memadankan pegangan, keadaan, dan tarikh akhir secara bersyarat. Pembayaran menggunakan ID operasi yang stabil untuk mengesahkan terlebih dahulu. Selepas pengesahan, transaksi mengesahkan semula pegangan dan melakukan commit tempat duduk, pesanan, dan outbox sebagai terjual sebelum pengambilan. Sebarang tamat masa menjadi tidak diketahui dan menumpu melalui webhook, carian, dan penyelarasan. Saya akan membuktikan reka bentuk ini dengan persaingan tempat duduk yang sama, perlumbaan tamat tempoh/pembayaran, respons yang hilang, mesej pendua, dan kegagalan shard.”

Penerangan Mendalam Langkah demi Langkah

Langkah 1: Tukar volum kepada sasaran kawalan kemasukan

Dua juta ketibaan dalam tempoh 300 saat mencatatkan purata kira-kira 6,667 sesaat. Puncak pinggir 50,000 permintaan sesaat menunjukkan bahawa detik pembukaan dan muat semula penyemak imbas adalah jauh lebih mendadak daripada purata. Inventori diperuntukkan untuk hanya 2,000 percubaan pegangan dan 1,000 pengesahan pembayaran sesaat, jadi percubaan semula pinggir tidak boleh mencapai perkhidmatan inventori secara terus.

Setiap pegangan boleh mengandungi sehingga enam tempat duduk, jadi 2,000 permintaan sesaat boleh menyebabkan sebanyak 12,000 keputusan baris tempat duduk sesaat sebelum konflik dan rollback. Ujian kapasiti memerlukan taburan bahagian hangat (hot-section) yang condong; menyebarkan 12,000 keputusan tersebut secara sama rata merentasi 50,000 tempat duduk akan menyembunyikan persaingan.

Ruang menunggu maya diasingkan oleh event_id dan boleh menerima pelawat sebelum jualan. Ia merekodkan kohort ketibaan, masa masuk, akaun, dan isyarat risiko. Apabila dibenarkan masuk, pelawat menerima admission_token bertandatangan jangka pendek yang terikat pada acara dan akaun. Masukan jualan mengesahkan token, tamat tempoh, dan satu sesi aktif; trafik tidak sah ditolak di pinggir. Kadar kemasukan bertindak balas terhadap masa menunggu kunci inventori, p99 pegangan, ralat pembayaran, pembeli aktif, dan kadar penyiapan. Apabila pangkalan data menjadi perlahan, kurangkan kemasukan dan bukannya menyembunyikan persaingan tulis di sebalik lebih banyak replika bacaan.

Dokumentasi ruang menunggu awam Cloudflare menerangkan susunan FIFO daripada cap masa di mana pelawat mula-mula mencapai barisan aktif dan mod rawak yang memilih pelawat yang menunggu. Ini adalah dasar produk, bukan mekanisme ketekalan pangkalan data. Malah FIFO memerlukan peraturan yang jelas untuk keperincian masa, sambungan semula, berbilang peranti, autoriti jam, dan bot. Ia tidak boleh menjanjikan susunan mutlak permintaan demi permintaan merentasi rangkaian global.

Langkah 2: Asingkan pelayaran, paparan tempat duduk, dan inventori berwibawa

Butiran acara, peta tempat statik, dan penjelasan harga boleh berada dalam CDN atau cache. Paparan tempat duduk menggabungkan syot kilat berversi dengan delta status. Klien mula-mula menerima snapshot_version, kemudian menggunakan perubahan yang mengandungi seat_id, status baharu, dan versi yang lebih tinggi. Ia memuatkan semula syot kilat selepas terputus sambungan atau terdapat jurang versi. Jika 10,000 pembeli aktif membuat pengundian (polling) setiap lima saat, mereka menjana kira-kira 2,000 bacaan sesaat. Penghantaran delta mengurangkan pembacaan peta penuh berulang, tetapi ia tidak menjadi punca kebenaran inventori.

Peta tempat duduk mungkin lapuk seketika. Pembeli boleh melihat AVAILABLE dan masih tewas dalam perlumbaan pegangan. Cache tidak boleh mengesahkan jualan atau menerima pegangan daripada data lapuk semasa pangkalan data tidak tersedia. Ini memisahkan laluan pelayaran berketersediaan tinggi daripada laluan tulis inventori yang konsisten secara teguh.

Tetapkan setiap acara kepada satu shard tulis utama dan gunakan transaksi hubungan di dalamnya. Acara berbeza diskalakan secara mendatar mengikut event_id, manakala acara yang sangat hangat mungkin menerima shard atau kumpulan sumber khusus. Lima puluh ribu baris tempat duduk bukanlah masalah kapasiti. Masa menunggu kunci, kehabisan sambungan, dan ribut percubaan semula yang disebabkan oleh banyak permintaan yang menyasarkan tempat duduk yang sama adalah puncanya.

Langkah 3: Tentukan API, keadaan, dan invarian

API teras boleh kekal kecil:

text
POST /events/{eventId}/holds
  { seatIds, idempotencyKey, admissionToken }
  -> { holdId, status, expiresAt, seats }

POST /holds/{holdId}/checkout
  { paymentMethodToken, idempotencyKey }
  -> { orderId, paymentStatus, nextAction }

GET /orders/{orderId}
  -> { orderStatus, paymentStatus, seats }

Model data minimum ialah:

text
SeatInventory(event_id, seat_id, price_version, status,
              hold_id, hold_expires_at, order_id, version)
Hold(hold_id, event_id, account_id, status, expires_at,
     idempotency_key, request_digest, created_at)
Order(order_id, hold_id, account_id, amount_minor, currency,
      status, payment_operation_id, created_at)
PaymentOperation(operation_id, order_id, provider_reference,
                 kind, status, idempotency_key, updated_at)
Outbox(event_id, aggregate_id, event_type, payload, published_at)

Invarian kritikal ialah:

text
one (event_id, seat_id) has at most one valid SOLD order
all seats in one hold share the event, account, and expiry
only the current hold_id may move HELD to SOLD or release it
order confirmation revalidates price version, quantity, limit, and total
one idempotency key describes one immutable request; changed parameters are rejected

Wang ialah integer dalam unit kecil mata wang. Jumlah yang diserahkan oleh klien adalah tidak berwibawa; pelayan mengira semula daripada versi harga yang dikunci. admission_token memberikan kemasukan ke jualan, bukan pemilikan mana-mana tempat duduk.

Langkah 4: Cipta pegangan berbilang tempat duduk atomik dengan transaksi pendek

Satu permintaan memilih paling banyak enam tempat duduk. Transaksi menyusun mengikut seat_id, kemudian mengunci baris dengan SELECT ... FOR UPDATE dalam susunan tetap itu, mengurangkan kebuntuan (deadlock) yang disebabkan oleh susunan kunci yang bertentangan. Jika setiap baris ialah AVAILABLE atau HELD yang telah tamat tempoh, transaksi menulis hold_id dan expires_at = database_now + 5 minutes yang sama pada semua baris dan memasukkan Hold serta peristiwa outbox. Jika satu baris terjual atau milik pegangan lain yang belum tamat tempoh, keseluruhan transaksi akan di-rollback.

UPDATE bersyarat dengan predikat status dan tarikh akhir ialah satu lagi pelaksanaan yang sah, dengan syarat perkhidmatan memeriksa bahawa kiraan baris yang dikemas kini bersamaan dengan kiraan yang diminta. Dalam mana-mana pendekatan, keputusan dan penulisan mesti berkongsi satu transaksi berwibawa. Memperoleh kunci Redis dan menulis pangkalan data secara tak segerak mencipta dua sumber kebenaran apabila satu berjaya dan satu lagi gagal. Membaca “tersedia” dan kemudian menulis tanpa syarat mempunyai perlumbaan asal yang sama.

PostgreSQL mendokumenkan bahawa kunci baris menyekat penulis dan pengunci pada baris yang sama dan dilepaskan pada akhir transaksi. Oleh itu, daftar keluar lima minit pembeli ialah keadaan data yang tahan lama, bukan transaksi pangkalan data lima minit. Lakukan commit dan lepaskan sambungan serta-merta, kemudian buka transaksi pendek baharu untuk setiap peralihan kemudian.

Lakukan commit rekod keidempotenan dengan hasil pegangan. Jika perkhidmatan melakukan commit pegangan dan terhenti (crash) sebelum membalas, percubaan semula dengan idempotencyKey yang sama mengembalikan holdId asal. Kunci baharu memasuki perlumbaan baharu. Simpan ringkasan permintaan (request digest) supaya kunci yang sama tidak boleh digunakan semula untuk kumpulan tempat duduk yang berbeza.

Langkah 5: Pastikan tamat tempoh betul walaupun tugas lewat

Jana hold_expires_at daripada masa pangkalan data. Pembacaan boleh memaparkan pegangan yang telah tamat tempoh sebagai tersedia, tetapi menuntutnya semula masih memeriksa tarikh akhir dalam transaksi tulis. Mencipta pegangan menjadualkan mesej tertangguh, dan imbasan berkala menyediakan pampasan. Kedua-duanya mempercepatkan peralihan eksplisit kembali kepada AVAILABLE; tiada satu pun yang menjadi sumber tunggal bagi ketepatan tamat tempoh.

Operasi pelepasan mesti menyerupai:

text
UPDATE seat_inventory
SET status = 'AVAILABLE', hold_id = NULL, hold_expires_at = NULL
WHERE event_id = :eventId
  AND hold_id = :holdId
  AND status = 'HELD'
  AND hold_expires_at <= database_now;

Mesej tertangguh boleh diduplikasi, lewat, atau tidak mengikut urutan. Jika hold_id baharu kini memiliki tempat duduk tersebut, predikat lama tidak lagi sepadan. Jika tempat duduk itu SOLD, statusnya tidak lagi sepadan. Melepaskan melalui seat_id sahaja boleh memadamkan pegangan sah pembeli lain.

Pengesahan pembayaran tambahan boleh mendekati tarikh akhir pegangan. Sebelum pengesahan bermula, reka bentuk ini boleh memindahkan Hold.status pegangan yang sah secara atomik kepada PAYMENT_PENDING dengan satu lanjutan penangguhan yang terhad. Pendudukan penangguhan masih dikira dalam inventori aktif dan had akaun. Hasil yang masih tidak diketahui pada tarikh akhir baharu memasuki penyelarasan; klien tidak boleh melanjutkan selama-lamanya untuk memonopoli tempat duduk.

Langkah 6: Masukkan hasil pembayaran yang tidak diketahui ke dalam mesin keadaan

Daftar keluar mencipta payment_operation_id yang stabil dan menggunakan semula kunci keidempotenannya dengan penyedia. Dokumentasi API awam Stripe menerangkan bahawa mencuba semula permintaan dengan kunci keidempotenan yang sama mengembalikan hasil tersimpan daripada permintaan pertama. Objek gaya PaymentIntent juga mendedahkan keadaan kitaran hayat untuk pembayaran yang mungkin memerlukan pengesahan tambahan atau penyiapan tak segerak.

Gunakan urutan ini:

  1. Dalam transaksi pendek, sahkan pegangan, had tiket, harga, dan tarikh akhir, kemudian cipta operasi Order dan pengesahan. Jika tempoh tangguh diperlukan, pindahkan Hold.status ke PAYMENT_PENDING dalam transaksi yang sama.
  2. Panggil pengesahan pembayaran di luar transaksi. Tamat masa menjadi UNKNOWN; ia tidak mencipta operasi kedua.
  3. Selepas pengesahan disahkan, kunci tempat duduk sekali lagi, padankan hold_id, tetapkan semua tempat duduk kepada SOLD, tetapkan pesanan kepada CONFIRMED, dan tulis peristiwa outbox dalam satu transaksi.
  4. Lakukan pengambilan selepas commit. Pengambilan berulang menggunakan ID operasi yang sama. Pengeluaran tiket hanya menggunakan peristiwa pengesahan yang telah di-commit.
  5. Jika pengesahan berjaya tetapi pegangan tidak lagi dapat disahkan, batalkan (void) pengesahan. Jika transaksi jualan telah di-commit dan pengambilan tidak diketahui, kekalkan tempat duduk dan pesanan semasa webhook, carian aktif, dan penyelarasan menumpu. Jangan lepaskan dan menjualnya semula. Jika pengambilan gagal secara muktamad dan tidak boleh dicuba semula, batalkan pesanan dan lepaskan tempat duduknya dalam transaksi pampasan yang diaudit sebelum pengeluaran tiket.

Susunan ini membenarkan keadaan sementara "terjual, pengambilan belum selesai" tetapi tidak pernah memberikan tempat duduk yang sama kepada dua pembeli. Jika perniagaan hanya boleh mengambil serta-merta, caj yang berjaya diikuti oleh transaksi jualan yang gagal memerlukan pembatalan atau bayaran balik yang boleh diaudit. Keupayaan penyedia itu meningkatkan risiko pelanggan dan operasi serta harus dinyatakan secara eksplisit.

Keadaan tempat duduk dan pesanan bergerak secara monotonik. Pengalihan penyemak imbas ke halaman kejayaan tidak boleh membenarkan pengeluaran tiket. Hanya respons penyedia yang disahkan, webhook, atau carian aktif yang memajukan keadaan pembayaran. Nyahduplikasi webhook mengikut ID peristiwa penyedia dan terima peralihan yang sah sahaja.

Langkah 7: Reka bentuk kegagalan, penskalaan, dan degradasi

  • Shard acara tidak tersedia: Hentikan kemasukan dan pegangan baharu untuk acara tersebut serta kekalkan pengguna di ruang menunggu. Pelayaran mungkin menyatakan tempahan tidak tersedia buat sementara waktu; replika lapuk tidak boleh terus menjual.
  • Cache atau penghantaran delta gagal: Kembali kepada syot kilat berversi dengan kekerapan lebih rendah. Pangkalan data masih memutuskan pegangan.
  • Mesej tamat tempoh hilang: Tuntutan semula bersyarat dan imbasan pampasan masih memulihkan tempat duduk. Pantau tunggakan tamat tempoh dan pegangan tertunggak paling lama.
  • Penyedia pembayaran menjadi perlahan: Kurangkan kemasukan dan keserentakan daftar keluar serta kekalkan operasi yang tidak diketahui. Jangan tukar penyedia secara automatik dan mengambil risiko caj kedua.
  • Respons hilang selepas commit: Kunci keidempotenan mendapatkan semula pegangan, pesanan, atau operasi pembayaran asal.
  • Satu acara menjadi sangat hangat: Berikan ia sumber pangkalan data khusus, hadkan kadar mengikut acara, dan kurangkan bacaan yang tidak penting. Jangan pisahkan satu transaksi berbilang tempat duduk merentasi shard.
  • Satu rantau gagal: Setiap acara mempunyai satu lokasi tulis dan failover yang disahkan. Sebelum nod utama baharu mengambil alih, buktikan bahawa nod utama lama tidak lagi boleh menulis, mengelakkan jualan berlebihan aktif-aktif.

Ruang menunggu juga memerlukan daya tahan terhadap penyalinan token, main semula (replay), dan pintasan. Token ditandatangani, jangka pendek, dan terikat pada acara dan akaun; perkhidmatan mengehadkan sesi serentak dan kuantiti tiket, manakala trafik berisiko tinggi menerima pengesahan tambahan. Kawalan ini mengurangkan kelebihan bot. Kawalan tersebut tidak membuktikan secara bebas bahawa pembeli ialah manusia atau bahawa peruntukan adalah adil sepenuhnya.

Langkah 8: Sahkan invarian dengan suntikan kerosakan (fault injection)

Sebagai tambahan kepada ujian ciri, sahkan sifat yang boleh diperiksa oleh mesin:

text
count(valid SOLD orders for one seat) <= 1
every CONFIRMED order owns exactly its recorded seats
every SOLD seat points to one CONFIRMED or payment-reconciling order
an expiry action changes only its own hold_id
replaying one idempotent request does not create new business state

Hantar beribu-ribu klien serentak untuk satu tempat duduk dan jangkakan satu pegangan yang sah. Kemudian minta klien meminta set tiga tempat duduk yang sama dalam susunan berbeza untuk mengesahkan tingkah laku semua-atau-tiada, susunan kunci tetap, dan percubaan semula kebuntuan. Gerakkan masa merentasi sempadan tamat tempoh sambil menyelitkan pegangan baharu, mesej tamat tempoh, pengesahan pembayaran, dan pemastian. Tugas pembersihan lama tidak boleh sekali-kali mengubah keadaan baharu.

Matikan proses atau hilangkan respons serta-merta selepas commit pegangan, sebelum dan selepas pengesahan kembali, selepas commit jualan, selepas penyerahan pengambilan, dan sebelum serta selepas penerbitan outbox. Gandakan webhook dan mesej tertangguh; putuskan sambungan cache, penyedia pembayaran, dan nod utama pangkalan data. Nilaikan hasil menggunakan kiraan terjual peringkat acara, masa menunggu kunci, kadar konflik bersyarat, kadar tamat tempoh pegangan, usia pembayaran yang tidak diketahui, masa menunggu giliran dan kadar kemasukan, serta perbezaan penyelarasan pengeluaran tiket. HTTP 200 sahaja membuktikan sedikit perkara.

Contoh Jawapan Berkualiti Tinggi

“Saya akan membahagikan masalah ini kepada perlindungan trafik dan ketepatan inventori. Dua juta ketibaan dalam lima minit mencatatkan purata kira-kira 6,667 sesaat, dengan puncak pinggir 50,000 permintaan sesaat, manakala inventori hanya menerima 2,000 percubaan pegangan sesaat. Saya akan mencipta ruang menunggu maya berskop acara. Ia menyerap trafik muat semula di pinggir dan mengeluarkan token kemasukan jangka pendek yang terikat pada akaun mengikut kesihatan shard acara dan laluan pembayaran. Susunan giliran ialah dasar produk yang eksplisit; ia tidak menyediakan pengecualian tempat duduk.

Halaman acara dan peta tempat statik menggunakan CDN. Peta tempat duduk menggunakan syot kilat berversi ditambah delta dan mungkin lapuk beberapa saat; hanya pegangan yang menentukan. Setiap acara mempunyai satu shard tulis pangkalan data hubungan, jadi 50,000 tempat duduknya tidak dipecahkan merentasi shard. API pegangan menerima satu hingga enam ID tempat duduk yang disusun dan satu kunci keidempotenan. Transaksi pendek mengunci baris tersebut dan menulis satu hold_id dengan tamat tempoh lima minit masa pangkalan data hanya apabila setiap tempat duduk tersedia atau tamat tempoh. Jika tidak, semuanya gagal. Transaksi melepaskan kuncinya semasa commit; daftar keluar mengekalkan keadaan pegangan yang tahan lama, bukan kunci pangkalan data.

Barisan tertangguh dan pengimbas membersihkan pegangan yang telah tamat tempoh, tetapi setiap pelepasan memadankan hold_id, HELD, dan tarikh akhir. Oleh itu, mesej lama yang lewat tidak boleh melepaskan pegangan baharu atau tempat duduk yang telah dijual. Kunci keidempotenan dan ringkasan permintaan di-commit bersama pegangan, jadi respons yang hilang selepas commit hanya mendapatkan semula hasil asal.

Untuk pembayaran, gesaan mengandaikan pengesahan dan pengambilan berasingan. Saya mencipta operasi pembayaran yang stabil dan mengesahkan terlebih dahulu. Tamat masa adalah tidak diketahui dan menggunakan ID operasi yang sama untuk carian atau percubaan semula. Selepas pengesahan, transaksi mengesahkan semula pegangan, harga, had, dan tarikh akhir, kemudian memindahkan tempat duduk ke SOLD, pesanan ke CONFIRMED, dan menulis outbox. Pengambilan dan pengeluaran tiket menyusul. Jika pengesahan berjaya tetapi pengesahan tempat duduk gagal, saya membatalkan pengesahan tersebut. Jika tempat duduk disahkan dan pengambilan tidak diketahui, saya mengekalkan pesanan dan menumpu melalui webhook, carian, dan penyelarasan; saya tidak pernah melepaskan dan menjual semula.

Penskalaan adalah berskop acara: acara biasa berkongsi shard, acara hangat menerima sumber khusus, dan satu acara mempunyai satu lokasi tulis. Jika pangkalan data, penyedia pembayaran, atau pengeluar menjadi perlahan, ruang menunggu mengurangkan kemasukan dan boleh menjeda pegangan. Untuk pengesahan, beribu-ribu klien bersaing untuk satu tempat duduk dan set tempat duduk yang bertindih semasa saya menyuntik tamat tempoh lewat, kerosakan selepas commit, respons pembayaran yang hilang, pendua webhook, kehilangan cache, dan kegagalan nod utama. Reka bentuk ini lulus hanya jika ia membuktikan paling banyak satu pesanan terjual yang sah bagi setiap tempat duduk, tiada keadaan baharu daripada main semula, dan tiada pegangan baharu diubah oleh tindakan tamat tempoh lama.”

Kesilapan Biasa

  • Mengunci dalam Redis dan menulis inventori secara tak segerak → Kunci dan penulisan pangkalan data boleh tidak bersetuju, menghasilkan dua autoriti → Laksanakan syarat, pegangan tahan lama, dan hasil idempoten dalam satu transaksi pangkalan data berwibawa.
  • Memegang kunci baris untuk daftar keluar lima minit → Transaksi panjang memakan sambungan, menyekat penulis, dan sukar dipulihkan selepas pengabaian → Gunakan kunci hanya untuk peralihan dan wakilkan daftar keluar dengan keadaan pegangan yang tahan lama.
  • Menganggap ruang menunggu maya menghalang terlebih jualan → Ia mengawal kemasukan sementara pembeli yang dibenarkan masuk masih bersaing pada baris yang sama → Kuatkuasakan pengecualian secara berasingan dalam transaksi inventori.
  • Melepaskan tamat tempoh mengikut ID tempat duduk sahaja → Mesej lewat boleh memadamkan pegangan baharu atau keadaan terjual → Padankan hold_id, keadaan, dan tarikh akhir bersama-sama.
  • Mengenakan caj kerana peta tempat duduk menunjukkan tersedia → Model bacaan mungkin lapuk dan pembeli lain boleh menang terlebih dahulu → Dapatkan pegangan berwibawa sebelum pembayaran.
  • Melepaskan dan mencuba semula di bawah kunci baharu selepas tamat masa pembayaran → Operasi pertama mungkin telah berjaya, menyebabkan jualan semula atau caj pendua → Kekalkan keadaan yang tidak diketahui, gunakan semula ID operasi, dan tumpu melalui webhook, carian, dan penyelarasan.
  • Melakukan shard secara rawak pada setiap tempat duduk acara hangat → Satu pegangan berbilang tempat duduk merentasi shard dan kehilangan keatomikan mudah → Kekalkan acara pada satu shard tulis sehingga kapasiti yang diukur membuktikan pemisahan inventori yang lebih kompleks diperlukan.
  • Menjanjikan FIFO global yang ketat → Kependaman rangkaian, sambungan semula, pertukaran peranti, dan bot mengubah susunan yang boleh diperhatikan → Tentukan keperincian barisan giliran, identiti, sambungan semula, dan dasar risiko sebagai kontrak keadilan yang boleh disahkan.
  • Menguji beban hanya pada daya pemprosesan purata → Permintaan pembukaan tertumpu pada beberapa tempat duduk, menyembunyikan masa menunggu kunci dan ribut percubaan semula di sebalik taburan seragam → Uji tempat duduk hangat, kumpulan bertindih, lonjakan serta-merta, dan kebergantungan yang perlahan.

Soalan Susulan dan Maklum Balas

Susulan 1: Apakah yang berubah untuk kemasukan am apabila hanya kuantiti peringkat tiket yang tidak boleh terlebih dijual?

Gantikan keadaan setiap tempat duduk dengan InventoryBucket(event_id, tier_id, available, held, sold, version). Transaksi pegangan secara bersyarat memerlukan available >= quantity, mengurangkan sekali, dan mencipta pegangan. Tamat tempoh dan pengesahan masih menggerakkan kiraan secara idempoten mengikut hold_id. Peringkat yang sangat dipertandingkan boleh menggunakan beberapa baldi (buckets) untuk menyebarkan operasi tulis, tetapi satah kawalan kuota mesti memperuntukkan kapasiti baldi dan memastikan jumlahnya berada dalam inventori sebenar. Mengalih keluar pemilihan tempat duduk atomik memudahkan penyimpanan; perlumbaan tamat tempoh dan pembayaran tidak diketahui tetap wujud.

Susulan 2: Pengesahan mengambil masa purata 90 saat dan pengesahan tambahan boleh melebihi lima minit. Bagaimanakah anda menghentikan pegangan jangka panjang?

Periksa baki masa sebelum pembayaran bermula dan tolak aliran pengesahan baharu apabila masa yang tinggal terlalu sedikit. Sebaik sahaja dimulakan, alihkan pegangan kepada keadaan penangguhan PAYMENT_PENDING terhad sekali sahaja, dengan had setiap akaun dan seluruh acara pada inventori tersebut. Pada tamat tempoh penangguhan, hentikan memulakan kerja dan buat pertanyaan kepada penyedia. Lepaskan hanya selepas mengesahkan tiada pengesahan; selesaikan atau batalkan pengesahan yang disahkan. Gunakan data penukaran dan pusing ganti inventori untuk memperhalusi pegangan dan penangguhan lima minit dan bukannya membiarkan klien memperbaharui berulang kali.

Susulan 3: Rantau tulis utama hilang semasa jualan. Patutkah rantau lain mengambil alih serta-merta?

Jangan mulakan penulis kedua berdasarkan tamat masa sahaja. Jeda kemasukan dan pegangan baharu untuk acara tersebut. Gunakan pajakan konsensus, failover pangkalan data, atau pengasingan nod utama lama untuk membuktikan terdapat satu penulis, kemudian biarkan nod utama baharu menyambung semula daripada kedudukan log yang disahkan. Barisan giliran dan degradasi baca sahaja boleh diteruskan semasa jurang tersebut; pegangan unik yang tidak dapat dibuktikan tidak boleh diteruskan. Selaraskan pesanan, tempat duduk, dan operasi pembayaran sebelum meningkatkan kemasukan semula.

Susulan 4: Bagaimanakah anda meningkatkan keadilan dan mengehadkan bot tanpa menjadikan kawalan penipuan sebagai kebergantungan ketepatan?

Gunakan akaun yang disahkan, had pembelian, had kadar, isyarat peranti dan tingkah laku, serta cabaran tambahan untuk sesi berisiko tinggi. Token giliran ditandatangani, jangka pendek, dan terikat pada acara dan akaun; sesi pendua digabungkan atau ditolak mengikut dasar. Jualan boleh menggunakan FIFO masa ketibaan kasar atau menetapkan kedudukan secara rawak kepada pengguna pra-giliran. Sama ada pengesanan risiko terlepas pandang bot atau tidak, pangkalan data menguatkuasakan invarian pegangan, had, dan pesanan yang sama. Kesilapan kawalan risiko menjejaskan keadilan peruntukan; ia tidak boleh menyebabkan terlebih jualan.

Susulan 5: Mengapa tidak melindungi setiap tempat duduk dengan perkhidmatan kunci teragih sedia ada?

Apabila inventori berwibawa sudah berada dalam pangkalan data hubungan dengan penulisan bersyarat dan transaksi pendek, perkhidmatan kunci berasingan mencipta keadaan kedua yang mesti bersetuju dengan inventori, ditambah dengan tamat tempoh pajakan dan sempadan pagar (fencing boundaries). Kunci baris atau kemas kini bersyarat meletakkan pengecualian dan penulisan tahan lama dalam satu transaksi dan adalah lebih mudah. Pertimbangkan kunci teragih hanya apabila inventori merangkumi storan yang tidak boleh berurus niaga bersama atau apabila bahagian kritikal melindungi sumber luaran. Walaupun begitu, storan tahan lama masih memerlukan token versi atau pagar untuk menolak pemegang yang lewat.

Sumber awam

Soalan berkaitan

Alat temu duga berkaitan

Gunakan Jawab untuk jawapan reka bentuk sistem

Jelaskan keperluan terlebih dahulu, kemudian teruskan dengan skala, seni bina, pilihan komponen dan pertukaran (trade-off).

Lihat alat