بیست مفهوم مهم در معماری نرم افزار

به نام خدا

1. مفهوم Domain Driven Design: اولین تعریفی که میتوانم بگویم Domain Driven Design یک دیدگاه به نرم افزار است از بالا پایین. وقتی که تیم توسعه به دنبال توسعه نرم افزار میباشند، باید دقت شود که اولویت اول و اصلی ما انتخاب تکنولوژی نیست (مشابه جمله عمو باب در کتاب معماری تمیز) بلکه اولویت اول ما business هست.

وقتی معماری یک پروژه را در نظر بگیریم از لحظه ای که از کد خروجی گرفته ایم با پسوند های مختلف مثلا برای جاوا .jar و ..... تا موقعی که به بالاترین سطح یعنی پروژه میرسیم یک سطح از انتزاع را میبینیم مثل شکل:

که کل این ساختار را میتوان Service نامید. اما تا این مرحله، این نما دید اکثر برنامه نویسان میباشد، ولی اگر بخواهیم یک دید سطح بالاتری را اتخاذ کنیم و چند Service مختلف را کنار هم قرار دهیم، از اجماع این سرویس ها بخشی از زیرساخت را تشکیل میدهند که برای حل برخی از مشکلات اساسی و مهم تر که در اول مطلب اشاره کردم یعنی مشکل لایه business میباشد. از مجموعه این سوریس ها domain تشکیل میشود.

در واقع همه ی این سرویس ها که درکنار هم قرار گرفته اند بخشی از مشکلات domain را حل میکنند که به آن ها Sub-Domain گفته میشود. ما domain های مختلفی داریم اگر بخواهیم domain e-commerce در نظر بگیریم Sub-Domain میشود product domain یا customer domainو... .

در اول مطلب یک تعریف بالا به پایین بیان شد که در شکل بالا domain در راس(top) همه ی سرویس های ما قرار دارد. Domain Driven Design دو ابزار در اختیار ما قرار میدهد، اولی Strategic design tools میباشد که به کمک آن میتوان تمام مشکلات مربوط به Software Modeling میباشد

و ابزار دوم Tactical design tools هست که بیشتر مهندسان نرم افزار و توسعه دهنگان به این بخش توجه زیادی دارند

و در آخر ابزار Strategic design tools بسیار مهم و حائز اهمیت میباشد و ما به کمک Domain Driven وDesign شروع به حل مشکلات میکنیم در مقیاس بالا و دید انتزاعی تر (مشابه عمو باب) مثلا سیستم عامل ویندوز 10 از ویندوز 8 خیلی بهتر کاربردی تر میباشد در واقع ما باید نیاز های مشتریان و به طور کلی ذینفع ها در لایه بیزینس را مد نظر داشته باشیم.

مفهوم Hexagonal Architecture :

در شکل زیر هر لایه که در انتهای فلش قرار داشته باشد از لایه قبلی خود هیچ اطلاعی ندارد یعنی در این جا لایه data access از لایه business logic اطلاعی ندارد.

حالا اگر جهت فلش تغییر کند و وابستگی تغییر کند باز هم business logic روی data access تاثیر میگذارد از طریق یک interface که توسط logic تعریف میشود

که انتظار میرفت در لایه data access تعریف شود. این interface، port نامیده میشود و لایه data access میداند که به چه صورت این interface را implement کند که به آن adapter گفته میشود.

ولی به طور کلی این معماری به جای port and adapter به نام Hexagonal Architecture شناخته میشود.

در واقع ما اطراف application core خود adapter های زیادی داریم.

و به این معنی هست که application core دارای هیچگونه وابستگی نیست و adapter های مختلف به آن وابسته هستند و به راحتی میتوان تست برای application core نوشت.

فرض کنید Adapter هایی مثل user interface & API & Command line میتوان primary نامید چون تاثیر مستقیم در core میگذارند و Adapter هایی مثل data access & email & message queue میتوان secondary نامید زیرا لایه core تاثیر مستقیمی روی آن ها میگذارد.

میتوان به لایه های مختلفی تقسیم بندی کرد لایه application که وابستگی ها همیشه به سمت داخل هستند. همه این adapter ها در لایه application در دو قسمت presentation & infrastructure و در مرکز بدون هیچ وابستگی domain که همان core business object ما هست(در فصل 22 کتاب معماری تمیز). همچنین interface هایی همچون domain services & IRrepository & IUnitOfWorkds همه این ها همان port هایی هستند که انتظار میرود implement شوند توسط adapter در لایه infrastructure. و لایه بالای interface ها مربوط به یکسری service ها میباشد.

در بحث معماری تمیز مشابه شکل صفحه 203 کتاب معماری تمیز شکل بالا را به صورت معماری

تمیز clean architecture ترسیم میکنیم:

مفهوم (Command Query Responsibility Segregation) CQRS:

به این معنی هست که شما یک data را مینویسی ولی هنگام بازیابی کردن همان data روشی متفاوتی را اتخاذ میکنی. در ادوار گذشته شما یکجا data را put و جای دیگر get میکردی به دلیل داشتن CRUD Operation یعنی شما write & read میکنید دقیقا از یک data-source یا وقتی تعداد write & read ها زیاد میشه و نیاز است تا یک شکافی ایجاد شود بین این حجم از خواندن و نوشتن ها.

اگر شما از Event Sourcing System استفاده کنید برایquery نوشتن در سیستم به مشکل بر خواهید خورد زیرا برای ساختن state application شما باید به همه ی event ها بروید تا یک single application وstate را بدست آورید و برنامه شما در بحث quality attributes مثل performance به مشکل بر خواهد خورد زیرا در زمان run-time باید به صورت مرتب در event های مختلف search انجام دهد.

