معماری رویداد محور
معماری رویداد محور یک الگوی طراحی نرمافزاری است که سازمان را قادر میسازد تا "رویدادها" یا لحظات مهم تجاری (مانند تراکنش، بازدید از سایت، رها کردن سبد خرید و …) را شناسایی کند و بر اساس آنها در زمان واقعی یا نزدیک به زمان واقعی عمل کند. این الگو جایگزین معماری سنتی "درخواست/پاسخ" میشود که در آن سرویسها باید قبل از اینکه بتوانند به کار بعدی بروند منتظر پاسخ باشند. جریان معماری رویداد محور توسط رویدادها اجرا می شود و برای پاسخ به آنها یا انجام برخی اقدامات در پاسخ به یک رویداد طراحی شده است.
معماری رویداد محور اغلب ارتباطات "ناهمزمان" نامیده می شود. این بدان معناست که فرستنده و گیرنده مجبور نیستند منتظر یکدیگر باشند تا به کار بعدی خود بروند. سیستم ها به آن پیام وابسته نیستند. یک مثال ناهمزمان می تواند پیام متنی باشد. شما پیامی می فرستید و در برخی موارد حتی نمی دانید آن را برای چه کسی می فرستید یا کسی گوش می دهد، اما منتظر پاسخ نیستید. همان طور که توضیح داده شد، رویدادها تقریباً در زمان واقعی تحویل داده می شوند، بنابراین مصرف کنندگان می توانند بلافاصله به رویدادها پاسخ دهند. در واقع تولیدکنندگان از مصرفکنندگان جدا شدهاند – یک تولیدکننده نمیداند کدام مصرفکننده به آن گوش میدهد و هر مصرف کننده ای همه رویدادها را می بیند.
رویدادها در طراحی سیستم دارای ویژگی های مشترک هستند:
آنها یک رکورد هستند که اتفاقی افتاده است.
آنها تغییر ناپذیر هستند - نمی توان آنها را تغییر داد یا حذف کرد.
آنها را می توان به طور نامحدود ادامه داد - رویدادها را می توان برای همیشه ذخیره کرد و به آنها دسترسی داشت.
آنها می توانند به تعداد دفعات نامحدودی مصرف شوند - هیچ محدودیتی برای تعداد دفعاتی که یک رویداد می تواند توسط یک سرویس پردازش شود وجود ندارد.
ساختار معماری رویداد محور
اجزای یک معماری رویداد محور می تواند شامل سه بخش باشد: تولید کننده، مصرف کننده، broker. Broker می تواند اختیاری باشد، به خصوص زمانی که شما یک تولید کننده و یک مصرف کننده دارید که مستقیماً با یکدیگر در ارتباط هستند و تولید کننده فقط رویدادها را برای مصرف کننده ارسال می کند. یک مثال می تواند تولید کننده ای باشد که فقط به یک پایگاه داده یا انبار، داده ارسال می کند تا رویدادها برای تجزیه و تحلیل جمع آوری و ذخیره شوند. معمولاً در شرکتها، شما منابع متعددی دارید که انواع رویدادها را با یک یا چند مشتری علاقهمند به برخی یا همه آن رویدادها ارسال میکنند.
نمونه معماری رویداد محور
برای بررسی، رویدادها کنش هستند و معماری رویداد محور نحوه تعریف واکنش سازمان به رویداد است.
برای مثال، بیایید ببینیم که چگونه یک فروشگاه آنلاین ممکن است معماری رویداد محور را اتخاذ کند. در یک سایت تجارت الکترونیک، ارسال اطلاعات پرداخت توسط مشتری یک اقدام رایج و حیاتی است. رابط کاربری رویداد "پرداخت ارسال شده" را با جزئیات کارت اعتباری ایجاد میکند و روتر رویداد میداند اعلان را بر اساس فراداده رویداد به سیستم پرداخت هدایت کند.
پس از دریافت اعلان، سیستم پرداخت رویداد را پردازش می کند و یک رویداد جدید "پرداخت" ایجاد می کند که نشان دهنده موفقیت یا شکست است. روتر رویداد این را به UI وب سایت باز می گرداند، که وضعیت را به مشتری نشان می دهد و مراحل بعدی را به شما می گوید. اگر پرداخت انجام نشد، رابط کاربری میتواند فرم را برای بهروزرسانی جزئیات دوباره باز کند. اگر پرداخت با موفقیت انجام شود، برای مثال، رابط کاربری میتواند جزئیات سفارش نهایی و تاریخ تحویل مورد انتظار را نمایش دهد.
موارد استفاده از معماری رویداد محور
سازمان ها هنگام طراحی سیستم های خود برای دستیابی به اهداف مختلف از معماری رویداد محور استفاده می کنند. موارد زیر رایج ترین هستند:
تکرار داده ها: یک رویداد را می توان بین چندین سرویس به اشتراک گذاشت که باید داده های آن را در پایگاه داده خود کپی کنند.
پردازش موازی: فرآیندهای متعددی می توانند توسط یک رویداد راه اندازی شوند تا به صورت ناهمزمان با یکدیگر اجرا شوند.
نظارت در زمان واقعی: سیستم ها می توانند رویدادهایی را برای تغییرات در وضعیت خود ایجاد کنند تا سازمان بتواند ناهنجاری ها و فعالیت های مشکوک را اسکن کند.
قابلیت همکاری: رویدادها را می توان بدون در نظر گرفتن سرویس های کدی که در آن نوشته شده است ادامه و منتشر کرد.
افزونگی: اگر سرویسی از کار بیفتد، رویدادها میتوانند در روتر ادامه داشته باشند تا زمانی که سرویس برای مصرف رویداد در دسترس باشد.
میکروسرویس ها: معماری رویداد محور معمولاً با میکروسرویس ها جفت می شود تا به طور موثر اطلاعات را بین سیستم های جدا شده در مقیاس به اشتراک بگذارد.[۳]
معماری جریان رویداد
جریان رویداد از الگوی مبتنی بر اشتراک عبور می کند. در این رویکرد، رویدادها در یک گزارش نوشته میشوند و همه مصرفکنندگان میتوانند گزارش را برای شناسایی رویدادهای مرتبط بخوانند. مصرفکنندگان میتوانند هر بخشی از جریان را بخوانند، بنابراین میتوانند رویدادهای گذشته را دوباره پخش کنند.
الگوهای معماری رویداد محور
بنا به دلایلی همچون scalability، flexibility و coupling کم، ممکن است یک تیم توسعهی نرمافزار تصمیم بگیرد سیستم خود را به نحوی طراحی و پیادهسازی کند که بین اجزای خود از ارتباط و پردازش رویداد محور استفاده کند. به همین منظور تیم توسعهی مذکور باید به استفاده از الگوهای معماری رویداد محور روی بیاورد. در این قسمت برخی از این الگوها را نام برده و به اختصار توضیح میدهیم.
همانگونه که بیان شد، میتوانیم پس از بررسیهای لازم با استفاده از این الگوهای معماری رویداد محور برای طراحی سیستمهای بزرگ و پیچیده، flexibility و scalability را افزایش دهیم. این الگوهای رویداد محور باعث میشوند سیستم توانایی پردازش حجم عظیمی از رویدادها را داشته باشد و به تغییرات component های خود واکنش درستی نشان دهد. همچنین فرایند یکپارچهسازی سیستم مورد نظر را با سایر سیستمها آسانتر میکنند. در کل با استفاده از این الگوها میتوان سیستمهایی بهینه طبق استانداردهای روز توسعهی نرمافزار طراحی و پیاده سازی کرد.
الگوهای پردازش رویداد
علاوه بر مدلهای مختلف، رویکردهای منحصربهفردی نیز برای پردازش رویدادها پس از رسیدن به مشتری وجود دارد.
پردازش رویداد ساده: مصرفکنندگان هر رویداد را همانطور که دریافت میشود پردازش میکند.
پردازش رویداد پیچیده: مصرفکنندگان مجموعهای از رویدادها را برای شناسایی الگوها در دادههای رویداد پردازش میکنند.
پردازش جریان رویداد: پلتفرمهای جریان داده رویدادها را جذب میکنند و خط لولهای ایجاد میکنند تا پردازشگرهایی را جریان دهد که دادهها را تغییر داده و مصرف میکنند.
معماری رویداد محور و میکروسرویسها
امروزه شرکتهای زیادی به سمت آن رفتهاند که از معماریهای براساس میکروسرویس را برای افزایش سرعت و بهرهوری استفاده کنند. از جمله معماریهایی که برای ارتباط سرویسهای مختلف در میکروسرویسها استفاده میشود معماری رویداد محور است.
میکروسرویسهای بر پایه معماری رویداد محور حاوی سه جزء اصلی هستند:
یکی از نمونه کاربردهای اصلی معماری رویداد محور در میکروسرویسها زمانی است که از الگوی "پایگاه داده به ازای سرویس" (database per service) استفاده شده است، بدین معنا که هر سرویس داده مربوط به خود را نگاه میدارد. هنگامی که یک در تراکنش چندین سرویس گسترده باشد، به مکانیزمی نیاز داریم که ثبات داده را در این سرویسها تضمین کند.
در صورت اتخاذ رویکرد رویداد محور، هر سرویس در صورت به روز رسانی دادههایش یک رویداد را منتشر میکند. سرویسهایی که به این رویداد subscribe کرده باشند آن را دریافت کرده و مطابقا داده خود را به روز رسانی میکنند. البته این نکته قابل توجه است که استفاده از معماری رویداد محور در معماری پایگاه داده به ازای سرویس منسوخ شده و به جای آن از رویکرد saga استفاده میشود.
نمونههای واقعی از استفاده از معماری رویداد محور
Uber
یکی از بزرگترین و گستردهترین نمونههای استفاده از معماری رویداد محور اوبر است که بر پلتفرم apache kafka ایجاد شده است. Kafka یک پلتفرم پخش توزیع شده است که برای ایجاد معماری رویداد محور استفاده میشود و به صورتی طراحی شده که توانایی کاری بالا و تاخیر پایینی داشته باشد. انتقال پیام در کافکای بر مبنای publish/subscribe است.
استفاده از کافکا در اوبر اجازه استفاده از 300 میکروسرویس که دادههایی در حجم پتابایت را در زمان نزدیک به بیدرنگ پردازش میکنند میدهد. در کنار اینها، جریانهای کاری بیشماری برای جریان دادن داده از پایگاه داده به subscriberها وجود دارند. حجم بالای داده اوبر باعث شد که آنها پلتفرم خودشان به نام Hudi را برای جریان دریاچهها داده ایجاد کنند.
Hermes
این شرکت پستی آلمانی یکی از بزرگترین کلاسترهای کافکا را در اروپا دارد. هرمس از کافکا برای ارائه تجزیه و تحلیل در زمان واقعی و مشاهده کل فرآیند لجستیک خود استفاده می کنند. زیرساخت ابری رویداد محور هرمس میتواند دادهها را به سرعت و به شکل ایمن تکرار کند و به هرمس این امکان را میدهد تا آنها را برای تصمیمگیری در زمان واقعی در کافکا ادغام کند و دید بیشتری در کل فرآیند لجستیک ایجاد کند.
هرمس با پردازش بیش از یک میلیارد رویداد روزانه، می تواند هر بسته را در طول سفر خود، از جمع آوری تا تحویل، ردیابی کند. این به آنها اجازه می دهد تا عملیات خود را بهینه کنند و به مشتریان خود اطلاعات دقیقی از وضعیت تحویل آنها ارائه دهند. به لطف راه حل اجرا شده، این شرکت می تواند توزیع و جابجایی بدنه های مبادله را بهینه کند، همچنین ترافیک بسته و تحویل را در زمان واقعی کنترل کند. مرتبسازی تور دیجیتال از مرتبسازی بستهها و برنامهریزی تورهای تحویل پیشرو بر اساس پردازش جریانهای رویداد کافکا برای محاسبه پیشبینیها پشتیبانی میکند.
مزایای معماری رویداد محور
معماری رویداد محور مزایای بسیاری را برای سازمان هایی ارائه می دهد که به دنبال بهبود پاسخگویی و انعطاف پذیری پشته فناوری خود هستند.
جداسازی: سرویسها دیگر نیازی به دانستن وجود سرویسهای دیگر، برای همکاری با یکدیگر ندارند. آنها فقط باید درباره رویدادها بدانند و کارگزار، رویدادهای مناسب را به سیستم های مناسب واگذار می کند. جداسازی، معماری رویداد محور را به یک راه مناسب برای اتصال میکروسرویس ها تبدیل می کند.
تغییرناپذیری: رویدادها را نمیتوان پس از ایجاد تغییر داد، بنابراین میتوان آنها را با چندین سرویس به اشتراک گذاشت، بدون اینکه خطر تغییر یا حذف اطلاعاتی که سایر سرویسها سپس مصرف میکنند، توسط یک سرویس به اشتراک گذاشته شود.
مقیاس پذیری: می توان از یک رویداد برای راه اندازی چندین عمل در مصرف کنندگان مختلف استفاده کرد که اجرای موازی کار را ممکن می کند و عملکرد را بهبود می بخشد. جداسازی همچنین فرآیندی، بهروزرسانی یا حذف تولیدکنندگان و مصرفکنندگان رویداد را ساده میکند، زیرا نیازی به بهروزرسانی منطق در هر سرویس یا سیستم ندارید و به شما امکان میدهد تا به سرعت مجموعه ابزار خود را برای برآورده کردن نیازها یا تقاضاهای جدید تنظیم کنید.
گردش کار در زمان واقعی: معماری رویداد محور با رخ دادن رویدادها اجرا میشود و از پاسخهای بلادرنگ یا تقریباً همزمان به تعاملات حیاتی مانند خرید و پیامهای چت زنده پشتیبانی میکند. این چابکی تضمین می کند که مشتریان همیشه به محض نیاز، پشتیبانی و اطلاعات را دریافت می کنند.
چالش های معماری رویداد محور
اگرچه معماری رویداد محور مزایای بسیاری را ارائه می دهد، برخی از این دستاوردها با معاوضه هایی همراه هستند، از جمله موارد زیر:
کارایی: گاهی اوقات ممکن است که مصرفکنندگان زمان بیشتری را برای اجرای کنشها صرف کند زیرا رویداد را به سرعت دریافت نمیکنند.
همچنین بین حرکت رویدادها با تمام دادههای موجود یا ارسال اعلانهای باریکتر معاوضههایی وجود دارد که از مصرفکنندگان میخواهد برای دادههای اضافی پرس و جو کنند. از یک طرف، انتقال رویداد بیشتر طول می کشد و ممکن است هر مصرف کننده ای به مجموعه داده کامل نیاز نداشته باشد. از سوی دیگر، باید منطق اضافی تعریف کنید تا اطمینان حاصل شود که مصرف کننده هرگونه داده از دست رفته را تهیه می کند.
سازگاری نهایی: دو سرویس ممکن است بر اساس مدت زمانی که برای اجرای وظایفشان و سایر عوامل طول می کشد، در زمان های مختلف یک رویداد را پردازش کرده و به آن واکنش نشان دهند. این بدان معنی است که همه واکنشها به یک رویداد به طور همزمان رخ نمیدهند، اما در نهایت همه سرویسها پردازش رویداد را به پایان خواهند رساند.
ابزار های مورد استفاده در معماری event driven:
1. apache kafka:
کافکا یک سیستم پیام رسان توزیع شده و مقیاس پذیر است که برای انتقال رخداد بین بخش های مختلف سیستم و جریان های داده ای استفاده میشود.
مثلا می توانیم داده های یک دیتابیس را به صورت اسنپ شات روی کافکا قرار دهیم تا سیستم های دیگر این داده را از روی کافکا بخوانند و لود روی دیتابیس ما کم شود.
کافکا میتواند داده ها را به صورت دائمی ذخیره سازی کند و همچنین امکان پردازش مجدد داده ها را در صورت لزوم فراهم میکند.
2. apache pulsar:
یک ابزار پیام رسانی و stream داده است که تاخیری کمتر از ۱۰ میلی ثانیه دارد. Pulsar امکان مدیریت رخداد ها و پیام ها را در محیط توزیع شده و با بار کاری بالا فراهم میکند.
3. rabbitMQ:
یک ابزار message broker اوپن سورس است که ابتدا پروتکلی برای صف بندی پیام ها ارائه کرد و بعد از آن دیزاین هایی برای استریم کردن پیام های مبتنی بر متن پیاده سازی کرد.
rabbit MQ قابلیت مدیریت صف ها و تبادل داده ها و مدیریت توزیع event ها را فراهم میکند.
4. apache storm:
این ابزار یک framework برای پردازه های stream کردن به صورت توزیع شده می باشد که بعد از خریداری شدن توسط توییتر به صورت open source در آمد. پردازش های این framework به صورت لحظه ای و پیوسته انجام میشود.
Storm قابلیت پیاده سازی الگوهای مختلف پردازش مانند ترکیب فیلتر و تحلیل را فراهم میکند.
5. apache flink:
یک framework اوپن سورس برای پردازه های streaming و batch می باشد که هسته اصلی پردازش پیامش با جاوا نوشته شده و عملکردی مبتنی بر pipeline و الگو های data parallel دارد.
معماری رویداد محور در پایتون با استفاده از کافکا
Python به عنوان یک زبان برنامهنویسی محبوب، کتابخانهها و فریمورکهای متعددی را برای پشتیبانی از طراحی مبتنی بر رویداد ارائه میدهد. یک ابزار قدرتمند که میتوان در Python برای معماری رویداد محور استفاده کرد، Apache Kafka است. Kafka یک سیستم پیامرسانی توزیعشده است که امکان انتقال بیدرنگ رویدادها و جریانهای داده (Data Streams) را بین اجزای مختلف یک سیستم فراهم میکند. میخواهیم بررسی کنیم چگونه میتوانیم از Kafka در Python برای ساخت برنامههای مبتنی بر رویداد استفاده کنیم.
برای شروع، باید کتابخانه کلاینت Kafka برای Python را نصب کرد. کلاینت رسمی Kafka برای Python که به نام confluent-kafka-python شناخته میشود، یک رابط با سطح بالا و یک رابط با سطح پایین برای تعامل با Kafka ارائه میدهد. این کتابخانه قابلیتهای قدرتمندی را برای تولید و مصرف رویدادها به صورت کارآمد فراهم میکند.
ابتدا، باید یک کلاستر Kafka را کانفیگ کنید یا از یک کلاستر موجود استفاده کنیم. هنگامی که کلاستر Kafka آماده بود، میتوانید شروع به ایجاد تولیدکنندگان (Producers) و مصرفکنندگان (Consumers) رویداد در برنامه Python خود کنید.
تولیدکنندگان رویداد:
در Python، میتوانید با استفاده از کتابخانه confluent-kafka-python یک تولیدکننده رویداد ایجاد میکنیم. تولیدکننده مسئول تولید و انتشار رویدادها به تاپیکهای Kafka است. در زیر مثالی از یک تولیدکننده رویداد را مشاهده میکنید:
from confluent_kafka import Producer # Configure the Kafka producer producer = Producer({'bootstrap.servers': 'kafka_bootstrap_servers'}) # Define the topic to which events will be published topic = ‘topic_name' # Produce events for i in range(10): event_data = f’Event {i}’ producer.produce(topic, value=event_data.encode('utf-8')) # Flush the producer to ensure all events are sent producer.flush()
مصرفکنندگان رویداد:
میتوانیم با استفاده از همین کتابخانه، یک مصرفکننده رویداد ایجاد کنیم. مصرفکننده مسئول اشتراک گذاری در تاپیکهای Kafka، دریافت رویدادها و پردازش آنهاست. در زیر مثالی از ایجاد یک مصرفکننده رویداد را مشاهده میکنید:
from confluent_kafka import Consumer, KafkaError # Configure the Kafka consumer consumer = Consumer({ 'bootstrap.servers': 'kafka_bootstrap_servers', 'group.id': 'consumer_group_id', 'auto.offset.reset': 'earliest' }) # Define the topic(s) to which the consumer will subscribe topics = ['topic_name'] # Subscribe to the topic(s) consumer.subscribe(topics) # Start consuming events while True: msg = consumer.poll(1.0) # Wait for events for a maximum of 1 second if msg is None: continue if msg.error(): if msg.error().code() == KafkaError._PARTITION_EOF: # End of partition event continue else: # Handle other error types print(f"Error: {msg.error()}") continue # Process the received event event_data = msg.value().decode('utf-8') print(f’Received event: {event_data}’) # Close the consumer consumer.close()
مقاله مرتبط:
بعد از معرفی دیزاین event driven یکی از دغدغه های اصلی عدم امکان تشخیص مشکلات سیستم توسط برنامه نویس بود چرا که چرخه ای که داده طی میکرد به طور کامل مشخص نبود. مقاله زیر که در سال ۲۰۲ برای مدرک فوق لیسانس یک دانشجو منتشر شده است نحوه پیاده سازی یک معماری میکروسرویس پیچیده و مقیاس پذیر و reliable مبتنی بر ساختار event driven را نشان میدهد و هدف اصلی آن پیاده سازی سیستمی است که visibility داده تامین شود و اتفاقاتی که روی آن رخ میدهد در سرتاسر سیستم مشهود باشد.
لینک در گوگل اسکولار:
دیگر منابع: