معماری رویدادمحور

در معماری معمول، سرویسها همدیگر را صدا میزنند: سرویس سفارش، سرویس انبار را صدا میزند تا موجودی کم شود، بعد سرویس پیامک را، بعد سرویس حسابداری را.
در معماری رویدادمحور، سرویس سفارش فقط اعلام میکند: «سفارشی ثبت شد.» و هر که علاقه دارد، خودش واکنش نشان میدهد.
تفاوت ظاهراً کوچک است و پیامدهایش عمیق.
چه چیزی آزاد میشود
سرویس منتشرکننده، مصرفکنندهها را نمیشناسد. افزودن قابلیت جدید — مثلاً ارسال پیام به باشگاه مشتریان — بدون دست زدن به سرویس سفارش ممکن است.
شکست یک مصرفکننده، بقیه را نمیخواباند. اگر سرویس پیامک پایین باشد، سفارش ثبت میشود و پیامک بعداً میرود.
بار جذب میشود. قلهٔ ترافیک در صف میماند و مصرفکننده با سرعت خودش پردازش میکند.
تاریخچهٔ طبیعی. جریان رویدادها، خودش سابقهٔ کامل اتفاقات است.
چه چیزی سختتر میشود
اینجا جایی است که تیمها غافلگیر میشوند.
دنبال کردن یک فرایند سخت است. در معماری معمول، مسیر اجرا در کد پیداست. در رویدادمحور، هیچجا نوشته نیست که پس از ثبت سفارش چه اتفاقهایی میافتد — باید بگردید ببینید چه کسی مشترک آن رویداد است.
بدون ردیابی توزیعشده، اشکالزدایی تقریباً ناممکن است. هر رویداد باید شناسهٔ همبستگی داشته باشد تا بتوانید کل زنجیره را دنبال کنید. پایش و لاگ اینجا پیشنیاز است، نه بهبود.
ترتیب تضمین نیست. رویداد «سفارش لغو شد» ممکن است پیش از «سفارش ثبت شد» برسد.
تحویل حداقل یک بار است، نه دقیقاً یک بار. هر مصرفکننده باید تکرار را خودش خنثی کند — همان اصل idempotency که در کارهای پسزمینه گفتیم و اینجا غیرقابل مذاکره است.
سازگاری نهایی. بخش بعدی.
سازگاری نهایی، که تصمیم کسبوکار است نه فنی
مهمترین بخش این مقاله.
وقتی سفارش ثبت میشود و رویداد منتشر، موجودی هنوز کم نشده. چند صد میلیثانیه — یا در شرایط بد، چند دقیقه — سامانه در حالت ناسازگار است.
سؤالی که باید از کسبوکار پرسیده شود: آیا این قابل قبول است؟
- «موجودی چند ثانیه دیرتر بهروز شود» → معمولاً بله.
- «ممکن است دو نفر آخرین کالا را بخرند» → معمولاً نه.
اگر جواب نه است، آن بخش نباید رویدادمحور باشد. رزرو موجودی باید همان لحظه و بهصورت تراکنشی انجام شود؛ اطلاعرسانی و حسابداری میتوانند رویدادمحور باشند.
این تفکیک را قبل از طراحی انجام دهید، نه بعد از اینکه مشتری از فروش کالای ناموجود شکایت کرد.
دام: صدا زدن با لباس رویداد
الگوی غلطی که مکرر دیدهایم:
سرویس سفارش رویدادی منتشر میکند به نام «موجودی را کم کن».
این رویداد نیست؛ دستور است با پوشش رویداد. منتشرکننده هنوز میداند چه کسی باید چه کاری بکند — فقط یک صف وسط گذاشته.
رویداد، چیزی است که اتفاق افتاده، با فعل گذشته: «سفارش ثبت شد»، «پرداخت تأیید شد».
دستور، چیزی است که باید انجام شود.
اگر همهٔ «رویدادهای» شما فعل امریاند، معماری رویدادمحور ندارید — معماری معمول دارید با پیچیدگی اضافه.
طراحی رویداد
نامگذاری با فعل گذشته.
محتوای کافی، نه بیشتر. رویداد باید اطلاعات لازم برای واکنش را داشته باشد، وگرنه هر مصرفکننده باید برگردد و از منتشرکننده بپرسد — که کل مزیت جدایی را از بین میبرد.
شناسهٔ یکتا، برای خنثی کردن تکرار.
شناسهٔ همبستگی، برای ردیابی زنجیره.
نسخه. ساختار رویداد روزی عوض میشود و مصرفکنندگان قدیمی نباید بشکنند. سازگاری عقبرو را جدی بگیرید: فیلد اضافه کنید، فیلد موجود را حذف یا تغییر معنا ندهید.
مهر زمانی رخداد، نه زمان انتشار.
زیرساخت
نیاز به لایهای دارید که رویدادها را نگه دارد و تحویل دهد — سازوکارهایش در صف پیام.
سه الزام:
صف مردگان. رویدادی که پس از چند تلاش پردازش نشد، باید جایی برود که کسی ببیندش. بدون آن، خطا خاموش میماند.
پایش تأخیر صف. صفی که رشد میکند یعنی چیزی پردازش نمیشود — حتی اگر سایت بالا باشد.
امکان بازپخش. اگر مصرفکنندهای باگ داشت و باید دوباره پردازش کند، باید بتوانید رویدادها را از نقطهای دوباره بفرستید. این قابلیت را از روز اول در نظر بگیرید.
کِی این معماری معنا دارد
نشانههای واقعی:
- چند سرویس مستقل با تیمهای جدا.
- یک اتفاق، چند واکنش — و واکنشها مرتب اضافه میشوند.
- بار نامنظم که باید جذب شود.
- یکپارچهسازی با سامانههای بیرونی که ممکن است کند یا در دسترس نباشند — همان الگویی که در یکپارچهسازی سامانهها گفتیم.
نشانههای اینکه زودهنگام است:
- یک برنامهٔ یکپارچه با تیم کوچک.
- فرایندها ساده و خطیاند.
- هیچکس تجربهٔ اشکالزدایی سامانهٔ ناهمگام را ندارد.
- پایش متمرکز ندارید.
بند آخر تعیینکننده است. معماری رویدادمحور بدون پایش، جعبهٔ سیاهی است که هیچکس نمیفهمد چرا کار نمیکند.
مسیر تدریجی
نیازی نیست همهچیز را رویدادمحور کنید. مسیری که در پروژهها جواب داده:
۱. از کارهای جانبی شروع کنید. اطلاعرسانی، گزارش، همگامسازی با سامانههای دیگر. اینها ذاتاً ناهمگاماند و اگر چند ثانیه دیر شوند کسی متوجه نمیشود.
۲. مسیر اصلی را تراکنشی نگه دارید. ثبت سفارش و رزرو موجودی، همان لحظه.
۳. اگر جواب داد، دامنه را باز کنید.
این ترتیب، کمریسکترین است: در هر مرحله چیزی کار میکند و میتوانید متوقف شوید.
و یک هشدار
معماری رویدادمحور، پیچیدگی را حذف نمیکند — جابهجا میکند.
هر سرویس سادهتر میشود و فهمیدن کل سامانه سختتر. برای سازمانی با چند تیم مستقل، این معامله معمولاً میارزد. برای تیم پنجنفره، معمولاً نه.
همان قاعدهای که در یکپارچه یا میکروسرویس گفتیم: پیچیدگی معماری باید متناسب با پیچیدگی سازمان باشد، نه بیشتر.