پس علت اصلی ما در استفاده از CQRS Pattern شما به راحتی میتوانید query های read & writeرا

به صورت Componentهای شخصی جداسازی(Segregate) و تفکیک کنید پس یک read operation و write operation خواهیم داشت که این تفکیک و operationهای مجزا کمک به load سریع برنامه و به صورت مستقل scalabilityبالایی برخوردار خواهد شد.

یک مثال از CQRSکه در آن سه نوع سرویس مختلف داریم که به روش Event Sourcing باید از همه ی سرویس ها لاگ بگیریم درحالی که با قرار دادن یک functionality به نام Orders Overview میتوانی تمام query ها را در یکجا collect کنید و در اختیار مشتری قرار دهید:

مفهوم Event Sourcing:

یک معنی جایگزین برای Storing Data میباشد با استفاده از لاگ هایی از event ها به جای استفاده از table ها که میتوان در آن ها از update & read & delete استفاده کرد.

در Event Sourcing جدولی طراحی میشود که در آن اتفاقاتی اعم از update & read & delete روی میدهند به صورت دقیق ضمیمه و ثبت میشوند.

البته باید این نکته را مدنظر قرار داد reading data در Event Sourcing دارای step های اضافی هست. ادامه توضیحات با توجه به شکل بیان میشود:

ابتدا داده ها خوانده شده در مورد 1و2 شکل و سپس event ها با هم ترکیب شده در زمان run-time و دقیقا به همان نقطه ای که اطلاعات قرار دارند هدایت میشوید مورد 3 در شکل بالا، نکته ای که حائز اهمیت است دیتا های ما به صورت فیزیکی به فرمت event ذخیره شده اند و درصورت فراخوانی، تمام ویژگی ها و موارد آن ها نیز فراخوانی خواهد شد و در مقیاس بزرگ با مشکل متفاوتی روبه رو خواهیم شد و این به این دلیل هست که از یک مدت زمانی به بعد تعداد event ها به شدت زیاد میشود و در زمان run-time گرفتن execute از داده ها کار زمان بری خواهد شد. راه حل این مشکل اجرای محاسبات در زمان نوشتن اطلاعات میباشد نه در زمانی که میخواهیم داده ها را write و ذخیره کنیم و از مزایای این روش این است که محاسبات روی داده ها فقط یکبار آن هم درزمان نوشتن انجام میشود و مهم نیست داده ها در زمان های دیگر چند بار read شوند که به این تکنیک CQRS گفته میشود که در صفحات قبل به صورت کامل توضیح داده شده است 😊.

مفهوم MVVM:

در واقع یک Design Pattern هست که در مواقعی که کد های ما قابل استفاده مجدد یا reusable هستند یا نیاز به maintain و نگه داری دارند استفاده میشود. یکی از استفاده های کلیدی آن در مواقعی هست که شما در حال توسعه یک application روی platform های متفاوت هستید به عنوان مثال استفاده از framework Flutter که میتواند روی platform مختلف کد های منبع خود را run کند.

به عنوان مثال در android & ios & windows، پس شما با MVVM میتوانید کل View model به اشتراک بگذارید در تمامی platform های ذکر شده. تنها بخشی از MVVM است.

که نیازمند platform-specific code است همان بخش View هست تا بتواند UI مورد نظر را در platform ها یمختلف به صورت مناسب نمایش دهد.

به عنوان مثال در مورد ماژول هایی صحبت میکنیم که در نهایت قابل تطابق با MVVM Design Pattern میباشد.

· یک:View همان UI هست یعنی آن چیزی که کاربر روی صفحه نمایشگر خود میبیند.

· دو: View Model منطق برنامه ما هست که به ازای ورودی application یک Expected result به نمایش میگذارد.

· سه: Model: همان data هست

که این ماژول ها با همدیگر ارتباط دارند:

اما تعریفی مختصر از data binding:

وقتی استفاده میشود که درخواست ایجاد ارتباط بین Logic & User-Interface اتفاق میافتد

که User-Interface شامل Dependency Object و Logic شامل Object میباشد، که دارای دو نوع ارتباط میباشند:

در ارتباط اول One-Way فقط و فقط Object قادر به تغییر اطلاعات میباشد، ولی در ارتباط Two-Way هر دوطرف قادر به ایجاد تغییرات هستند.

اما interface که ما مقابل Notifications استفاده میکنیم شامل INotifyPropertyChange میباشد که هر کدام از data های مربوط به برنامه تغییر کرد notify و اطلاع دهد به عنوان مثال وقتی برنامه از سیستم عامل اندروید به ios تغییر کرد و دومی ObservableCollection<T> میباشد که دسترسی تغییرات در سطح کلاس یا combine کردن آن ها را به ما میدهد.

مفهوم Micro-Frontends:

درواقع یک رویکرد برای تست کردن Micro-service ها میباشد یا کدی برای بخشی از یک صفحه وب است. در این مدل صفحه وب host میکند آن component را و میتوان آن را Host page نامید. یک فریم

ورک Micro-FE FrameWork وجود دارد که بین Host page و Micro-Frontends قرار میگیرد

تا load ها و unloading ها را مدیریت کند.

یک تعریف ساده تر این است که Micro-Frontends بخش Front-End را به بخش های کوچکتر با قابلیت مدیریت بیشتر و بهتر تقسیم میکند و این امر باعث خوشحالی توسعه دهندگان در امر توسعه نرم افزار میشود. وقتی که ما به این وبسایت آمازون نگاه میکنیم

یکسری user-interface element میبینیم که تارگت Micro-Frontends میباشد، درواقع همان پنل های میانی که در شکل مشخص شده:

