Modul 08Penggal 3 · Kebolehpercayaan dan skala10 item poster
Async, Event dan Masa Nyata
Log masuk untuk menyimpan kemajuan anda merentas peranti. Sehingga itu, ia disimpan dalam pelayar ini.
Mengapa ini penting
Menghantar e-mel, menjana PDF, memanggil ejen LLM, memproses webhook: jika semua ini berjalan di dalam request pengguna, request itu menjadi perlahan, tamat masa kerana had serverless, dan kehilangan kerja apabila berlaku crash. Reka bentuk async ialah cara sistem yang serius kekal pantas dan tidak kehilangan apa-apa.
Hasil pembelajaran
- Pindahkan kerja yang perlahan atau tidak boleh diharap ke background job yang tahan lasak.
- Pilih antara queue, pub/sub dan reka bentuk event-driven.
- Kendalikan webhook dengan selamat (sahkan, dedupe, ack dengan cepat, proses secara async).
- Selaraskan aliran kerja berbilang langkah dengan saga dan corak outbox.
- Pilih transport masa nyata yang betul: WebSockets, SSE atau long polling.
- Jalankan scheduled job yang selamat jika bertindih dan selamat jika terlepas.
Pelajaran
8.1 Queue dan worker (15)
Corak: request mengesahkan input, menulis niat ke DB, memasukkan job ke queue, memulangkan 202 Accepted bersama job ID. Worker memproses, mengemas kini status, memberitahu.
- Penghantaran dalam praktiknya ialah at-least-once: reka setiap job handler supaya idempotent.
- Pilihan: terurus (SQS, Cloud Tasks), berasaskan Redis (BullMQ), berasaskan Postgres (pg-boss, Graphile Worker), enjin aliran kerja tahan lasak (Inngest, Trigger.dev, Temporal).
- Enjin aliran kerja tahan lasak selalunya paling sesuai untuk ejen AI: setiap langkah di-checkpoint dan di-retry secara berasingan.
8.2 Pub/Sub dan seni bina event-driven (16, 17)
- Queue: satu mesej, satu consumer (tugas yang perlu dibuat).
- Pub/Sub: satu event, banyak subscriber bebas (fakta yang telah berlaku:
order.paid). - Event-driven: servis bertindak balas terhadap event dan bukannya memanggil satu sama lain secara terus. Tidak terikat, tetapi lebih sukar dijejak; memerlukan schema untuk event dan observability yang baik.
- Namakan event dalam kala lampau; versikan schema event; sertakan event ID untuk dedupe.
8.3 Transaksi teragih, outbox dan saga (18, 19)
- Anda tidak boleh mempunyai satu transaksi ACID merentas DB anda, Stripe dan penyedia e-mel.
- Transactional outbox: dalam transaksi DB yang sama, tulis perubahan perniagaan dan satu baris outbox; relay menerbitkan baris outbox. Mengelakkan "disimpan tetapi tidak pernah diterbitkan" atau "diterbitkan tetapi tidak disimpan."
- Saga: jujukan langkah setempat yang setiap satunya ada tindakan pampasan (tempah stok → caj kad → cipta penghantaran; jika penghantaran gagal: refund, lepaskan stok). Secara orkestrasi (satu penyelaras) atau koreografi (event).
- Two-phase commit memang wujud tetapi jarang sesuai dalam sistem web moden.
8.4 Webhook (101)
Menerima:
- Sahkan tandatangan (HMAC dengan secret dikongsi) dan timestamp untuk menghalang pemalsuan dan replay.
- Dedupe berdasarkan event ID penyedia (unique constraint).
- Ack dengan cepat (2xx dalam beberapa saat), kemudian proses dalam background job.
- Kendalikan penghantaran yang tidak mengikut tertib; ambil keadaan semasa daripada penyedia apabila ragu-ragu. Menghantar: tandatangan payload, retry dengan backoff, sediakan log penghantaran dan replay untuk pelanggan, lindungi daripada SSRF pada URL yang dibekalkan pelanggan.
8.5 Cron job (21)
- Anggap satu larian boleh terlepas, tertangguh atau berjalan dua kali. Jadikan job idempotent dan boleh disambung semula.
- Elakkan pertindihan dengan lock (DB advisory lock).
- Proses secara berkelompok dengan checkpoint, bukan satu transaksi gergasi.
- Pantau dengan heartbeat "dead man's switch" (beri amaran jika job itu tidak berjalan).
- Simpan jadual dalam UTC; berhati-hati dengan daylight saving di pasaran lain.
8.6 Transport masa nyata (22, 23, 24)
| Transport | Arah | Gunakan apabila |
|---|---|---|
| SSE | Server ke client | Streaming token LLM, notifikasi, kemajuan. Ringkas, berfungsi melalui HTTP, auto-reconnect |
| WebSockets | Dua hala | Chat, kolaborasi, permainan langsung, suara |
| Long polling | Push simulasi | Fallback apabila streaming disekat |
| Pertimbangan: authenticate sambungan, re-authorize pada sambungan hayat panjang, kendalikan reconnect dan mesej yang terlepas (sambung semula dari event ID terakhir), platform serverless mungkin mengehadkan tempoh sambungan; gunakan servis masa nyata terurus (Supabase Realtime, Pusher, Ably, Cloudflare Durable Objects) pada skala besar. |
Makmal 8: Jadikannya async
- Pindahkan operasi segerak anda yang paling perlahan (panggilan LLM, PDF, e-mel) ke job tahan lasak dengan polling status atau kemajuan melalui SSE.
- Laksanakan penerima webhook (Stripe atau Resend) dengan pengesahan tandatangan, dedupe dan pemprosesan async. Replay event yang sama 10 kali; buktikan hanya satu kesan.
- Laksanakan saga 3 langkah dengan pampasan; suntik kegagalan pada langkah 3; buktikan rollback.
- Tambah cron job dengan lock pertindihan dan amaran heartbeat.
Definition of Done
Pek prompt AI
- "Kenal pasti setiap operasi dalam request handler yang memanggil servis luaran atau boleh mengambil masa lebih 1 saat. Cadangkan mana yang patut dipindahkan ke background job."
- "Laksanakan webhook handler ini: sahkan tandatangan dengan perbandingan constant-time, tolak timestamp yang basi, dedupe berdasarkan event id dengan unique constraint, masukkan pemprosesan ke queue, pulangkan 200."