معماریهای رویداد محور (Event Driven Architectures) به عنوان یک الگوی قدرتمند برای طراحی و ساختن سیستمهای بسیار مقیاسپذیر و انعطافپذیر ظاهر شدهاند. در قلب یک معماری رویداد محور این اصل نهفته است که رویدادها بلوک های ساختمانی اساسی سیستم هستند و رویدادهای مهم یا تغییرات حالت را در دامنه سیستم ثبت می کنند. یکی از الگوهای برجسته در این سبک معماری، Command Query Responsibility Segregation (CQRS) است که نگرانیهای مربوط به رسیدگی به فرمانهایی را که وضعیت سیستم را تغییر میدهند از مسائل مربوط به پرس و جو و بازیابی داده جدا میکند. CQRS تمایز واضحی را بین عملیات نوشتن و خواندن ترویج میکند و عملکرد بهینه و مقیاسپذیر را برای هر دو امکانپذیر میسازد. یکی دیگر از مفاهیم کلیدی که از نزدیک با معماری های رویداد محور مرتبط است، منبع یابی رویداد (Event Sourcing) است که بر ثبت تاریخچه کامل تغییرات به عنوان دنباله ای از رویدادها تأکید دارد. با ذخیره رویدادها به جای وضعیت فعلی، منبع رویداد یک گزارش حسابرسی قابل اعتماد را فراهم می کند و امکان بازسازی وضعیت سیستم را در هر نقطه از زمان فراهم می کند. CQRS و رویداد منبع یابی با هم ابزارهای قدرتمندی را برای ساختن سیستم های پیچیده ای ارائه می دهند که بسیار مقیاس پذیر، قابل نگهداری و توانایی پردازش و تجزیه و تحلیل داده ها در زمان واقعی هستند.
CQRS مخفف Command and Query Responsibility Segregation است که یک الگو است که عملیات خواندن و بروزرسانی برای یک مخزن داده را از هم جدا میکند. پیادهسازی CQRS در برنامه شما میتواند کارایی، قابلیت مقیاسپذیری و امنیت آن را بیشینه کند. انعطاف پذیری که با مهاجرت به CQRS ایجاد میشود، به یک سیستم امکان میدهد تا در طول زمان بهتر تکامل یابد و جلوی تداخل دستورات بروزرسانی در سطح دامنه را بگیرد.
در معماریهای سنتی، همان مدل داده برای پرس و جو و بروزرسانی پایگاه داده استفاده میشود. این روش ساده است و برای عملیات CRUD اساسی کارآمد است. با این حال، در برنامههای پیچیدهتر، این رویکرد میتواند پیچیده شود. به عنوان مثال، در سمت خواندن، برنامه ممکن است بسیاری از پرس و جوهای مختلف را اجرا کند و شیهای انتقال داده (DTO) با شکلهای مختلف برگرداند. نگاشت شی ممکن است پیچیده شود. در سمت نوشتن، مدل ممکن است اعتبارسنجی پیچیده و منطق کسب و کار را پیادهسازی کند. نتیجتاً ممکن است با یک مدل بسیار پیچیده مواجه شوید که خیلی زیاد کار میکند.
بارکاری خواندن و نوشتن معمولاً نامتقارن هستند و نیازهای کارایی و مقیاس آنها به شدت متفاوت است.
غالباً هماهنگی بین نمایش و بروزرسانی دادهها وجود دارد، مانند ستونها و خصیصههای اضافی که باید با درستی بروزرسانی شوند، حتی اگر به عنوان بخشی از یک عملیات مورد نیاز نباشند.تضاد دادهها میتواند رخ دهد وقتی که عملیاتها به صورت همزمان بر روی همان مجموعه داده انجام میشوند.
رویکرد سنتی میتواند تأثیر منفی بر روی عملکرد داشته باشد به دلیل بار روی مخزن داده و لایه دسترسی به داده، و پیچیدگی پرس و جوهای مورد نیاز برای بازیابی اطلاعات.
مدیریت امنیت و مجوزها ممکن است پیچیده شود، زیرا هر موجودیت مشمول عملیاتهای خواندن و نوشتن است که ممکن است اطلاعات را در متن نادرست ارائه دهد.
CQRS عملیات خواندن و نوشتن را در مدلهای مجزا جدا میکند و از دستورات برای بروزرسانی داده و پرس و جوها برای خواندن داده استفاده میکند.
دستورات باید مبتنی بر وظیفه باشند، نه محور داده. (مانند "رزرو اتاق هتل"، نه "تنظیم وضعیت رزرو به رزرو شده"). دستورات ممکن است در صف قرار گیرند برای پردازش ناهمزمان، به جای پردازش همزمان. پرس و جوها هیچگاه پایگاه داده را تغییر نمیدهند. یک پرس و جو یک DTO را برمیگرداند که هیچ دانش دامنهای را شامل نمیشود. سپس مدلها میتوانند جدا شوند، همانطور که در نمودار زیر نشان داده شده است، اگرچه این یک الزام مطلق نیست.
معماری اصلی CQRS جدا کردن مدلهای پرس و جو و بروزرسانی طراحی و پیادهسازی را سادهتر میکند. با این حال، یک نقطه ضعف این است که کد CQRS نمیتواند به طور خودکار از یک طرح پایگاه داده با استفاده از مکانیزمهای اسکفولدینگ مانند ابزارهای O/RM تولید شود (با این حال، شما قادر خواهید بود که سفارشیسازی خود را بر روی کد تولید شده انجام دهید).
برای جداسازی بیشتر، میتوانید دادههای خواندنی را از دادههای نوشتنی جدا کنید. در این صورت، پایگاه داده خواندنی میتواند از یک طرح داده خود استفاده کند که برای پرس و جوها بهینه شده است. به عنوان مثال، میتواند یک دید موادیالیزه از داده را ذخیره کند تا از ادغامهای پیچیده یا نگاشتهای پیچیده O/RM جلوگیری شود. ممکن است حتی از نوع مختلفی از مخزن داده استفاده کند. به عنوان مثال، مخزن داده نوشتنی ممکن است رابطهای باشد، در حالی که مخزن داده خواندنی یک مخزن سندی است.
اگر از پایگاه دادههای جداگانه خواندن و نوشتن استفاده شود، باید تأمین کنند که همواره همگام باشند. به طور معمول، این کار با صدور یک رویداد توسط مدل نوشتنی هنگام بروزرسانی پایگاه داده انجام میشود. برای کسب اطلاعات بیشتر در مورد استفاده از رویدادها، راهنمایی در مورد سبک معماری مبتنی بر رویداد را ببینید. از آنجا که معمولاً بروکرهای پیام و پایگاه دادهها نمیتوانند در یک تراکنش توزیعشده یکپارچه شوند، ممکن است در تضمین سازگاری در هنگام بروزرسانی پایگاه داده و انتشار رویدادها چالشهایی وجود داشته باشد. برای کسب اطلاعات بیشتر، راهنمایی در مورد پردازش پیامهای همسان استاندارد را ببینید.
مخزن خواندنی میتواند یک کپی فقط خواندنی از مخزن نوشتنی باشد یا مخزن خواندنی و نوشتنی ممکن است به طور کامل ساختار متفاوتی داشته باشند. استفاده از چند کپی فقط خواندنی میتواند عملکرد پرس و جو را افزایش دهد، به خصوص در سناریوهای توزیع شده که کپیهای فقط خواندنی در نزدیکی نمونههای برنامه قرار دارند.
جداسازی مخزن خواندنی و نوشتنی همچنین امکان برآوردهسازی هر کدام را برای تطبیق با بار مورد نیاز فراهم میکند. به عنوان مثال، مخزن خواندنی معمولاً با بار بسیار بیشتری مواجه میشود نسبت به مخزن نوشتنی.بعضی از پیادهسازیهای CQRS از الگوی Event Sourcing استفاده میکنند. در این الگو، وضعیت برنامه به عنوان یک دنباله از رویدادها ذخیره میشود. هر رویداد مجموعهای از تغییرات در دادهها را نمایش میدهد. وضعیت فعلی با بازپخش رویدادها ساخته میشود. در محیط CQRS، یکی از مزایای Event Sourcing این است که همان رویدادها میتوانند برای اعلام به سایر اجزا - به ویژه به اطلاع رسانی مدل خواندنی - استفاده شوند. مدل خواندنی از رویدادها برای ایجاد یک نمای کلی از وضعیت فعلی استفاده میکند که برای پرس و جوها بهینه است. با این حال، استفاده از Event Sourcing پیچیدگی را در طراحی اضافه میکند.
• مقیاس پذیری مستقل. CQRS اجازه میدهد تا بار خواندن و نوشتن به طور مستقل مقیاس شود و ممکن است منجر به کاهش اختلاف قفل شوندگیها شود. • طرحهای داده بهینهسازی شده. سمت خواندن میتواند از یک طرح داده استفاده کند که برای پرس و جوها بهینه شده است، در حالی که سمت نوشتن از یک طرح داده استفاده میکند که برای بروزرسانی بهینه شده است. • امنیت. آسانتر است که فقط موجودیتهای دامنه مناسب بتوانند بر روی دادهها عملیات نوشتن انجام دهند. • جداسازی مسئولیتها. جدا کردن سمت خواندن و نوشتن میتواند منجر به مدلهایی شود که قابلیت نگهداری و انعطاف پذیری بیشتری داشته باشند. بیشتر قوانین کسب و کار پیچیده در مدل نوشتنی قرار میگیرند. مدل خواندنی میتواند نسبتاً سادهتر باشد. • پرس و جوهای سادهتر. با ذخیره یک نمایش موادیالیزه در پایگاه داده خواندنی، برنامه میتواند از پیوستنهای پیچیده در هنگام پرس و جو اجتناب کند.
به جای ذخیره فقط وضعیت کنونی داده در یک دامنه، از یک مخزن فقط افزودنی برای ثبت سری کاملی از عملیاتهای انجام شده بر روی داده استفاده کنید. این مخزن به عنوان سیستم ثبت عملکرد عمل میکند و میتواند برای مواد مادامالعمر دامنه مورد استفاده قرار گیرد. این میتواند وظایف را در دامنههای پیچیده سادهتر کند، با اجتناب از نیاز به هماهنگی مدل داده و دامنه کسب و کار، در حالی که عملکرد، قابلیت مقیاسپذیری و واکنشپذیری را بهبود میبخشد. این میتواند همچنین پایداری برای دادههای تراکنشی فراهم کند و تاریخچه کاملی را حفظ کند که عملیاتهای جبرانی را ممکن میسازد.
بیشتر برنامهها با دادهها کار میکنند و رویکرد معمول این است که برنامه با بروزرسانی وضعیت کنونی داده توسط کاربران آن را نگهداری کند. به عنوان مثال، در مدل ایجاد، خواندن، بروزرسانی و حذف (CRUD)، فرآیند معمولی داده این است که داده را از مخزن خوانده، تغییراتی روی آن اعمال کند و وضعیت کنونی داده را با مقادیر جدید به روز کند - اغلب با استفاده از تراکنشهایی که داده را قفل میکنند.
رویکرد CRUD برخی محدودیتها دارد:
سیستمهای CRUD عملیات بروزرسانی را مستقیماً بر روی مخزن داده انجام میدهند. این عملیات میتواند عملکرد و واکنشپذیری را کاهش دهد و مقیاسپذیری را محدود کند به دلیل بار پردازشی که نیاز دارد.
در یک دامنه همکاری با بسیاری از کاربران همزمان، تداخل در بروزرسانی دادهها احتمالاً بیشتر است، زیرا عملیات بروزرسانی بر روی یک مورد داده انجام میشود.
مگر اینکه یک مکانیزم حسابرسی دیگر وجود داشته باشد که جزئیات هر عملیات را در یک لاگ جداگانه ثبت کند، تاریخچه از بین میرود.
الگوی Event Sourcing رویکردی را تعریف میکند برای برخورد با عملیاتهایی بر روی داده که توسط یک دنباله از رویدادها رهبری میشود و هر یک از این رویدادها در یک مخزن فقط افزودنی ثبت میشود. کد برنامه سری رویدادهایی را که هر عملیاتی را که روی داده انجام شده را توصیف کند، به مخزن رویداد ارسال میکند و در آنجا ثبت میشوند. هر رویداد مجموعهای از تغییراتی را در داده نمایش میدهد (مانند اضافه شدن مورد به سفارش).
رویدادها در یک مخزن رویداد ثبت میشوند که به عنوان سیستم ثبت عملکرد (منبع داده معتبر) در مورد وضعیت کنونی داده عمل میکند. این مخزن رویدادها را به طور معمول منتشر میکند تا مشترکان مطلع شوند و در صورت لزوم آنها را کنترل کنند. به عنوان مثال، مصرف کنندهها ممکن است وظایفی را شروع کنند که عملیات موجود در رویدادها را در سایر سیستمها اعمال کنند یا هر عملیات مرتبط دیگری را انجام دهند که برای تکمیل عملیات لازم است. توجه کنید که کد برنامه که رویدادها را تولید میکند از سیستمهایی که به رویدادها مشترک میشوند، جدا شده است.
استفادههای معمول از رویدادهای منتشر شده توسط مخزن رویداد شامل حفظ نمایشهای مواد بعد از اینکه عملیات در برنامه آنها را تغییر دادهاند و ادغام با سیستمهای خارجی است. به عنوان مثال، یک سیستم میتواند یک نمایش مادی از تمام سفارشهای مشتری را نگهداری کند که برای پر کردن بخشهایی از رابط کاربری استفاده میشود. برنامه سفارشهای جدید اضافه میکند، موارد را به سفارش اضافه یا حذف میکند و اطلاعات حمل و نقل را اضافه میکند. رویدادهایی که این تغییرات را توصیف میکنند، قابل مدیریت و استفاده برای بهروزرسانی نمایش مادی هستند.
در هر لحظه، برنامهها میتوانند تاریخچه رویدادها را بخوانند. سپس میتوانید آن را برای نمایش کنونی یک موجودیت بازیابی کنید با بازیابی و مصرف تمام رویدادهای مرتبط با آن موجودیت. این فرایند میتواند برای مصرف شیء دامنه در هنگام کنترل یک درخواست رخ دهد یا این فرایند از طریق یک وظیفه زمانبندی شده انجام میشود تا وضعیت موجودیت به عنوان یک نمایش مادی ذخیره شود و به لایه ارائه پشتیبانی کند.
شکل نمایش کلی الگو، از جمله برخی از گزینهها برای استفاده از جریان رویداد مانند ایجاد نمایش مادی، ادغام رویدادها با برنامهها و سیستمهای خارجی، و بازپخش رویدادها برای ایجاد پروژکشنهای وضعیت کنونی موجودیتهای خاص را نشان میدهد.
• رویدادها غیرقابل تغییر هستند و میتوانند با استفاده از عملیات اضافه کردن به صورت برخط ذخیره شوند. رابط کاربری، گردش کار یا فرایندی که یک رویداد را آغاز میکند، میتواند ادامه یابد و وظایفی که رویدادها را پردازش میکنند میتوانند به صورت پسزمینه اجرا شوند. این فرایند، به همراه عدم وجود همزمانی در هنگام پردازش معاملات، میتواند عملکرد و قابلیت مقیاسپذیری برنامهها را به طور قابل توجهی بهبود دهد، به ویژه برای سطح ارائه یا رابط کاربری.
• رویدادها اشیاء سادهای هستند که عملیاتی را که انجام شده است، همراه با هر داده مرتبط مورد نیاز برای توصیف عملیات نماینده رویداد، توصیف میکنند. رویدادها به صورت مستقیم یک مخزن داده را به روز نمیکنند، بلکه فقط برای پردازش در زمان مناسب ثبت میشوند. استفاده از رویدادها میتواند پیادهسازی و مدیریت را سادهتر کند.
• رویدادها به طور معمول برای یک کارشناس دامنه معنی دارند، در حالی که ناسازگاری شیء-رابطهای میتواند جداول پیچیده پایگاه داده را سخت قابل درک کند. جداول ساختارهای مصنوعی هستند که وضعیت کنونی سیستم را نمایش میدهند نه رویدادهای رخ داده.
• استفاده از Event Sourcing میتواند از ایجاد تداخل در بهروزرسانیهای همزمان جلوگیری کند زیرا نیازی به بهروزرسانی مستقیم اشیاء در مخزن داده نیست. با این حال، مدل دامنه همچنان باید طراحی شود تا از درخواستهایی که ممکن است منجر به وضعیت ناسازگار شود، محافظت کند.
• ذخیره برخط رویدادها یک مسیر ممیزی را فراهم میکند که میتواند برای نظارت بر عملیات انجام شده در برابر یک مخزن داده استفاده شود. با بازپخش رویدادها در هر زمان، میتوان وضعیت کنونی یک موجودیت را با مصاحبه و مصرف تمام رویدادهای مرتبط با آن مادی کرد. این فرآیند میتواند به صورت درخواستی رخ دهد تا یک شیء دامنه را هنگام پردازش درخواست مادی کند. یا این فرآیند از طریق یک وظیفه زمانبندی شده انجام میشود تا وضعیت موجودیت به صورت یک نمایش مادی ذخیره شود و در لایه ارائه پشتیبانی کند.
• مخزن رویدادها رویدادها را ارسال میکند و وظایف عملیاتها را در پاسخ به این رویدادها انجام میدهند. این جدا شدن وظایف از رویدادها امکان انعطافپذیری و گسترش را فراهم میکند. وظایف درباره نوع رویداد و داده رویداد اطلاع دارند، اما درباره عملیاتی که منجر به رویداد شد نمیدانند. علاوه بر این، چندین وظیفه میتوانند هر رویداد را پردازش کنند. این امکان را فراهم میکند که به راحتی با سایر سرویسها و سیستمها که تنها به رویدادهای جدیدی که توسط مخزن رویدادها برافراشته میشوند گوش داده میشوند، ادغام شود. با این حال، رویدادهای مرتبط با Event Sourcing معمولاً در سطح بسیار پایین هستند و ممکن است لازم باشد رویدادهای ادغام خاصی را تولید کنیم.
Event Sourcing به طور معمول با الگوی CQRS ترکیب میشود، با انجام وظایف مدیریت داده در پاسخ به رویدادها و با از رویدادهای ذخیره شده، نمایشهای مادی را موجود میکند.
برای مطالعه بیشتر میتوانید از منابع زیر استفاده کنید فیلم های شرکت confluent: • https://www.youtube.com/watch?v=lg6aF5PP4Tc • https://www.youtube.com/watch?v=tIDqyrYscgk&t=24s فیلم هایی از اساتیدی بزرگ مثل martin fowler: • https://www.youtube.com/watch?v=STKCRSUsyP0&t=122s • https://www.youtube.com/watch?v=ksRCq0BJef8 و کتاب معروف از Oreilly • https://www.goodreads.com/en/book/show/39793332