و همچنین بخش header & footer سایت هم تارگت مناسبی برای Micro-Frontends میباشد زیرا باید بین صفحات مختلف سایت به اشتراک گذاشته شوند. رفتن به سمت Micro-Frontends یکسری مزیت های جالبی دارد:

1. یک: Team Scalability: کمک میکنه به ما که افراد بیشتری به عنوان توسعه دهنده و برنامه نویس بتوانند روی web-page کار کنند. Micro-Frontends کمک میکند که ما بتوانیم بخش های مختلف سایت را به صورت تیم های مجزا deploy & develop کنیم.

در واقع این رویکرد به ما کمک میکند تا بین وظایف مختلف خط بکشیم و در زمینه های مختلف معماری تعریف کنیم و کمک میکند به تیم تا کار خود را handle کند به طور مستقل

1. دو: Reusability : فرض کنید شما یک ماژول جذاب در بخش UI در Home-Page خود را دارید میتوانید به راحتی در بخش About Us نیز استفاده کنید

2. سه: Digital Experiences: به کمک Micro-Frontends میتوانیم کد های front-end را تحت کنترل داشته باشیم تا بتوانیم تجربه دیجیتالی فوق العاده ای را برای کاربران به ارمغان بیاوریم.

3. چهار: Different Technology: ما به کمک Micro-Frontends میتوانیم در بخش های مختلف کار از تکنولوژی های متفاوتی استفاده کنیم و code base های آن را از هم جدا کنیم. در نهایت هر component کار خود را به طور مستقل انجام میدهد.

4. پنج: Share Common Structure: در واقع به این معنی است که ساختار های مرسوم و معمول را بین صفحات مختلف application یا web site به اشتراک میگذارد مثل Header & Footer & Page Navigation & Authentication

5. شش: Decoupling: به سازمان ها امکان scalable ownership محصولات دیجیتالی را میدهد تا امکان تولید کد های Decouple شده با کد repository کوچک با قابلیت نگهداری بالا. این Decoupling به توسعه دهندگان کمک میکند تا عناصر خاصی از جمله build برنامه test برنامه و deployment pipeline را به صورت مجزا handle کنند، که این خود باعث میشود تا محصول یا همان product ما سریع تر وارد بازار شود و در Update های بعدی risk کمتری برای تیم توسعه داشته باشد.


مفهوم API Gateway:

خب API = Application Programming Interface یک interface از application ها هست که به دو برنامه اجازه صحبت با یکدیگر را میدهند. وقتی شما اقدام به استفاده از Instagram یا پیامک عادی یا رزرو بلیط هواپیما از سایت میکنید، در واقع از API ها استفاده میکنید. API ها اقدام به Make OR Break کردن applicationها با توجه به نیازمندی های ما در بحث Infrastructure :

یعنی Secure & Scale & Accelerate میکنند.

در معماری های ادوار گذشته ما Monolithic Application ها را داشتیم که کل برنامه به صورت یکپارچه بود.

و بعدا معماری Micro-Servicesآمد که بخش های مختلف برنامه را به قطعات کوچکتر شکست تا تیم های مختلف بتوانند روی بخش های کوچکتر کار کنند و این وابستگی از بین برود که کمک میکند app ما scalableو availabilityبالا و resource efficient باشد.

اما در Micro-Service-Oriented-Architectureنیاز به APIهایی داریم تا به برقراری ارتباط بین clientها و Micro-Serviceها کمک کنند.

ما باید برای سیستم های توزیع شده ترافیک APIها را به صورت ایمن تامین کنیم، که راهکار اصلی API-Gateway میباشد. API-Gatewayدقیقا بین client های شما و Micro-Service ها قرار میگیرد از مزیت های آن:

1. یک: Client Performance: به جای این که از web or App من درخواست های مکرر به Micro-Serviceها فرستاده شود این درخواست ها به API-Gateway میرود، و API-Gatewayبه صورت Randomدرخواست ها را بین Micro-Service ها پخش میکند و این کار موجب کاهش Latencyمیشود.

1. دو: Security: شما به راحتی میتوانید متوجه حملات امنیتی شوید به شکلی که در API-Gateway میتوان سرویس هایی همچون Authorization & Authentication و یا لایه های دیگر امنیت را قرار داد.

2. سه: Protocol Translation: اگر ما پروتکل های متفاوتی همچون HTTPS داریم که امنیت را برقرار میکند و بعد از API-Gateway میتوان تبدیل به HTTP شوند. وقتی درخواستی به صورت HTTPS based به سمت API-Gateway می آید، که میتواند Rest API یا GraphQL باشد، بعد دریافت درخواست HTTPS، API-Gateway درواقع Validation آن را چک میکند و درمرحله بعد چک میکند آیا IP Address که درخواست شده مجاز و اجازه دسترسی به آن است یا خیر متناسب با طلاعات HTTP Header deny/accept list :

و بعد به سراغ Authorization & Authentication میرود که دربخش قبلی توضیح داده شد

سایر ویژگی هایی که API-Gateway به ما میدهد:

مثل error handling ,monitoring, logging, caching. به صورت جامع ما میتوانیم API-Gateway های متفاوتی داشته باشیم که یکی از کاربرد های آن در IOT(IOT موضوع پروژه اینجانب) میباشد.


مفهوم BPMS:

سه مفهوم 1. model, 2. Build 3. Run سه قدم طلایی برای موفقیت در BPMS هستند. میتوانم این مفهوم با یک سوال شروع کنم که آیا شرکت یا سازمان شما دارد به صورت Agile کار میکند آیا شما اطلاعی از فرایند ها دارید و مهمتر از آن آیا میتوانید اوضاع را تحت کنترل در بیاورید؟ و اگر اتفاقی در business شما افتاد آیا قادر به پاسخ گویی سریع و مطلع کردن سایر اعضای سازمان یا شرکت هستید؟

