اینجا یک سری از موارد پایهای معماری نرمافزار رو بررسی میکنیم:
اولین مورد:
Chaos Engineering:
در این رویکرد بهصورت عمدی و کنترلشده، خرابی یا فشاری در سیستم ایجاد میکنیم تا تحمل سیستم را بسنجیم. دلیل انجام این کار این است که نهتنها سنجیدن هر یک از سرویسها اهمیت دارد، بلکه ارتباط بین آنها نیز اهمیت دارد. پس سنجش رفتار کل سیستم بسیار اهمیت دارد. پس در این رویکرد نهتنها رفتار هر یک از سیستمها را میسنجیم، بلکه ارتباط بین آنها را هم بررسی میکنیم.
در این فرآیند اول بررسی میکنیم که سرویس ما در وضعیت پایدار باید چه رفتاری داشته باشد. سپس یک سناریو ایجاد میکنیم که در آن یکی از سرویسها به مشکل بر بخورد یا بهطور کامل قطع شود. مثلا pod یکی از آنها بهطور کامل پایین بیاید. سپس بررسی میکنیم در این شرایط آیا کل کارایی از بین میرود و یا سرویس دیگر قابل استفاده نیست یا همچنان میشود از آن استفاده کرد.
Basiri, A., Behnam, N., de Rooij, R., Hochstein, L., Kosewski, L., Reynolds, J., & Rosenthal, C. (2017). Chaos Engineering. arXiv:1702.05843
Backend for Frontend:
در این الگو برای هر مدل frontend یک کد backend اختصاصی طراحی میشود. یعنی به جای اینکه همه استفادهکنندگان از یک API استفاده کنند، هر کدام یک API با نیاز خودش دارد. در این ساختار Frontend فقط همان دادهای که نیاز دارد را دریافت میکند.
در چنین ساختاری، این لایه بین frontend و backend قرار میگیرد و این لایه میتواند چند API مختلف را صدا کند یا فیلدهای اضافی را حذف کند و خروجی نهایی، همان خروجی قابل استفاده برای آن frontend مورد نظر باشد.
بهطور مثال، امکان دارد که یک کلاینت، در نسخه frontend موبایل خود اطلاعات کمتری نسبت به نسخه وب نیاز داشته باشد. در این شرایط این لایه کمک میکند که نسخه موبایل دقیقا موارد مورد نیاز خود را دریافت کند.
Newman, S. Pattern: Backends for Frontends
Microsoft Azure Community Hub. Implementing the Backend-for-Frontend (BFF) / Curated API Pattern Using Azure API Management
Artificial Intelligence for Software Engineering:
این مفهوم به معنی استفاده از هوش مصنوعی برای کمک به فرآیندهای مهندسی نرمافزار است. در این زمینه AI در تولید کد، تولید تست یا مستندسازی و دیباگ کمک میکند. در اصل، بخشی از کارهای تکراری در توسعه نرمافزار خیلی سریعتر پیش میرود که میتواند به ما کمک کند زمان بیشتری برای طراحی و تصمیمگیریهای مهم داشته باشیم. البته فقط در تولید کد استفاده نمیشود و میتواند در فرآیندهای نرمافزاری، بهطور مثال از user story تا تولید تست، به ما کمک کند.
IBM. AI in Software Development
Google for Developers. Gemini Code Assist Overview
SE4AI:
این مفهوم تقریبا برعکس مورد قبلی است. در این رویکرد از اصول مهندسی نرمافزار برای مدیریت و یا ساخت سیستمهایی که با هوش مصنوعی کار میکنن، استفاده میکنه. یعنی این سیستمهای AI بتوانند در تمام حالتها در یک محیط واقعی کار کنند. تفاوت این رویکرد با قبلی در این است که در اینجا موضوع اصلی خود سیستم AI است ولی در مورد قبلی از AI صرفا بهعنوان کمک استفاده میکنند.
بخش مهم در این زمینه MLOps است که موارد و اصول DevOps را به سیستمهای ML میآورد و موارد آن را برای مدلهای ML خودکار میکند.
Google Cloud. MLOps: Continuous delivery and automation pipelines in machine learning
Microsoft. Responsible AI Principles and Approach
MLOps:
این مفهوم در مورد قبلی هم توضیح داده شد، ولی بهصورت مفصلتر، این رویکرد باعث میشود مدلهای ML در محیطهای واقعی هم قابل اعتمادتر باشند. در DevOps معمولا تمرکز اصلی روی کد و مواردی مانند Deployment هست، اما در MLOps مواردی مثل کد، monitoring و ارزیابی مدل هم اهمیت دارد. یکی از اهداف اصلی این رویکرد این است که چرخه عمر مدلهای ML را خودکارسازی کند و یعنی ما مدل را بهصورت کامل monitor و تست میکنیم. مفاهیم CI/CD هم در این زمینه استفاده میشود.
AWS. What is MLOps? Machine Learning Operations Explained
Google Cloud. MLOps: Continuous delivery and automation pipelines in machine learning
Infrastructure as Code (IaC):
در این روش، منابعی مثل سرور، شبکه، دیتابیس و اینگونه موارد زیرساخت، به جای تنظیم دستی، در فایلهای configuration تعریف میشوند. دلیل استفاده از این رویکرد این است که بتوانیم منابع زیرساختی را قابل استفاده دوباره، قابل نسخهبندی و قابل خودکارسازی کنیم. مثلا به جای اینکه یک نفر بهصورت دستی موارد مورد نیاز را در پنل یا سایر interfaceها وارد کند، موارد و وضعیت مطلوب و مورد نیاز ما در کد نوشته شده و توسط یک سری ابزار ایجاد یا تغییر میکند و اصطلاحا configure میشود. مدیریت دستی موارد زیرساخت در مقیاس بالا میتواند باعث خطای انسانی شود. این روش باعث میشود تنظیمات محیط یکسانتر و قابل کنترل باشد.
AWS. What is Infrastructure as Code?
HashiCorp Developer. Use infrastructure as code
API Gateway & Service Mesh:
API Gateway یک لایه در ورودی سیستم هست که درخواستها را دریافت میکند و آنها را به سرویسهای مناسب در backend هدایت میکند. در اصل، یک نقطه ورود واحد برای APIها هست. در این معماری کلاینت لازم نیست با چندین microservice بهصورت مستقیم در ارتباط باشد، بلکه این موارد از طریق API Gateway انجام میشود.
Service Mesh یک لایه زیرساختی برای مدیریت ارتباطات بین خود سرویسها هست. یعنی بدون نیاز به تغییر کد برنامه، قابلیتهایی برای امنیت و کنترل ترافیک فراهم میکند. برای مثال، اگر دو سرویس باید باهم ارتباط بگیرند، service mesh این ارتباط را امنتر و قابل کنترلتر میکند. پس بهصورت کلی API Gateway دریچه ورود است برای APIهای سیستم، ولی Service Mesh ارتباطات داخلی بین خود سرویسها را کنترل میکند.
AWS. Amazon API Gateway
Istio. The Istio Service Mesh
CQRS (Command Query Responsibility Segregation):
یک الگوی معماری هست که عملیات خواندن داده را از نوشتن یا تغییر دادن سیستم جدا میکند. یعنی در این روش command مسئول تغییر وضعیت سیستم هست و بخش Query فقط برای دیدن داده استفاده میشود. یعنی command معمولا به معنای قصد کاربر برای تغییر یک مورد هست و معمولا این عملیات دادهای را تغییر میدهد و نباید مثل query برای نمایش مستقیم دادهها استفاده شود. query هم نباید بتواند وضعیت سیستم را تغییر دهد و فقط برای نمایش اطلاعات استفاده میشود. البته این الگو برای تمامی سیستمها مناسب نیست، به دلیل اینکه میتواند پیچیدگی معماری را افزایش دهد. پس بهتر است فقط زمانی استفاده شود که تفاوت جدی بین read و write وجود داشته باشد.
Microsoft Learn. CQRS Pattern
Fowler, M. CQRS
TechTarget. What is CQRS (Command Query Responsibility Segregation)
Event-Driven Architecture (EDA):
مانند موارد قبلی، یک الگوی معماری هست که سرویسها با ارسال eventها باهم ارتباط برقرار میکنند که این eventها معمولا نشاندهنده یک تغییر وضعیت یا مورد مهمی در سیستم هست. یکی از ویژگیهای مهم این معماری کاهش وابستگی بین سرویسها هست. یعنی ارسالکننده event نیازی ندارد بداند که چه کسانی این event را دریافت میکنند یا چه کاری برای آن انجام میدهند که وابستگی بین سرویسها را کمتر میکند. اما این رویکرد یک سری چالشهایی دارد که بعضی موارد مانند دیباگ کردن را سخت میکند، چون ترتیب این eventها هم میتوانند مهم باشند و به دلیل ارتباط کمتر، trace کردن این موارد سختتر خواهد شد.
پس این معماری برای سیستمهایی مناسب هست که رخدادهای زیادی دارند یا نیاز هست سرویسها وابستگی کمتری بهم داشته باشند. اما برای سیستمهای ساده، پیچیدگی میتواند درست کند.
AWS. What is EDA? Event-Driven Architecture Explained
Microsoft Learn. Event-driven architecture style
Serverless Architecture:
در این معماری برنامهها بدون مدیریت مستقیم سرور اجرا میشوند. یعنی در این مدل بهصورت خودکار بر اساس درخواستها یا eventهای مختلف منابع داده میشوند. یعنی مثلا اگر در زمانی ترافیک زیاد بود، منابع بیشتری فراهم میشود و در زمان کم شدن ترافیک، منابع کم میشوند.
در این مدل بر اساس استفادهای که از منابع میشود، هزینه گرفته میشود و در هزینهها بسیار صرفهجویی میشود. البته این معماری چالشهایی مانند وابسته بودن به cloud provider و سختتر شدن دیباگ دارد. یعنی به دلیل اینکه ما از cloud provider منبع میگیریم، در زمانی که نیاز هست این منابع برای زمانی زیادتر شوند یا کمتر شوند، به cloud provider وابسته میشویم.
در اصل این معماری به توسعهدهندگان کمک میکند تیمها سریعتر توسعه دهند و کمتر درگیر مسائل زیرساخت باشند.
AWS. Serverless Computing
Google Cloud. Serverless
Google Cloud. What is Cloud Run
API-first Approach:
در این رویکرد APIها از همان اول فرآیند طراحی بهعنوان بخش اصلی سیستم در نظر گرفته میشوند. یعنی فقط یک خروجی از backend نیست، بلکه برای ارتباطات بین سرویسها و کلاینتها استفاده میشود. در این روش معمولا قبل از نوشتن کد اصلی، به طراحی API پرداخته میشود. این مسئله یک توافق بین تیمهای مختلف درست میکند و تیمها میتوانند بهصورت موازی کار کنند. مثلا تیم frontend میتواند با مستندات یک سری mock API درست کند و به جای APIهای اصلی از آنها برای تست استفاده کند که به testability سیستم هم کمک میکند. البته برای پروژههای کوچک میتواند پیچیدگی را بیشتر کند.
Postman. What is API-first? The API-first Approach Explained
SmartBear / Swagger. Adopting a Design First Approach with OpenAPI Specification
Domain Driven Design:
مدلسازی در این رویکرد براساس دامنه کسبوکار و نیازهای واقعی سیستم هست. یعنی طراحی سیستم فقط از دید فنی انجام نمیشود و مفاهیم کسبوکار در آن اثر دارند. دامنه در اینجا همان حوزه کسبوکاری هست که برای آن نرمافزار میسازیم. مثلا در یک سیستم فروشگاهی، سفارش، پرداخت و ... بخشی از دامنه هستند.
این معماری به ما کمک میکند مرز سرویسها را بر اساس مرزهای واقعی کسبوکار مشخص کنیم و نه لایههای فنی. البته این رویکرد برای تمام پروژهها نیاز نیست و امکان دارد باعث زیاد شدن پیچیدگی در آنها شود.
Microsoft Learn. Designing a DDD-oriented microservice
Microsoft Learn. Use domain analysis to model microservices
Martin Fowler. Bounded Context
Microsoft Learn. Identify microservice boundaries
Hexagonal architecture:
این معماری برای این معرفی شد که منطق اصلی برنامه از جزئیات فنی آن جدا شود. در این معماری هسته برنامه و مهمترین بخش آن قوانین کسبوکار و منطق اصلی آن است و به تکنولوژیای وابستگی ندارد و به جای ارتباط مستقیم با قسمت فنی، از port استفاده میشود.
Port در اصل یک interface هست که مشخص میکند منطق برنامه چگونه با دنیای بیرون ارتباط بگیرد. یعنی برای قسمت اصلی برنامه مهم نیست با چه جزئیات فنیای کار میکند. مثلا برای بخش اصلی اهمیت ندارد که از چه دیتابیسی استفاده میشود. Adapter کمک میکند جزئیات فنی بیرون از هسته اصلی را برای آن قابل فهم کند. این معماری تست کردن را بسیار راحتتر میکند، چون بخش منطق برنامه به لایه فنی خارج آن وابستگی ندارد.
AWS Prescriptive Guidance. Hexagonal architecture pattern
AWS Prescriptive Guidance. Building hexagonal architectures on AWS – Overview
Event Sourcing:
در این الگو، به جای اینکه فقط آخرین وضعیت بهصورت event ذخیره شود، تمام تغییرات وضعیت بهصورت کامل ذخیره میشود که هر کدام از این eventها مشخص میکند چه چیزی وضعیت سیستم را تغییر داده است. در این ساختار event جدید به event قبلی اضافه میشود و event قبلی پاک نمیشود. اینگونه ما یک تاریخچه کامل از تغییرات سیستم داریم که برای دیباگ کردن و گزارشگیری به شدت مفید است. وضعیت فعلی در این رویکرد به این صورت مشخص میشود که سیستم به ترتیب آنها را خوانده و با اعمال آنها، وضعیت سیستم را بعد از هر event بازسازی میکند. فقط دقت شود که این الگو زمانی به درد ما میخورد که نیاز داشته باشیم تمام تغییرات قبلی سیستم را داشته باشیم، وگرنه حفظ کردن تمامی این eventها فضای زیادی میتواند بگیرد که برای تمام سیستمها مناسب نیست.
Microsoft Learn. Event Sourcing Pattern
AWS Prescriptive Guidance. Event Sourcing Pattern
Low-code/No-code platforms:
پلتفرمهایی هستند که ساخت اپلیکیشنها و نرمافزارها را راحتتر کرده و بدون کدنویسی یا با حداقل کدنویسی میشود با آنها نرمافزار ساخت. یعنی با داشتن یک interface UI و استفاده از drag and drop و استفاده از templateهای مختلف میتوانیم نرمافزار مورد نیاز را داشته باشیم. این رویکرد میتواند فشار را روی تیمهای فنی کم کند، چون بعضی موارد ساده و تکراری میتواند با تیمهای غیرفنی پیش برود. البته در پروژههایی که سفارشی هستند میتواند باعث محدودیت شود و کنترل را روی کد کم کند. از طرفی برای customize کردن هم محدودیت درست میکند، چون خیلی از موارد دیگر دست خود تیم فنی نیست.
IBM. Low-Code vs. No-Code: What’s the Difference
AWS. What is Low Code? Low Code Explained
IBM. What is No-Code?
Business Process Management Systems (BPMS):
این سیستمها کمک میکنند فعالیتها و وظایف مختلفی که برای یک سازمان هست بهتر مدیریت و هماهنگ شوند. در این فرآیند معمولا اول فرآیندها مدلسازی میشوند که به ذینفعان کمک میکند بهتر ارتباطات و فعالیتها را ببینند و درک کنند.
هدف این است که به جای اینکه فرآیندها فقط در کاغذها و مستندات باشند، در سیستم قابل پیگیری باشند و برای فرآیندهایی مناسب هست که چند واحد سازمانی و چندین نقش درگیر آن هستند که به افزایش شفافیت کمک میکند و کنترل را روی فرآیندها افزایش میدهد. البته BPMS برای تمام کارها لازم نیست و برای فعالیتهای کوتاه نیازی به آن نیست.
IBM. What is Business Process Management
TechTarget. What is Business Process Management Software (BPMS)?
Microsoft. Power Automate: Business Process Workflow Automation
Message Queue (such as Kafka and RabbitMQ):
یک واسطه برای ارسال و دریافت پیام بین بخشهای مختلف سیستم است. به جای اینکه دو سرویس مستقیم بهم وابسته باشند، یک سرویس پیام را داخل یک صف گذاشته و سرویس دیگر بعدا آن را دریافت میکند و پردازشهای لازم را انجام میدهد. خوبی این روش این هست که نیاز نیست حتما هم دریافتکننده و هم فرستنده در دسترس باشند. مثلا اگر یکی از آنها بهصورت موقت قطع شود، این پیام در صف باقی میماند تا وقتی که مشکل رفع شده و پیام را بتواند بررسی کند. بهطور مثال، در RabbitMQ صفها معمولا رفتار FIFO دارند. یعنی پیامها به ترتیب پردازش میشوند، ولی میتوانیم تنظیمات مختلفی روی آنها انجام دهیم.
AWS. What is a Message Queue?
RabbitMQ. Queues
Containers (eg., Docker) and Container orchestration (e.g., Kubernetes):
Container در اصل یک بسته قابل اجرا از کد برنامه و dependencyهای آن است که باعث میشود رفتار سیستم در تمام سیستمها بهصورت یکسان باشد. Containerها به دلیل اینکه سیستمعامل جداگانه ندارند سبک هستند و setup سریعتری دارند. Docker یکی از ابزارهای مهم هست که کمک میکند تمام موارد برنامه با تمام dependencyها در محیطهای مختلف قابل Deploy باشند. اگر تعداد containerها کم باشد، میشود با Docker Compose آن را مدیریت کرد ولی اگر تعداد بیشتر باشد، به دلیل پیچیدگی بیشتر باید از ابزارهایی مانند Kubernetes استفاده کنیم. در Kubernetes کوچکترین واحد pod هست که میتواند شامل چند container باشد که همزمان اجرا شده و منابع را باهم به اشتراک میگذارند.
پس بهصورت کلی این ابزارها به ما کمک میکنند که ما بتوانیم یک نرمافزار را بدون نیاز به دانستن محیط آن اجرا و مدیریت کنیم.
Docker. What is a Container
Kubernetes Documentation. What is Kubernetes?
Multi-Tenancy Architecture:
در این نوع معماری با یک زیرساخت و نرمافزار به چند مشتری سرویس میدهیم. یعنی چند مشتری میتوانند از یک زیرساخت و یا اپلیکیشن استفاده کنند، ولی دادهها و تنظیمات متفاوتی نسبت بهم داشته باشند و نمیتوانند به دادههای هم دست پیدا کنند. مثلا در مدل SaaS یک نرمافزار از طریق شبکه ابری به چندین مشتری ارائه میشود.
در بعضی سیستمها تمام منابع بین مشتریها به اشتراک گذاشته میشود و در بقیه موارد بعضی منابع فقط مشترک هستند. مزیت این معماری این است که هزینهها کاهش پیدا کرده و از منابع بهتر استفاده شود. البته در این زمینه باید به امنیت داده و کنترل دسترسی هم بسیار دقت کرد که میتواند باعث چالش شود.
IBM. What is Multi-Tenant?
Microsoft Learn. Architect multitenant solutions on Azure
Microsoft Learn. Tenancy models for a multitenant solution
Data Migration:
فرآیند انتقال دادهها از یک سیستم به سیستم دیگر است که هدف آن این است که دادهها با کمترین اختلال و بدون از دست رفتن به مقصد جدید منتقل شوند. یکی از چالشهای این فرآیند این است که اگر دادهها قدیمی باشند، میتواند در سیستم جدید ناسازگار باشد. پس مهم هست قبل از انجام عملیات حتما دادهها بررسی شوند. همچنین باید در این فرآیند به امنیت دادهها هم اهمیت داد و پس از انجام آن، دادهها را حتما بررسی کرد تا مشکلی توی آنها بعد از انتقال وجود نداشته باشد.
IBM. What is Data Migration
AWS. What is Data Migration? Data Migration Plan Explained