ما با کمک BPMS کمک میکنیم که business مورد نظر بیشتر efficient و flexible باشد. فرض کنید در یک شرکت یکی از کارمندان نیاز به یک لپ تاپ دارد، این مشکل آن کارمند نیست ولی در اکثر شرکت ها و ارگان ها فرایند ثیت درخواست بسیار طولانی و طاقت فرسا هست و نیاز به نامه نگاری دارد :

مثل excel or breed sheet or email or phone calls، اما به جای این همه اضافه کاری روش های ساده تری برای ثبت درخواست وجود دارد.

مزایای BPMS:

1. یک: Workload Reduction: که امکان straight-through processing فرض کنید یک فرض کنید یک سازمان بزرگ دارید و افراد زیادی در آن سازمان مشغول به کار هستند و یکسری اسناد هست که بین کارمندان مختلف در چرخش هست که با استفاده از BPMS این چرخه بلا استفاده جمع میشود.

a. الف: Less Coordination: یعنی نیازی نیست شما مستقیما به شخصی نیاز داشته باشید مثل منشی که مثلا این پرونده ببر طبقه اول اتاق 2 و این پرونده ببر پیش ریاست، تمام این مشکلات با BPMS حل میشود.

b. ب: Less gathering of relevant information: یعنی اگر یک document به میز اتاق شما رسید و شما ملزم به مطالعه آن سند و جمع آوری اطلاعات و تصمیم درمورد یک موضوعی باشید، این کار به صورت خودکار با BPMS انجام میشود

2. دو: Flexible System Integration:

a. Generic functionality of process layer

b. Easier to change process logic

c. Island automation

مفهوم Message Queue (Kafka & RabbitMQ):

در واقع Queue به صفی از چیز های مختلف گفته میشود که منتظر handle شدن توسط سیستم هستند، از ابتدای صف شروع شده و به صورت یک توالی منظم پشت سر هم قرار دارند دقیقا مثل صف ماشین ها در جایگاه سوخت که پشت سر هم حرکت میکنند:

مفهوم Message Queue را Message Broker نیز مینامند که Queue از پیام ها هست که بین دو بخش سیستم قرار گرفته اند برای برقراری ارتباط بین آن ها. در واقع Message ها یک نوع data transporter هستند بین فرستنده و گیرنده. مثلا یک بخش از سیستم دستور انجام یک task را به بخش دیگر سیستم ارسال میکند یا حتی پیام ها به صورت log ذخیره شده یا پیام شامل task هایی است که کامل شده اند.

پس ساختار به این شکل است که Producers پیام را تولید کرده و تحویل Message Queue میدهند و consumer های ما به Message Queue متصل شده و پیام را دریافت میکند و پیامی مبنی بر دریافت یا عدم دریافت به Message Queue میدهد.

مفهوم Message Queue ها asynchronous communication protocol را فراهم میکنند به این معنی که یک سیستم یک پیام در Message Queue قرار میدهد و نیازی به پاسخ سریع و بلادرنگ ندارد و به تعویق می افتد.

واضح ترین مثال ایمیل هست، وقتی شما ایمیلی برای کسی میفرستید، شروع به ادامه سایر کار های خود میکنید و نیازی به پاسخ در همان لحظه ندارید، این روش handle کردن پیام ها Decouple میکند Producer از consumer.

یک مثال دیگر فرض کنید یک application سفارش Fast Food دارید و سفارش شما را آماده کرده ولی باید همزمان پاسخ گوی سایر سفارشات باشد یعنی web-service باید دارای availability بالایی داشته باشد. پس درصورتی که تعداد درخواست ها بالا رود در Message Queue ذخیره شده و consumer پیام را دریافت کرده و در زمان مناسب پاسخ میدهد.


مفهوم Docker-And-Containers:

مفهوم Docker یک پلتفرم Opern-Source هست که کمک میکند application ها و وابستگی های بین Module ها و Component های آن را package کرده و داخل Container Docker قرار دهیم برای توسعه و deploy کردن نرم افزار مورد نظر.

ما به کمک Docker میتوانیم framework های مناسب برای app های مختلف در نظر بگیریم:

در واقع Docker حاصل ترکیب زیرساخت(Infrastructure) و Development میباشد.

این Containerization شامل تمام وابستگی ها هست مانند framework ها و library ها. به کمک Docker Containers اپ های ما میتوانند به راحتی و به صورت efficiently روی محیط های مختلف کامپیوتری کار کنند به دلیل خاصیت Lightweight بودن. Container ها فضای کمی را روی حافظه ما اشغال میکند. Container ها application ها را به صورت مجزا اجرا میکنند و هسته سیستم عامل را با Container ها به اشتراک میگذارد. Containerها یکسری policy برای application ها دارند که باعث secure ماندن آن ها میشود. Container ها بسیار portable هستند و در اکوسیستم Docker قایل اجرا هستند و تعدادی نرم افزار میتوانند Encapsulate شوند داخل یک Container و به راحتی میتوانند در platform های مختلف deploy شوند. وقتی که یک Container ساخته میشود میتواند روی هر سیستم دیگری که روی آن Docker نصب شده است run شود دقیقا مشابه سیستم قبلی بدون هیچ تغییری. Container ها میزان زمان boot را به حداقل میرسانند که این مزیت باعث کم شدن مدت زمان deployment میشود.

در آخر به یکسر مزایای خاص Docker Container ها اشاره میکنیم:

· یک: No External Dependency: Container هیچ وابستگی برای run کردن application ندارد، و

مفهوم Container فقط در host و run کردن application دخالت میکند.

· دو: Easily Shipped: فقط کافی است Docker روی سیستمی نصب باشد و Container بدون توجه به سیستم عامل و یا محیط توسعه اجرا میشود و با توجه به کم مصرف کردن میزان حافظه سرعت بالایی دارد.

· سه: Volumes: یک روش share کردن data هست که از امنیت خوبی برخوردار هست در میان Container های مختلف

· چهار: Isolation: در Container ها host operating system ها امکان isolation فراهم میکنند تا وابستگی ها از بین بروند به عنوان مثال micro-service ها به راحتی میتوانند با این روش کار کنند بدون هیچگونه وابستگی.

در این شکل میتوانیم Container های مختلف Docker را ببینیم:

یک Container میتواند Apache Tomcat را به صورت package به همراه وابستگی های آن به زبان برنامه نویسی Java را در یک فایل قرار دهد.

مفهوم Container-Orchestration:

فرض کنید 3 تا Micro-service دارید که به صورت جداگانه Containerize شده اند فرض کنید این 3 سرویس Front-End و Back-End و Data-Base میباشند. تمرکز توسعه دهنده ما روی End-User هست که به Front-End دسترسی دارد و خود Front-End وابسته به Back-End میباشد و خود Back-End وابسته به Data-Base پس تمام تمرکز developer ما به صورت کلی روی همین لایه هست:

در زیر این لایه، لایه Orchestration قرار دارد ما میتوانیم اسم این لایه را Master قرار دهیم مشابه Kubernetes که در آن یکسری Master Node وجود دارد که application های متنوع را روی منابع سیستم شما مدیریت میکند.

در شکل بالا همه Micro-Service هایی که به صورت Containerize رسم شد با دید کلی توسعه دهنده میتوان به این صورت در نظر گرفت:

پس اولین قدم در Orchestration، deploy کردن application میباشد. قدم دوم Scaling میباشد:

پلتفرم Orchestration میاد و schedule میکنه Micro-Service ها و Container ها را تا مطمئن شود از منابع به بهترین نحو ممکن استفاده میشود. قدم سوم Networking هست یعنی چگونگی برقراری ارتباط بین افراد و سرویس های مختلف که مستلزم ساخت سرویس ها هست که هر کدام از Container ها را معرفی کند. خب الان handle کردن ارتباط بین همه Front-End با هم و همه Back-End ها با هم و همه Data-Base ها با هم که این وظیفهplatform Orchestration هست تا End-User بتواند به راحتی به بخش های مختلفی مثل Front-End و Back-End و Data-Base دسترسی پیدا کند.

قدم چهارم Insight هست که به بخش درونی توجه میکندplatform Orchestration، یعنی اگر در یکی از Micro-Service ها یکی از Front-End ها به مشکل خورد و حذف شد به سرعت در Micro-Service دیگر یک Front-Endرا وارد چرخه کرده و همه این کار های جایگزینی را به صورت خودکار انجام میدهد.


مفهوم Log Management Tool (ELK):

در cloud تعداد زیادی application وجود دارد که روی platform های مختلف اجرا میشوند:

هر کدام از این application در طول روز میلیون ها log ایجاد میکنند با type های مختلف، و نیاز مبرم به یک ابزار مدیریت log میباشد تا بتوانید مشکلاتی و error هایی که در سیستم ایجاد شده اند را به موقع شناسایی و مشکل مورد نظر به سرعت debugeشود در غیر این صورت شما مجبور میشوید تا ساعت های زیادی را برای analyze کردن میلیون ها خط log و همچنین با log type های گوناگون صرف کنید تا بتوانید error مورد نظر را کشف کنید. یکی از این ابزار ها ELK میباشد.

مفهوم ELK از سه قسمت Elastic search & Logstash & Kibana. Elastic search یک database از نوع No-SQL توزیع شده است که شما میتوانید پیام ها را به فرمت json ذخیره کنید و با استفاده از Elastic میتوانید از سرویس های Restful استفاده کنید. Component بعدی Logstash هست که میتوان یک framework باشد که داده های مختلف را از منابع مختلف جمع آوری میکند و داده ها را به صورت stream در pipeline قرار میدهد و لاگ ها را push میکند داخل Elastic search. و در آخر Kibana که یک component UI میباشد داده ها را به روشی که مدنظر شما میباشد نشان میدهد.

پس اگر شما در مرحله deployment باشید، یک سری ابزار نیاز دارید برای مدیریت لاگ های خود که اولی Elastic search به عنوان یک component نرم افزاری و Logstash که جریان داده های مختلف از سیستم ها یا زیرساخات های مختلف جمع آوری میکند و Kibana به عنوان یک ابزار UI که میتوان برای نمایش دادن report های مختلف به کار گرفته شوند.

این یک محیط شبیه سازی UI به نام Kibanaمیباشد که فقط حاوی یک لاگ است.


مفهوم Monitoring Tools (Prometheus):

مفهوم Prometheus ابزاری است برای monitor کردن محیط های داینامیک container مثل Kubernetes و docker و همچنین میتواند در زیرساخت هایی که به صورت container نیستند نیز استفاده شود ولی به طور کلی این ابزار محبوبیت زیادی در Container Microservices Infrastructure دارد.

مفهوم DevOps مدرن در دنیای امروزی دارای پیچیدگی های زیادی است که نیاز دارد بخشی از آن ها به صورت automation تبدیل شوند. فرض کنید شما چند سرور مجزا دارید و تعدادی Containerize Application را Run میکنند و صدها process روی زیرساخت ها در حال انجام هستند و همه چیز به هم پیوسته هستند، حالا فرض کنید این سرور ها به صورت distributed هستند و شما هیچ اطلاعاتی از سخت افزار یا برنامه نرم افزاری آن ها ندارید به عنوان مثال مشکلاتی شامل: Response Latency, Overloaded, Errors, Enough resource یا حتی down شدن یکی از سرور ها، در چنین زیرساخت پیچیده ای احتمال خطا زیاد میشود. وقتی شما صدها application دارید که deploy شده اند هر کدام که crash or failure کند باعث خلل در سایر سرویس ها میشود و شما نیاز داری که سریعا مشکل را شناسایی کنید.

فرض کنید شما برای ورود به سامانه گلستان دچار مشکل شده اید و پیغام خطا در رمز عبور یا user-id را نمایش میدهد، شما باید بتوانید مشکلات را بررسی کرده به صورت step by step و تعیین کنید که آیا مشکل از back-end است یا یکی از سرور ها یک exception را نمایش داده است یا مشکل از سرویس شناسایی و ذخیره رمز عبور است یا اصلا مشکل از یکی از سرور ها به دلیل پر شدن حافظه داخلی آن است! شما به کمک این ابزار به راحتی و در زمان مناسب متوجه میشوید که یکی از سرور ها به دلیل کمبود فضای حافظه به زودی crash میکند و سیستم login گلستان به مشکل خواهد خورد.

پس شما به کمک این ابزار میتوانید کل سیستم و زیرساخت ها و سرویس ها را مانیتور کنید و alert و هشدار امکان وقوع failure or crash دریافت کنید و به موقع مشکل را شناسایی و برطرف کنید.


مفهوم Static Code Analysis:

یک method برای debugging کردن کد ها بدون execute میباشد. اگر توسعه دهنده ای اقدام به تولید کدی با کیفیت و تمیز کند، نیاز به debugging آن کد دارد. در واقع Static Code Analysis زمانی اجرا میشود که توسعه دهنده در حال تکمیل کد مربوطه است یعنی دقیقا قبل از اتمام و تست آن، میتوان به عنوان تست source code در نظر گرفت و قبل از تست نرم افزار اصلی صورت میگیرد. از مزیت های این تست:

· کمک به شناسایی مشکلات موجود در کیفیت توسعه نرم افزار، هر نرم افزاری یک تعداد fault و bug دارد و اگر شما این مشکلات را زود handle نکنید وقتی کد پیچیده تر میشود یا محصول را به دست مشتری بدهید bug های آن مشخص خواهند شد، پس Analysis کردن کد بسیار مهم است.

· همچنین به کمک Static Code Analysis میتوانیم کد هایی را که نیاز مبرم به ساده سازی دارند را شناسایی کرده و تغییرات مورد نظر را اعمال کنیم

· یکی دیگر از مزایای Static Code Analysis کشف error های موجود در کد است.

· ایجاد یک ارتباط خوب و قوی بین تیم های مختلف که در حال توسعه نرم افزار هستند به منظور برقراری ارتباط و رفع مشکلات یکدیگر و بالا بردن کیفیت کد.

یکی از این ابزار ها PVS Studio میباشد که در زبان های C, C++, C#, Java نوشته شده است، پس شما میتوانید به راحتی با استفاده از این ابزار زبان های ذکر شده را به صورت Static ، آنالیز و تست کنید و به راحتی در سیستم عامل های Widows, Linux, Mac Os اجرا میشود.

این ابزار Static Code Analysis را انجام میدهد و error ها و bug های موجود را به صورت log به شما report میدهد. ابزار های دیگری نیز جهت Static Code Analysis در جهان وجود دارد مثل intellij idea یا SonarQube و SonarJava..


مفهوم Continuous Delivery:

بحث اصلی در مورد این است که چطور کد را به سمت production ببریم. اگر ما تغییرات مهمی را در کد منبع خود ایجاد کنیم چطور آن را باید به production خود منتقل کنیم؟

در ابتدای کار ما باید طی فرایند build کد خود را به نرم افزار تبدیل کنیم، یعنی کد را run کرده و فایل exe را استخراج کنیم. خب الان ممکن است فکر کنید حالا که نرم افزار را داریم میتوانیم به راحتی میتوان نرم افزار را deploy کرد روی production، در حالی که این تفکر کاملا اشتباه است. شرکت های بزرگ به هیچ وجه این عمل را مستقیم انجام نمیدهند و با قرار دادن نرم افزار در محیط های تست آن را تست کرده و مشکلات fault, error های آن را پیدا کرده و برطرف میکنند به عنوان مثال محیط های تستی همچون QA, performance, stage. پس وقتی شما به pipeline یک ابزار Continuous Delivery نگاه میکنید با این مفاهیم روبه رو میشوید که محیط های تست نامبرده شده میتوانند به صورت خودکار deploy شوند و در محیط QA و stage میتوان Automating testing قرار داد.

و قسمت build را میتوانیم از ابزار های مختلفی استفاده کنیم که به آن CI یا همان continuous delivery گفته میشود و همچنین بین سطح stage و production که level دیگری از governance وجود دارد.


مفهوم SSO:

از نظر کاربر هر دو مفهوم Single Sign on و Federated Identity Management یکسان هستند و یک از کاربرد های آن ها وقتی که کاربر به اکانت google خود وارد میشود میتواند در YouTube و سایر شبکه های اجتماعی login کند بدون نیاز به وارد کردن رمز. SSO یک authentication است، و کمک میکند تا کاربر بتواند به صورت امن به application ها و سرویس- های مختلف دسترسی داشته باشد به کمک فقط یک id. به عنوان مثال شما میتوانید وارد Gmail و YouTube و slack و آمازون و غیره. یک صفحه مشابه این شکل نمایش میدهد:

و شما به کمک SSO میتوانید در هر بار مراجعه به این سایت بدون نیاز به وارد کردن رمز عبور به راحتی login کنید. در واقع به کمک service provider در Gmail این اطلاعات از Protocol های امن به application یا سایت مورد نظر منتقل میشود. دو Protocol مرسوم برای پروسه authentication وجود دارد:

1. یک: SAML (Security Assertion Markup Language): در واقع یک فایل XML میباشد و مسئولیت ایجاد تغییر اطلاعات هویتی بین سرویس ها میباشد.

1. پروتکل دوم OpenID connect میباشد:

مشابه همین صفحه ورود گوگل:

یکی از استفاده های این پروتکل منجر به ورود به YouTube میشود که از JWT یا همان JSON Web Tokenاستفاده میکند تا بتواند اطلاعات هویتی فرد را بین سرویس های مختلف به اشتراک بگذارد.

مثال: کاربری برای ورود به حساب twitter خود از Gmail که یک Service Provider میباشد اقدام میکند. سرور Gmail دامین کاربر را تشخیص میدهد وrequest SAML Authentication را به مرورگر کاربر برمیگرداند:

مرورگر SAR و اطلاعات کاربر را منتقل میکند به Identity Provider مانند Okta & Authu0 & oneLogin. Identity Provider بلافاصله Login Page را به کاربر نشان میدهد:

و کاربر پس از وارد کردن اطلاعات خود و ارسال به Identity Provider مجدد پیامی برمیگردد با عنوان Signed SAML assertion که یک امضای رمزنگاری شده در مستندات XML میباشد که شامل اطلاعات کاربر و میزان دسترسی کاربر به Service Provider میباشد. این اطلاعات در قالب فایل XML از مرورگر کاربر به Service Provider ارسال میشود و Service Provider آن را Validate کرده که توسط کلید عمومی این کار را انجام میدهد:

سپس Service Provider میاد و protected resource را به مرورگر کاربر برمیگرداند متناسب با میزان دسترسی کاربر:


مفهوم Federated Identity Management (FIM):

در Service Provider، SAML request را همچنان ارسال میکند مشابه SSO ولی این بار request به جای ارسال به Identity Provider، به مرکز Federation application ارسال میشود. Federation application دو مورد را چک میکند: 1. آیا Identity Provider شما بخشی از Federation میباشد؟ 2. مورد دوم آیا شما اجازه دسترسی به سرویس ها را دارید یا خیر.

مفهوم Service Mesh:

یک مفهومی است مربوط به Micro-Service ها میباشد. فرض کنید یک application یکپارچه monolithic دارید و تمام feature های application را شامل میشود و وقتی این application monolithic را به Micro-Service تبدیل کنیم مزایای زیادی برای ما دارد.

یکی از مزایای آن وجود component های کوچک و مستقل است که به راحتی قابل deploy هستند و سایر بخش های سیستم تحت تاثیر تغییرات صورت گرفته قرار نمیگیرند یا حتی اگر component دچار مشکل شود و down یا crash کند سایر بخش های سیستم به مشکل نخواهند خورد در نتیجه flexibility برنامه حفظ میشود. به دلیل استقلال component ها در Micro-Service ها به راحتی میتوان data-base یا framework یا حتی زبان برنامه نویسی را تغییر داد.

فرض کنید یک Micro-Service داریم که با دو ورژن از catalog صحبت میکند و دو ورژن از catalog هم با inventory صحبت میکنند. چهار علت اصلی در استفاده از Service Mesh مطرح میشود که اولی secure یا همان امنیت است پس نیاز به یک Mutual TLS میباشد وقتی یک سرویس با سرویس دیگر صحبت میکند.

در مرحله بعدی ارتباط بین سوریس ها به صورت داینامیک پیکربندی میشوند یعنی این که چطور 2 سرویس به یکدیگر connect میشوند، فرض کنید 90% ترافیک به catalog-v1 و 10% ترافیک را به catalog-v2 مادامی که در حال انجام تست هستم ارسال میکنم. سومین دلیل Observe کردن کارکرد application به صورت end-to-end میباشد یعنی بررسی سرویس های مختلف و این که ترافیک و flow داده ها از کدام سرویس ها بیشتر عبور میکنند. دلیل چهارم باید بررسی شود که کدام سرویس اجازه دسترسی و صحبت کردن با سرویس دیگر را دارد، در این مثال سرویس UIاجازه صحبت مستقیم با Inventory را نداشته در نتیجه مجبور میشود از سرویس catalog با دو ورژن متفاوت استفاده کند و مطابق شرایط ترافیک های مختلفی را به هریک اختصاص دهد یا حتی میتوانیم به نکات بیشتری توجه کنیم به عنوان مثال سرویس UI اجازه دسترسی به catalog از طریق پروتکل HTTP get Request و catalog از طریق post Request با Inventory ارتباط برقرار کند. در زمان قدیم توسعه دهنده های اصلی ما هر 4 مورد ذکر شده را برنامه نویسی کرده و مستقیما در در کد های application قرار میدادند که باعث بزرگ شدن بیش از حد Micro-service UI میشد و به صورت کلی انعطاف پذیری برنامه کم میشد. ولی با روش جدید Service Mesh، application را کوچک نگه میداریم به صورت business focus عمل میکنیم.

مفهوم BRMS:

فرض کنید به عنوان یک Analysis در یک شرکت کار میکنید و نیاز دارید تا یکسری تغییراتی در یکسری ابزار در نرم افزار ایجاد کنید، در جواب باید مواردی بیان شود از جمله هر شرکت یا سازمانی یک سری Business rule برای application های خود دارد که به یک زیان واحد نوشته شده اند مثل جاوا، مثلا در شکل زیر دایره ها نشان دهنده business rule یا business logic و مثلث ها قوانین applicationمیباشد:

مفهوم Rule Management System هایی مانند BRMS به ما کمک میکنند که قوانین و logic بیزینس خود را از کد های application جدا کنید و به ما اجازه میدهد که قوانین جدید خود را در فرمت های مختلف تبیین کنیم که در شکل پایین نمایش داده شده است. حالا با جدا کردن business rule از کد های application، این برنامه ما چه طور با قوانین مربوط به businessتعامل خواهد داشت؟ در جواب این سوال راه های متفاوتی را میتوان اتخاذ کرد. در یکی از این راه ها باید قوانین را در application قرار داد و یک rule engine برای اداره آن در فایل jarایجاد کرد در این راستا به راحتی میتوان از یک KIE server استفاده کرد که تمام قوانین business ruleرا در خود جای میدهد.

نحوه برقراری ارتباط بین application و KIE server، برقراری ارتباط از طریق Java API و یا از REST API که توسط خود KIE server فراهم شده است. پس وقتی Analysisیا توسعه دهنده ما یک سری تغییرات را در Business central(شکل اول) ایجاد میکند، تغییرات اعمال شده به KIE serverمنتقل شده و از طریق Java API و یا از REST API به application اعمال میشوند.

مفهوم Low code platform:

در سال های پیش کمپانی های بزرگی همچون اوراکل یک سری application های پیچیده را تولید کردند تا بتوانند به راحتی business problems ها را شناسایی و حل کنند و این application همه مواردی از جمله فروش و حسابداری را handle میکنند و این application یکسری فرایند های بسیار پیچیده دارند که مشکلاتی مختلفی از جمله وجود یکسری gap در endless spreadsheet و وقتی این که حجم این sheet ها زیاد میشود توانایی modify کردن و ایجاد تغییرات به مشکل برخورده و برنامه هنگام اجرا خطا میدهد ولی مزایای این spreadsheet قابلیت فهم آسان آن ها است با توجه به مزایا و معایب ذکر شده بین spreadsheet و اپ های بزرگ و حجیم یک gap وجود دارد به نام low code. در واقع flexible و قابل درک آسان برای فهم افرادی که در حوزه businessتخصص دارند. که قابل translate شدن به scalable application ها میباشد تا توسعه دهنده و برنامه نویسان به راحتی میتوانند آن را modify کرده و برنامه را توسعه دهند.

فرض کنید یک سازمان قصد استخدام تعدادی کارمند را دارد و باید پروسه مصاحبه و تکمیل فرم و addکردن اطلاعات شخصی که در مصاحبه قبول شده به سیستم شرکت ما که قطعا پروسه زمان بری خواهد بود و کار اضافی برای کارمندان ما ایجاد خواهد کرد که ما به کمک low code platform میتوانیم همه این کار ها را automate کنیم و به این طریق بیزینس ما نیز کمتر آسیب میبیند. مثلا در دانشگاه شهید بهشتی بعد از قبولی شما باید یک شناسه id شهید بهشتی درست کنید و ایمیل دانشگاهی و رمز عبور دریافت کنید برای بهرهمندی از خدمات کتاب خانه، اینترنت دانشگاه و خوابگاه، سایت نظر سنجی بهشتی، و سایت مقالات که همه ی این کار ها را خود دانشجو باید انجام دهد در صورتی که با قرار دادن یک low code platform این فرایند به صورت خودکار صورت گرفته و مشکل حل میشود.


مفهوم ESB:

در معماری سرویس گرا یا SOA، سیستم ها قادر به برقراری ارتباط و تبادل داده ها با یکدیگر از طریق یک فایل XML هستند.

ولی پیچیدگی در integrate کردن سیستم ها زیاد میباشد. وقتی شما سه سیستم در معماری خود داشته باشید شما نیاز به یک interface برای هر کدام از سیستم ها دارید برای اتصال به آن ها و این جمله به این معنی است که یک interface کلی نداریم. اما راه حل جامع آن Enterprise Service Bus یا همان ESB میباشد. یعنی ESB میشود آن interface جامع ما و هر کدام از سیستم ها در سازمان ما به ESB متصل شده و هر سیستم کافی است که فقط با ESB ارتباط برقرار کند که شامل یک سری auto system میباشد. پس هر سیستم ما نیاز دارد interface خود را به ESB متصل کند:

مفهوم ESBبه سیستم ها کمک میکند تا عمل routing message را هدایت کند. وقتی پیام ها از interface سیستم ها به ESB ارسال میشود، ESB قبل از فرستادن پیام اطمینان حاصل میکند که سیستم مقصد آیا alive(زنده) هست و میتواند پیام را دریافت کند یا خیر؟ سیستم ها مسئولیتی در قبال delivery پیام ها ندارند و هر سیستم میتواند روی توسعه سرویس های خود تمرکز کند، پس ESB مسئولیت رسیدن پیام ها را به سیستم مقصد به عهده میگیرد و سیستم ما بعد ارسال پیام روی توسعه سرویس های خودش کار میکند به جای پیگیری ارسال موفقیت آمیز پیام به مقصد که باعث better performance برای سرویس ها میشود.

وقتی سرور Aبرای سرور Bیک پیامی را میفرستد که همه ی اطلاعات درخواستی سرور B را شامل نمیشود ESB کمک به insert کردن data به پیام مورد نظر میکند.

مفهوم ESB همچنین امنیت را برقرار میکند با قرار دادن firewall، قبل از ارسال فایل XML هر کدام از سیستم ها مرحله authenticate را پشت سر گذاشته و احراز هویت میشوند. وقتی سیستم Aبه سیستم Bفایل XMLخود را ارسال میکند ESBمیتواند یک login functionاضافه کند و پیام را به سیستم دیگری ارسال کند.

منابع: ویکی پدیا و سایت های تخصصی در برنامه نویسی

ممنون از وقتی که گذاشتید.