<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
    <channel>
        <title>نوشته های danny</title>
        <link>https://virgool.io/feed/@dany_kh</link>
        <description></description>
        <language>fa</language>
        <pubDate>2026-04-15 04:41:17</pubDate>
        <image>
            <url>https://files.virgool.io/upload/users/7080/avatar/OrkBqM.png?height=120&amp;width=120</url>
            <title>danny</title>
            <link>https://virgool.io/@dany_kh</link>
        </image>

                    <item>
                <title>معرفی کتاب معماری‌های میکروسرویس</title>
                <link>https://virgool.io/@dany_kh/%D9%85%D8%B9%D8%B1%D9%81%DB%8C-%DA%A9%D8%AA%D8%A7%D8%A8-%D9%85%D8%B9%D9%85%D8%A7%D8%B1%DB%8C-%D9%87%D8%A7%DB%8C-%D9%85%DB%8C%DA%A9%D8%B1%D9%88%D8%B3%D8%B1%D9%88%DB%8C%D8%B3-okre9y8sxwqn</link>
                <description>بارها شده یه پروژه یا معماری خاص نرم‌افزاری رو باید طراحی کنی ولی سوالی که میاد تو ذهنت اینه که مهندس‌های نرم‌افزار توی شرکت‌های برتر تولید کننده نرم‌افزار مثل گوگل چه معماری و طرحی رو برای پروژه‌هاشون انتخاب می‌کنند؟ اینجا نقطه‌ای هست که ایده‌ای نداری و با ترس و ناآگاهی شروع به طراحی معماری یک نرم‌افزار می‌کنی جایی که بارها خودت رو تکرار یا سعی و خطا می‌کنی، ساعت‌ها با هوش‌مصنوعی درگیر میشی و زمان و بودجه رو از بین میبری تا شاید بتونی یک برنامه با قابلیت پایداری و نگهداری بالا و مقیاس‌پذیر بسازی.اما اگر میخوای یک کار بی‌نقص یا اثر هنری از خودت خلق کنی، چیزی که چهار اصل معماری نرم‌افزاری مثل: Scalability Reliability High Performance Maintainability رو داشته باشه؛ باید الگوهای و ضد الگوهای مختلفی رو بشناسی؛ اینجاست که این کتابِ «الگوهای طراحی ابری و معماری‌های مایکروسرویس» به کمکت میاد. این کتاب برای همه علاقه‌مندان به حوزه نرم‌افزار و DevOps و مهندسی داده حتی طراحی سیستم‌های edge و iot پیشنهاد می‌شود.برای دانلود کتاب به لینک زیر مراجعه کنید:دانلودبرای دسترسی به کدهای به این گیت‌هاب رجوع کنید.این کتاب شامل مفاهیم زیر است.</description>
                <category>danny</category>
                <author>danny</author>
                <pubDate>Wed, 11 Feb 2026 18:47:58 +0330</pubDate>
            </item>
                    <item>
                <title>اصول SOLID یک بار برای همیشه</title>
                <link>https://virgool.io/@dany_kh/%D8%A7%D8%B5%D9%88%D9%84-solid-%DB%8C%DA%A9-%D8%A8%D8%A7%D8%B1-%D8%A8%D8%B1%D8%A7%DB%8C-%D9%87%D9%85%DB%8C%D8%B4%D9%87-mmdby9zra9mu</link>
                <description>در دنیای پرشتاب توسعه نرم‌افزار، نوشتن کدِ عالی، قابل نگهداری و مقیاس‌پذیر بسیار مهم است. یک راه برای دستیابی به این هدف، پیروی از مجموعه‌ای از اصول طراحی بنیادی به نام اصول SOLID است. این اصول یک چارچوب واضح برای ساخت نرم‌افزارهایی ارائه می‌دهند که درک، توسعه و نگهداری آنها آسان است. در این متن، ما اصول SOLID را بررسی خواهیم کرد و به طور دقیق به تک‌تک اجزای آن خواهیم پرداخت. ما راهنماهای عملی پیاده‌سازی و بهترین روش‌ها برای اعمال آنها را مرور خواهیم کرد. حال بیایید کاوش خود را با یک مرور کلی مختصر از اصول SOLID آغاز کنیم.مقدمه:اصول SOLID مجموعه‌ای از پنج اصل طراحی اساسی هستند که توسط «رابرت سی مارتین» برای راهنمایی توسعه‌دهندگان نرم‌افزار در ایجاد سیستم‌های نرم‌افزاری قابل نگهداری، مقیاس‌پذیر و انعطاف‌پذیر معرفی شده‌اند. این اصول، زمانی که رعایت شوند، به توسعه نرم‌افزاری کمک می‌کنند که درک، اصلاح و توسعه آن در طول زمان آسان‌تر باشد.حروف اختصاری SOLID مخفف موارد زیر است: اصل مسئولیت واحد Single Responsibility Principle (SRP)اصل باز و بسته Open/Closed Principle (OCP)اصل جانشینی Liskov یا Liskov Substitution Principle (LSP)اصل جداسازی رابط‌ها Interface Segregation Principle (ISP) اصل وارونگی وابستگی Dependency Inversion Principle (DIP)اهمیت اصول طراحی در توسعه نرم‌افزاراصول طراحی، مانند اصول،SOLID به دلیل متعددی نقش محوری در فرایند توسعه نرم‌افزار ایفا می‌کنند.قابلیت نگهداری: رعایت اصول طراحی اصولی باعث می‌شود کد قابل نگهداری‌تر شود. هنگامی که کد به خوبی ساختاریافته باشد و به این اصول پایبند باشد، شناسایی و رفع مشکلات، اضافه‌کردن ویژگی‌های جدید و انجام بهبودها بدون ایجاد عواقب ناخواسته آسان‌تر می‌شود.قابلیت مقیاس‌پذیری: نرم‌افزارهای طراحی شده به‌خوبی مقیاس‌پذیر هستند. آنها می‌توانند بدون نیاز به بازنگری گسترده یا پیچیده‌شدن تدریجی کد برنامه، تغییرات و رشد در نیازمندی‌های جدید را پذیرا باشند. قابلیت استفاده مجدد از کد: رعایت اصول طراحی اغلب منجر به کدی می‌شود که قابلیت استفاده مجدد بیشتری دارد. اجزای قابل‌استفاده مجدد باعث صرفه‌جویی در زمان و تلاش مؤثرتر در توسعه و تست می‌شوند.همکاری: اصول طراحی یک چارچوب مشترک برای توسعه‌دهندگان برای کار در آن ارائه می‌دهد. این درک مشترک باعث همکاری و کاهش سوءتفاهم بین اعضای تیم می‌شود. کاهش باگ‌ها و مشکلات: رعایت اصول طراحی به شناسایی و کاهش مشکلات رایج برنامه‌نویسی و دام‌های طراحی کمک می‌کند. این منجر به باگ‌های کمتر و نرم‌افزار باثبات‌تر می‌شود.آینده‌نگری: نرم‌افزارهای طراحی شده به‌خوبی می‌توانند با نیازها و فناوری‌های در حال تغییر سازگار شوند. این سرمایه‌گذاری برای ماندگاری بلندمدت محصول نرم‌افزار است. حال بیایید به طور عمیق به تک‌تک اجزای اصول SOLID بپردازیم.اصل مسئولیت واحد (SRP)حرف &quot;S&quot; در اصول SOLID مخفف Single Responsibility Principle (SRP) است که بیان می‌کند یک کلاس باید فقط یک دلیل برای تغییر داشته باشد، یا به‌عبارت‌دیگر، باید یک مسئولیت یا کار مشخص و خوبی تعریف شده در یک سیستم نرم‌افزاری داشته باشد.بیایید نگاهی به یک نمونه کد جاوا در زیر بیندازیم که به طور واضح اصل SRP را نقض می‌کند:SRP - badدر مثال بالا، کلاس کارمند (Employee) دو مسئولیت دارد: محاسبه حقوق کارمند و ایجاد گزارش حقوق و دستمزد. این کار اصل مسئولیت واحد (SRP) را نقض می‌کند؛ زیرا دلیل بیشتری برای تغییر دارد.رفع نقض اصل SRPبرای رفع نقض SRP در مثال قبلی، بیایید کد را برای تفکیک دغدغه‌ها بازنگری کنیم و اطمینان حاصل کنیم که هر کلاس یک مسئولیت واحد و به‌خوبی تعریف شده دارد. ما کلاس‌های متمایزی برای محاسبه حقوق کارمند و ایجاد گزارش حقوق و دستمزد ایجاد خواهیم کرد.SRP - good
در راه‌حل بازنگری شده، مسئولیت‌های محاسبه حقوق و ایجاد گزارش حقوق و دستمزد تقسیم شده است که هر PayrollReportGenerator و Employee به دو کلاس مجزا کدام یک مسئولیت واحد دارند. این با اصل SRP مطابقت دارد. بیایید نگاهی به نمایش کلاس‌ها و پیاده‌سازی SRP بیندازیم. SRP - compare خطاها و اشتباه‌های رایجاستفاده از SRP با خطاها و اشتباهات رایجی همراه است که باید آنها را بشناسیم. درک این چالش‌ها به ما امکان می‌دهد تا بهتر از آنها اجتناب کنیم و کد بهتر و قابل نگهداری بیشتری ایجاد کنیم. بیایید برخی از این مشکلات بالقوه را بررسی کنیم.همان‌طور که در مثال اولیه نشان داده شد، سربارگذاری (overloading) بیش از حد کلاس‌ها با مسئولیت‌های متعدد یک اشتباه رایج است. این می‌تواند منجر به کد پیچیده و نگهداری سخت شود.نادیده‌گرفتن اصل انسجام (Cohesion) که به SRP مرتبط است، می‌تواند منجر به کلاس‌هایی شود که وظایف نامرتبطی را انجام می‌دهند و باعث شود کد سازماندهی کمتری داشته باشد و مدیریت آن دشوارتر شود.بهترین راه‌حل‌ها:برای رعایت مؤثر،SRP نکات زیر را در نظر بگیرید: مسئولیت‌ها یا نقش‌هایی را که هر کلاس باید داشته باشد به طور واضح تعریف کنید. از مخلوط‌کردن وظایف نامرتبط در یک کلاس واحد خودداری کنید. از اصل جداسازی نگرانی‌ها (SoC(Separation of Concerns برای تقسیم عملکرد برنامهٔ خود به ماژول‌ها یا کلاس‌های مجزا استفاده کنید که هر کدام مسئول یک دغدغه خاص هستند.اگر کلاسی با چندین مسئولیت پیدا کردید، آن را به کلاس های کوچک‌تر و متمرکزتر با یک مسئولیت واحد برای هر کدام، بازنگری کنید. کلاس‌های خود را به‌گونه‌ای طراحی کنید که تغییرات در یک مسئولیت بر پیاده‌سازی سایر مسئولیت‌ها تأثیری نداشته باشد. برای اطمینان از رعایت SRP توسط کلاس‌ها، بررسی کد انجام دهید. اعضای تیم را تشویق کنید تا در مورد مسئولیت‌های کلاسهای بازخورد ارائه دهند.اصل باز/بسته (OCP)اصل باز/بسته (Open/Closed Principle)OCP بیان می‌کند که موجودیت‌های نرم‌افزار (مانند کلاس‌ها، ماژول‌ها و توابع) باید برای توسعه باز باشند؛ اما برای تغییر بسته باشند. به‌عبارت‌دیگر، شما باید بتوانید بدون تغییر کد منبع موجود، قابلیت یا رفتار جدیدی را به یک موجودیت نرم‌افزار اضافه کنید. برای درک بهتر اصل باز/بسته (OCP) بیایید نگاهی به یک نمونه کد جاوا بیندازیم که به طور واضح این اصل را نقض می‌کند. OCP -badدر مثال بالا، کلاس مستطیل (Rectangle) برای محاسبه مساحت یک مستطیل طراحی شده است. بااین‌حال، اگر می‌خواهید آن را برای کار با اشکال دیگر مانند دایره یا مثلث گسترش دهید، باید کلاس را اصلاح کنید که این کار اصل باز/بسته (OCP) را نقض می‌کند.رفع نقض اصل باز/بسته (OCP)ما اصل باز/بسته (OCP) را اعمال خواهیم کرد و خواهیم دید که چگونه می‌توانیم مشکل ذکر شده در بالا را حل کنیم. OCP -good
در این راه‌حل بازنگری شده، کلاس Shape به‌عنوان یک کلاس پایه انتزاعی برای همه اشکال معرفی شده است. هر شکل (Shape ) خاص (Rectangle, Circle) کلاس Shape را گسترش می‌دهد و پیاده‌سازی خاص خود از متد calculateArea را ارائه می‌دهد. این با اصل باز/بسته (OCP) مطابقت دارد؛ زیرا شما می‌توانید بدون تغییر کد موجود، اشکال جدید اضافه کنید. در زیر نمایش بصری کلاس ها و پیاده‌سازی اصل باز/بسته (OCP) آمده است.OCP-goodخطاها و اشتباهات رایجبیایید برخی از خطاها و اشتباهات رایجی را که توسعه‌دهندگان ممکن است با آنها مواجه شوند بررسی کنیم: یک اشتباه رایج، تغییر مستقیم کد موجود برای اضافه‌کردن عملکرد یا functionality جدید به‌جای گسترش آن است. این کار اصل باز/بسته (OCP) را نقض می‌کند و می‌تواند باعث ایجاد باگ یا مسیر اشتباه شود.عدم تعریف انتزاع‌های مناسب یا کلاس‌های پایه می‌تواند منجر به کدی شود که بدون تغییر کد آن، گسترش و توسعه آن دشوار است.بهترین راه‌حل‌ها: برای پیاده‌سازی مؤثر اصل باز/بسته (OCP) باید نکات زیر را در نظر بگیرید: برای ایجاد انتزاعی که موجودیت‌های نرم‌افزار می‌توانند برای ارائه قابلیت‌های جدید آنها را گسترش دهند یا پیاده‌سازی کنند از کلاس های انتزاعی (abstract classes) یا رابط‌ها (interfaces) استفاده کنید.هنگام گسترش یک abstract class یا پیاده‌سازی یک، interface برای ارائه رفتار خاص برای هر موجودیت، متدها را override کنید.از چندریختی (Polymorphism) برای رفتار یکنواخت با اشیا کلاس‌های Concrete مختلف (به‌عنوان‌مثال، اشکال مختلف) از طریق کلاس پایه یا رابط مشترک آنها استفاده کنید.از تزریق وابستگی (Dependency Injection) برای تزریق وابستگی‌ها یا رفتارها به کلاس‌ها به‌جای hardcoding کردن آنها استفاده کنید تا گسترش و توسعه عملکرد آسان‌تر شود.اصل جانشینی (LSP) Liskovاصل Liskov Substitution Principle  یا به‌اختصار (LSP) بیان می‌کند که اشیا یک کلاس مشتق شده (subtype) باید بتوانند بدون تأثیر بر عملکرد برنامه، اشیای کلاس پایه (supertype) را جایگزین کنند. به‌عبارت‌دیگر، اگر کلاس A زیرمجموعه‌ای از کلاس B باشد، نمونه‌های کلاس B باید بدون ایجاد مشکل جایگزین نمونه‌های کلاس A شوند.نمونه‌ای از نقض اصل جانشینی Liskovبرای درک بهتر اصل جانشینی Liskov بیایید نگاهی به یک نمونه کد جاوا بیندازیم که به طور واضح این اصل را نقض می‌کند.LSP - badدر این مثال، کلاس شترمرغ (Ostrich) زیرمجموعه‌ای از کلاس پرنده (Bird) است. بااین‌حال، اصل جانشینی  LSP را نقض می‌کند؛ زیرا متد fly را که ارتباطی با شترمرغ ندارد (زیرا شترمرغ نمی‌تواند پرواز کند) را override می‌کند. این بدان معنی است که نمی‌توان یک نمونه از شترمرغ را بدون ایجاد رفتار غیرمنتظره جایگزین نمونه‌ای از پرنده کرد.رفع نقض LSPما اصل LSP را اعمال خواهیم کرد و خواهیم دید که چگونه می‌توانیم مشکل ذکر شده در بالا را حل کنیم:LSP - goodدر این مثال اصلاح شده، کلاس شترمرغ زیرمجموعه‌ای از کلاس پرنده (Bird) است و متد move را برای ارائه رفتاری معنادار که با اصل LSP مطابقت دارد را override می‌کند. یک نمونه از شترمرغ را می‌توان بدون ایجاد مشکل جایگزین نمونه‌ای از کلاس پرنده کرد. در اینجا نمایش بصری کلاس‌ها و پیاده‌سازی اصل LSP آمده است.LSPخطاها و اشتباهات رایجهمان‌طور که اصل LSP را یاد می‌گیریم، آگاهی از خطاها و اشتباهات رایجی که توسعه‌دهندگان ممکن است با آنها مواجه شوند، ضروری است. بیایید برخی از این مشکلات بالقوه را بررسی کنیم.یک اشتباه رایج، override کردن متدها در کلاس های مشتق شده به روشی است که با رفتار کلاس پایه در تضاد باشد. تغییر پیش‌شرط‌ها (نیازمندی‌های ورودی) یا پس‌شرط‌ها (ضمانت‌های خروجی) متدها در کلاس‌های مشتق شده می‌تواند اصل جانشینی Liskov را نقض کند.بهترین راه‌حل‌هابرای پیاده‌سازی مؤثر اصل جانشینی، Liskov نکات زیر را در نظر بگیرید: اطمینان حاصل کنید که کلاس های مشتق شده، سازگاری رفتاری کلاس های پایه خود را حفظ می‌کنند. متدها در کلاس های مشتق شده باید از همان قراردادهای متدهای کلاس پایه پیروی کنند.اگر یک متد کلاس پایه پیش‌شرط‌های خاصی (به‌عنوان‌مثال، محدودیت‌های ورودی) داشته باشد، متدهای کلاس مشتق شده باید پیش‌شرط‌های مشابه یا ضعیف‌تری داشته باشند. پس‌شرط‌ها (ضمانت‌های خروجی) باید به‌اندازه متدهای کلاس پایه یا بهتر از آنها باشد.از چندریختی(polymorphism) برای فعال‌کردن جایگزینی اشیای کلاس مشتق شده با اشیا کلاس پایه استفاده کنید. این اغلب شامل override کردن متدها برای ارائه رفتار مخصوص آنها درعین‌حال حفظ عملکرد اصلی است.اصل جداسازی رابط (ISP)حرف &quot;I&quot; در حروف اختصاری  SOLID مخفف Interface Segregation Principle (ISP) است که بر این نکته تأکید دارد که سرویس کلاینت‌ها کلاس‌ها یا مؤلفه‌هایی که از رابط‌ها (interfaces) استفاده می‌کنند، نباید مجبور شوند به رابط‌هایی که استفاده نمی‌کنند وابسته باشند. به‌عبارت‌دیگر، یک رابط باید مجموعه خاصی و متمرکزی از متدها داشته باشد که به کلاسهای پیاده‌سازی شده مرتبط هستند.نمونه‌ای از نقض اصل جداسازی رابط (ISP)بیایید یک نمونه کد جاوا را بررسی کنیم که به طور واضح این اصل را نقض می‌کند:ISP-badدر این مثال، اینترفیس Worker حاوی سه متد ()eat و () work و ()sleep است. بااین‌حال، ممکن است همه کلاس‌هایی که این اینترفیس‌هایی را پیاده‌سازی می‌کنند به همه این متدها نیاز نداشته باشند. این کار می‌تواند منجر به این شود که کلاس‌ها مجبور به پیاده‌سازی متدهایی شوند که برای عملکرد آنها بی‌ربط هستند و اصل جداسازی رابط (ISP) را نقض می‌کنند.رفع نقض اصل جداسازی رابط (ISP)ما اصل جداسازی رابط (ISP) را اعمال خواهیم کرد و خواهیم دید که چگونه می‌توانیم مشکل ذکر شده در بالا را حل کنیم.ISP-goodدر این راه‌حل بازنگری شده، رابط Worker به سه اینترفیس کوچک‌تر و متمرکزتر تقسیم شده است: قابل‌اجرا (Workable) قابل‌خوردن (Eatable) و قابل خواب (Sleepable) هستند. حال، کلاس‌ها می‌توانند فقط اینترفیس‌هایی را که با عملکرد آنها مرتبط هستند را پیاده‌سازی کنند که مطابق با اصل جداسازی رابط (ISP) است.نمایش بصری اینترفیس‌های بازنگری شده (Sleepable ،Eatable ،Workable) مطابق با اصل جداسازی رابط (ISP) در زیر نشان‌داده‌شده است.خطاها و اشتباهات رایجبیایید برخی از خطاها و اشتباهات رایجی را که توسعه‌دهندگان هنگام اعمال اصل جداسازی رابط (ISP) ممکن است با آنها مواجه شوند، بررسی کنیم: ایجاد رابط‌های بزرگ و یکپارچه با روش‌های زیاد می‌تواند منجر به پیاده‌سازی متدهایی در کلاس‌ها شود که به آنها نیاز ندارند و این امر اصل جداسازی رابط (ISP) را نقض می‌کند. تغییر یک اینترفیس برای اضافه یا حذف متدها می‌تواند پیاده‌سازی‌های موجود را بشکند. هنگام ایجاد تغییرات، توجه به تأثیر آن بر سرویس‌گیرنده‌ها Client مهم است.بهترین راه‌حل‌هابرای رعایت مؤثر اصل جداسازی رابط (ISP) نکات زیر را در نظر بگیرید:  اینترفیس‌ها را با یک هدف خاص طراحی کنید که فقط شامل متدهایی باشد که به طور مستقیم به آن هدف مرتبط هستند.ترجیحاً به‌جای یک اینترفیس بزرگ که همه کاری می‌کند، چندین اینترفیس کوچک‌تر داشته باشید که سرویس کلاینت بتواند پیاده‌سازی آنها را انتخاب کند. از دیدگاه سرویس کلاینت‌ها (کلاس‌هایی که اینترفیس را پیاده‌سازی می‌کنند) فکر کنید و اینترفیس‌هایی را در اختیار آنها قرار دهید که متناسب با نیازهایشان باشد.اگر نیاز به‌اضافه کردن متدهای جدید به یک اینترفیس موجود دارید بدون اینکه پیاده‌سازی‌های فعلی را بِشکنید، استفاده از متدهای پیش‌فرض (default methods) را در نظر بگیرید که پیاده‌سازی‌های پیش‌فرض را برای متدهای جدید ارائه می‌دهند.اصل وارونگی وابستگی (DIP)اصل وارونگی وابستگی Dependency Inversion Principle (DIP) بیان می‌کند که ماژول‌های سطح بالا (یا کلاس‌ها) نباید به ماژول‌های سطح پایین وابسته باشند؛ بلکه هر دو باید به انتزاع رابط‌ها یا کلاسهای انتزاعی (interfaces or abstract classes) وابسته باشند. به عبارت ساده‌تر، این اصل استفاده از رابط‌های انتزاعی را برای جداکردن کامپوننت‌های سطح بالا از جزئیات سطح پایین تشویق می‌کند.نمونه‌ای از نقض اصل وارونگی وابستگی (DIP)برای درک بهتر اصل وارونگی وابستگی (DIP) بیایید نگاهی به یک نمونه کد جاوا بیندازیم که به طور واضح این اصل را نقض می‌کند: DIP - badدر این مثال، کلاس Switch مستقیماً به کلاس LightBulb وابسته است که یک جزئیات سطح پایین است. این نقضی بر اصل وارونگی وابستگی (DIP) است؛ زیرا ماژول‌های سطح بالا مانند Switch نباید به جزئیات سطح پایین وابسته باشند.رفع نقض اصل وارونگی وابستگی (DIP)ما اصل وارونگی وابستگی (DIP) را اعمال خواهیم کرد و خواهیم دید که چگونه می‌توانیم مشکل ذکر شده در بالا را حل کنیم:DIP - goodدر این راه‌حل بازنگری شده، کلاس Switch به رابط Switchable وابسته است که یک انتزاعی است. کلاس LightBulb رابط Switchable را پیاده‌سازی می‌کند. این با اصل وارونگی وابستگی (DIP) مطابقت دارد؛ زیرا ماژول‌های سطح بالا اکنون به انتزاع‌ها (abstractions) به‌جای جزئیات سطح پایین وابسته هستند.نمایش بصری وارونگی وابستگی، نشان می‌دهد که چگونه ماژول‌های سطح بالا (Switch) به انتزاع‌ها (Switchable) به‌جای پیاده‌سازی‌های واقعی (LightBulb) وابسته هستند که در زیر نشان‌داده‌شده است: DIPخطاها و اشتباهات رایجهمان‌طور که اصل وارونگی وابستگی (DIP) را یاد می‌گیریم، بیایید برخی از خطاها و اشتباهات رایجی را که توسعه‌دهندگان ممکن است با آنها مواجه شوند بررسی کنیم: یک اشتباه رایج وابستگی مستقیم ماژول‌های سطح بال به جزئیات سطح پایین است که اصل وارونگی وابستگی (DIP) را نقض می‌کند. ایجاد انتزاع‌های ضعیف یا به طور ضعیف تعریف شده می‌تواند رعایت مؤثر اصل وارونگی وابستگی (DIP) را به چالش بکشد.برای پیاده‌سازی مؤثر اصل وارونگی وابستگی (DIP) نکات زیر را در نظر بگیرید: برای نمایش وابستگی‌ها، رابط‌های انتزاعی یا کلاس های انتزاعی معرفی کنید تا به ماژول‌های سطح بالا اجازه دهید به این انتزاع‌ها وابسته باشند.از تزریق وابستگی برای تزریق پیاده‌سازی‌های واقعی به ماژول‌های سطح بال از طریق انتزاع‌هایِ آنها استفاده کنید. این کار باعث پیوستگی ضعیف می‌شود.ترکیب اصل وارونگی وابستگی (DIP) با سایر اصول SOLID می‌تواند منجر به کد تمیزتر و قابل نگهدارتر شود.استفاده از چارچوب‌های تزریق وابستگی مانند Spring یا Guice را برای مدیریت خودکار وابستگی‌ها در نظر بگیرید.سخن پایانیاصول SOLID راهنماهای اساسی برای طراحی و نگهداری سیستم‌های نرم‌افزاری باکیفیت بالا، انعطاف‌پذیر و قدرتمند هستند. تشویق به کاربرد این اصول در شیوه‌های توسعه نرم‌افزار می‌تواند منجر به توسعه کارآمدتر، باگ کمتر و تکامل نرم‌افزار به‌صورت روان‌تر در طول زمان شود. پذیرش اصول SOLID سرمایه‌گذاری برای موفقیت بلندمدت و پایداری پروژه‌های نرم‌افزاری است.</description>
                <category>danny</category>
                <author>danny</author>
                <pubDate>Fri, 11 Oct 2024 13:57:04 +0330</pubDate>
            </item>
                    <item>
                <title>معرفی کتاب معماری‌های مُدرن در نرم‌افزار</title>
                <link>https://virgool.io/@dany_kh/%D9%85%D8%B9%D8%B1%D9%81%DB%8C-%DA%A9%D8%AA%D8%A7%D8%A8-%D9%85%D8%B9%D9%85%D8%A7%D8%B1%DB%8C-%D9%87%D8%A7%DB%8C-%D9%85%D9%8F%D8%AF%D8%B1%D9%86-%D8%AF%D8%B1-%D9%86%D8%B1%D9%85-%D8%A7%D9%81%D8%B2%D8%A7%D8%B1-ci4hspeksgkv</link>
                <description>مقدمه:چند ماه پیش که کتاب سیستم دیزاین ۱ رو معرفی کردم. با یک بازخورد مواجه شدم که این کتاب برای افراد تازه‌وارد سختی‌هایی داره و برای این کتاب یک مقدمه لازمه با صحبت‌هایی که با دوستم جواد (نویسنده دیگه‌ی کتاب) داشتم به این نتیجه رسیدیم که جای کار روی کتاب دیگه‌ای، بریم سراغ یه متن مقدماتی و البته رایگان برای کتابِ «سیستم دیزاین۱» و می‌خواستیم یک متن بین ۱۰۰ الی ۱۵۰ صفحه‌ای باشه که مقدمه‌ای باشه برای درک بهتر کتاب قبلی‌ مون و اسمش رو هم گذاشتیم «مقدمه‌ای بر سیستم دیزاین» یا «مقدمه‌ای بر طراحی سیستم نرم‌افزاری» و عمده متن‌های مورد نظرمون از کتاب سیستم دیزاین karan و سایت bytebytego  و چندتا منبع دیگه‌ بود. ما شروع به نوشتن کردیم و سعی کردیم مباحثی رو بیاریم که هم برای مخاطب جالب باشه و هم برای خودمون و کلی وسواس به خرج دادیم تا کتاب نزدیک ۸۵۰ صفحه شد. بعد فکر کردیم این رو دو تا کتاب جداگانه کنیم پس شد یکی  این کتاب و یک کتابی هم در مورد اصول solid و design pattern‌ها که برای پیاده‌سازی با زبان‌های معروف برنامه‌نویسی رایج نسخه‌های متفاوتی داشته باشه؛ در ادامه روی اصلاح متن و تدوین کتاب اول کار کردم و چون نمی‌خواستم فقط تو حوزه سیستم دیزاین باشه و کتاب موضوعات مختلفی رو شامل می‌شد که به هم ربط داشتند، در نتیجه اسم کتاب رو به «معماری‌های مُدرن در نرم‌افزار» تغییر دادیم و اون کتاب دوم رو هم بی‌خیال شدیم در حال حاضر. هر چند این برنامه وجود داره که چند وقت یکبار این کتاب رو بروزرسانی هم بکنیم و برای اطلاع از بروزرسانی‌ها صفحه گیت‌هاب کتاب رو دنبال کنید.این کتاب برای چه افرادی مناسب هست؟ایده‌ی من این بود که این کتاب برای کسانی که مدرک تحصیلی‌شون رو گرفتند و می‌خوان وارد بازار IT بشند مناسب هستش و یه دید کلی توی مباحث مهم و اساسی بهشون می‌ده.برای افرادی که می‌خوان با راه‌حل‌های مختلف و روش‌های مشخص و تثبیت شده در نرم‌افزار کار بکنند.برای مصاحبه‌های استخدامی نرم‌افزاری از کجا کتاب رو دانلود کنیم؟راه حل مستقیم این هست که روی این لینک دانلود کلیک کنید تا دانلود بشه. ولی همونطور که گفتم برای دریافت بروزرسانی‌های یا صفحه گیت‌هاب رو دنبال یا watch کنید یا صفحه Release اون رو.حرف آخرگرفتن بازخورد و نظرتون می‌تونه باعث بهبود کار ما برای سایر فعالیت‌های مشابه بشه و برای بازخورد و سایر پیشنهاد‌هاتون به ایمیل من و جواد در مقدمه کتاب رجوع کنید.اگر کتاب براتون مفید بود به دیگران هم معرفیش کنید :)</description>
                <category>danny</category>
                <author>danny</author>
                <pubDate>Wed, 21 Aug 2024 01:22:07 +0330</pubDate>
            </item>
                    <item>
                <title>ریپو‌های مهم GitHub که هر مهندس نرم‌افزار باید بداند.</title>
                <link>https://virgool.io/@dany_kh/%D8%B1%DB%8C%D9%BE%D9%88-%D9%87%D8%A7%DB%8C-%D9%85%D9%87%D9%85-github-%DA%A9%D9%87-%D9%87%D8%B1-%D9%85%D9%87%D9%86%D8%AF%D8%B3-%D9%86%D8%B1%D9%85-%D8%A7%D9%81%D8%B2%D8%A7%D8%B1-%D8%A8%D8%A7%DB%8C%D8%AF-%D8%A8%D8%AF%D8%A7%D9%86%D8%AF-onhxgliqsvho</link>
                <description>سرانجام، پس از مدت‌ها، به تمایل خود برای نوشتن مقالاتی برای کمک به سایر مهندسان نرم‌افزار برای پیشرفت شغلی خود پی بردم. با این کار، من قصد دارم به آنها کمک کنم تا دانش خود را بهبود بخشند، درحالی‌که به خودم اجازه می‌دهم در طول این فرایند یاد بگیرم و رشد کنم. در اولین مقاله‌ام، مجموعه‌ای از ریپو‌های جالب را برای همه مهندسان نرم‌افزاری که بدون درنظرگرفتن سطح یا موقعیت خود به دنبال به‌روز ماندن و بهبود مهارت‌های خود در هر زمان ممکن هستند، به شما ارائه می‌دهم. بیایید مستقیماً به سراغ آن‌ها برویم:گزینه‌های مورد نظر بر اساس دسته‌بندی زیر است.RoadMapsBooks, Blogs, and WebsitesAlgorithmsDesign PatternsSystem DesignDesign ResourcesProjects, Tutorials, and APIsInterviewsRoadMapsدر مورد RoadMaps ما دو repo داریم که زمانی که به دنبال یادگیری در مورد یک‌زبان یا ابزار هستید، مسیری را برای دنبال‌کردن ارائه می‌دهند و به شما راهنمایی می‌کنند تا دانش اولیه‌ای را که باید کسب کنید یا قبلاً داشته باشید.https://github.com/kamranahmedse/developer-roadmaphttps://github.com/liuchong/awesome-roadmapsکتاب‌ها، وبلاگ‌ها و وب‌سایت‌هاپس از درک مسیری که باید از طریق نقشه راه طی کنید، باید به اسناد، کتاب‌ها، وبلاگ‌ها و وب‌سایت‌ها بپردازید. برای این کار، ما چندین مخزن با کتاب‌ها، وبلاگ‌ها و سایت‌های مهم مختلف برای شما داریم تا پایگاه دانش خود را به طور مستحکم بسازید.https://github.com/EbookFoundation/free-programming-bookshttps://github.com/kilimchoi/engineering-blogshttps://github.com/sdmg15/Best-websites-a-programmer-should-visithttps://github.com/freeCodeCamp/freeCodeCampالگوریتم‌هابا داشتن یک پایگاه دانش خوب، می‌توانید از repoهای زیر دیدن کنید و دانش خود را در الگوریتم‌ها عمیق‌تر کنید، پیاده‌سازی الگوریتم‌های مختلف را در زبان‌های برنامه‌نویسی مختلف بررسی کنید تا همیشه بهترین رویکرد را در هنگام مواجهه با یک مشکل بدانید.https://github.com/arpit20adlakha/Data-Structure-Algorithms-LLD-HLDhttps://github.com/tayllan/awesome-algorithmsالگوهای طراحی (Design Patterns)از طریق مخازن الگوهای طراحی، می‌توانید دانش خود را در مورد الگوهای مورداستفاده در اجرای خدمات و پروژه‌ها عمیق‌تر کنید و درک کنید که آن‌ها چگونه کار می‌کنند و چگونه می‌توانید آنها را پیاده‌سازی کنید.https://github.com/kamranahmedse/design-patterns-for-humanshttps://github.com/DovAmir/awesome-design-patternsطراحی سیستم (System Design)با مخازن System Design، می‌توانید درک خود را از ساخت برنامه‌های خود، درنظرگرفتن مقیاس‌پذیری، performance، روش‌های ذخیره‌سازی داده‌ها، به‌دست‌آوردن دانش برای کمک به تعریف فنی برنامه و توسعه یک پروژه باکیفیت را عمیق‌تر کنید.https://github.com/ByteByteGoHq/system-design-101https://github.com/donnemartin/system-design-primerhttps://github.com/InterviewReady/system-design-resourceshttps://github.com/karanpratapsingh/system-designمنابع طراحی (Design Resources)با مخازن زیر می‌توانید به منابع طراحی مختلف مانند راهنماهای سبک، قالب‌های وب، چارچوب‌های CSS دسترسی داشته باشید و بهترین طرح‌ها و الگوهای طراحی را برای پروژه‌های خود ایجاد کنید.https://github.com/goabstract/Awesome-Design-Toolshttps://github.com/bradtraversy/design-resources-for-developersپروژه‌ها، تمرین‌ها و APIهابرای دستیابی به کار و ایجاد پروژه‌های خود، مخازن زیر ایده‌ها، پروژه‌های قبلاً اجرا شده و APIهای عمومی را ارائه می‌کنند که منابع و ابزارهایی را در اختیار شما قرار می‌دهند تا همه چیزهایی را که آموخته‌اید تمرین کنید و دانش کسب شده را تقویت کنید.https://github.com/florinpop17/app-ideashttps://github.com/practical-tutorials/project-based-learninghttps://github.com/public-apis/public-apisمصاحبه‌هادر نهایت، در مخازن زیر، پس از تمام مراحل آماده‌سازی و اجرای پروژه، ابزارها و اسناد مختلفی را در اختیار شما قرار داده شده تا به شما کمک کند که آمادگی مصاحبه خود را بهبود بخشیده و آنها را به بهترین شکل ممکن انجام دهید و در حرفه خود پیشرفت کنید و به دیگران کمک کنید.https://github.com/kdn251/interviewshttps://github.com/yangshun/tech-interview-handbookhttps://github.com/DopplerHQ/awesome-interview-questionsنتیجه‌گیریامیدوارم از این پست لذت برده باشید و چیزهای جدیدی یاد بگیرید.ممنون ❤️منبع:https://dev.to/jrmarcio_/github-repositories-every-software-engineer-should-know-2e80?ref=dailydev&lt;br/&gt;</description>
                <category>danny</category>
                <author>danny</author>
                <pubDate>Tue, 06 Aug 2024 21:31:35 +0330</pubDate>
            </item>
                    <item>
                <title>چرا باید با کپی کردن شروع کنیم؟</title>
                <link>https://virgool.io/@dany_kh/%DA%86%D8%B1%D8%A7-%D8%A8%D8%A7%DB%8C%D8%AF-%D8%A8%D8%A7-%DA%A9%D9%BE%DB%8C-%DA%A9%D8%B1%D8%AF%D9%86-%D8%B4%D8%B1%D9%88%D8%B9-%DA%A9%D9%86%DB%8C%D9%85-hgoqgh55t5cf</link>
                <description>داستان اولچارلز ایمز به بهترین وجه گفت: «ما «هنر» نمی‌کنیم، بلکه مشکلات را حل می‌کنیم.»برای خرید مبلمان در سال 1950، باید بین مقرون به صرفه بودن و ماندگاری، بین ناهموار و مد روز یکی را انتخاب می کردید. Charles و Ray یک صندلی طراحی کردند که تمام موارد بالا بود و آن را به قیمت 20.95 دلار فروختند و آن را LCW نامیدند.در LCW تجسم وسواس ایمز در مورد سادگی در مواد و روش است. آنها گفتند:«ما می خواهیم بهترین ها را برای کمترین ها بسازیم.» طراحی انقلابی بود: در سال 1999، مجله تایم LCW را «بهترین طراحی قرن» نامید. امروز می‌توانید یک LCW کاملاً جدید از هرمان میلر (تولیدکننده مجوز رسمی محصولات Eames) با قیمت 1195 دلار خریداری کنید. یا می‌توانید یک صندلی به نام &#x27;Fathom&#x27; را از شرکتی به نام Modway به قیمت 145 دلار خریداری کنید.از نظر عملکرد و زیبایی، صندلی ها یکسان هستند.یک LCW مربوط به سال 1946 در مجموعه MOMA وجود دارد. این یکی از اولین نمونه‌هایی است که تا کنون ساخته شده است. اکثر مردم آن را LCW اصلی می نامند.چارلز و ری ایمز حقوق تولید مبلمان خود را در سال 1947 به هرمان میلر فروختند. مجموعه داران LCWهای ساخته شده در دهه 40 و 50 را &#x27;اصل&#x27; می نامند. اما به نوعی، اینها - و نسخه‌های هرمان میلر که اخیراً تولید شده‌اند - کپی‌هایی از آن LCW در مجموعه MOMA هستند.و سپس Modway Fathom وجود دارد. این به وضوح یک کپی است، یک نسخه بدون مجوز. اما با قیمت 145 دلار (معادل 12.78 دلار در سال 1947) مقرون به صرفه تر از LCW است که برای اولین بار تولید و فروخته شد. از نظر روحی، بیشتر از هر LCW اصلی است: بهترین، برای بیشتر افراد با کمترین قیمت.من این داستان را به اشتراک می‌گذارم زیرا یک واقعیت شگفت‌انگیز را نشان می‌دهد: چه چیزی چیزی را «اصیل» (اولین، بهترین، معروف‌ترین، واقعی‌ترین) یا «کپی» (یک کپی، یک کپی غیرمجاز، یک تفسیر یا یک ریمیکس) می‌سازد. همیشه واضح نیست، هر چند که مهم است.من یک طراح هستم من به عنوان یک طراح، احساس می کنم باید اصیل باشم. اگر طراح هستید، یا حتی اگر فقط به طراحی علاقه دارید، احتمالاً احساس می کنید که باید اصیل باشید. ما تمایل داریم مخترعان و مبتکران را پرستش کنیم، طراحانی که پیشرو و مبتکر بودند. پس ما از آنها را کپی می کنیم.این نوع کاردستی می تواند انسان را دیوانه کند. فضای زیادی بین اصالت و صنعت، تأیید و تصدیق  وجود دارد.برخی از مردم از کپی برداری ناامید شده اند، از پذیرش آن سرباز زده اند و با تمام توان خود در برابر آن مبارزه کرده اند. افراد دیگر از کپی برداری به نفع خود استفاده کرده اند، خواه برای بهبود خود یا ایجاد یک جامعه بهتر.من فقط به دلیل کپی کردن توانستم در طراحی دارای درجه حرفه‌ای باشم.امیدوارم تا زمانی که خواندن را تمام کردید، متوجه اهمیت کپی برداری شوید. درست یا غلط، فضیلت یا بد، کپی کردن روشی است که در طراحی‌ها به خوبی کار می‌کند.داستان دوماستیو جابز اهل کپی کردن بود. او به نقل از پابلو پیکاسو (یا استراوینسکی؟ تی. اس. الیوت؟) گفت: «هنرمندان بزرگ دزدی می‌کنند». جابز و اپل در روزهای اولیه خود از بسیاری از طرح‌ها کپی کردند که مهمترین آنها از یک آزمایشگاه تحقیقاتی زیراکس (Xerox) در Palo Alto بود. داستان اینچنین پیش می رود:زیراکس در اوایل قرن بیستم پیشگام فناوری اداری بود. در اواسط قرن، رایانه‌ها کوچک‌تر و مقرون به صرفه‌تر شدند و زیراکس می‌دانست که باید سخت تلاش کند تا تسلط خود را در بازار حفظ کند. در سال 1970، مرکز تحقیقات زیراکس پالو آلتو - زیراکس PARC - برای بررسی آینده &#x27;paperless office&#x27; تاسیس شد.طی دو سال، زیراکس PARC یک کامپیوتر پیشگامانه به نام Alto طراحی کرد. یکی از ابداعات آن یک رابط کاربری گرافیکی بود: برنامه‌ها و فایل‌ها در پنجره‌های مجازی نمایش داده می‌شدند که کاربران با استفاده از ماوس مسیریابی می‌کردند. این تصویر ترسناک دقیقی بود از اینکه کامپیوترهای شخصی 30 سال بعد چگونه خواهند بود.جف راسکین، رهبر پروژه مکینتاش در اپل، کارهای زیراکس را دیده بود. او می خواست استیو جابز خودش آن را ببیند و جلسه‌ای در این مورد ترتیب داد.جابز درباره رابط کاربری Alto گفت: «فکر می‌کردم این بهترین چیزی است که در زندگی‌ام دیده‌ام. «در عرض ده دقیقه برای من واضح بود که همه رایانه ها روزی به این شکل کار می کنند.»هنگامی که مکینتاش در سال 1984 عرضه شد، دارای یک رابط کاربری گرافیکی بود. برنامه‌ها و فایل‌ها در پنجره‌های مجازی نمایش داده می‌شوند که کاربران با استفاده از ماوس آن‌ها را هدایت می‌کنند.درست مثل Alto بود.استیو جابز دوست نداشت چیزی کپی شود.در سال 1985، یک سال پس از عرضه مکینتاش، اپل از شرکتی به نام Digital Research Interactive به دلیل کپی کردن رابط کاربری مکینتاش شکایت کرد. شکایت از Digital Research خارج از دادگاه حل شد و ظاهر نمادها، پنجره‌ها و نشانگرهای ماوس خود را تغییر داد.در سال 1990، اپل از مایکروسافت و HP شکایت کرد. این مورد تکرار شد: ویندوز مایکروسافت و HP NewWave دارای طرح‌هایی بودند که اپل ادعا کرد کپی‌هایی از سیستم عامل مکینتاش هستند. اما قراردادهای اولیه مجوز بین اپل و مایکروسافت مشخص نکرد که آیا تخلفی صورت گرفته است یا خیر. در نتیجه پرونده بدون نتیجه خاصی مختومه شد.در اواسط پرونده اپل علیه مایکروسافت، زیراکس از اپل شکایت کرد، به این امید که حقوق خود را به عنوان مخترع رابط کاربری دسکتاپ تثبیت کند. دادگاه این پرونده را نیز منتفی کرد و این سوال را مطرح کرد که چرا زیراکس اینقدر طول کشید تا این موضوع را مطرح کند. بیل گیتس بعداً در مورد این موارد گفت: «هر دوی ما این همسایه ثروتمند به نام زیراکس را داشتیم... من برای دزدی به خانه او نفوذ کردم تا چیزی هایی مثل تلویزیون  را بدزدم ولی فهمیدم که [جابز] قبلاً آن را دزدیده است.»کپی برداری گسترده که به رشد انفجاری رایانه های مصرف کننده دامن می زد به این معنی بود که تا سال 1990، رابط کاربری دسکتاپ همه جا حاضر بود. تعیین اینکه چه کسی منشأ بخشی از آن است، یا چه کسی از چه کسی کپی کرده است، غیرممکن بود. تلاش برای به خطر انداختن ادعای آنها تقریباً اپل را از بین برد. اما وقتی ظاهر شدند، یکی دو چیز یاد گرفته بودند. امروزه اپل بیش از 2300 گواهی طراحی ثبت شده دارد.این داستان در سال 2011 با شکایت اپل از سامسونگ به دلیل کپی برداری از طراحی محصولات نرم افزاری و سخت افزاری به پایان می رسد. یکی از قابل توجه ترین ادعاها: سامسونگ با فروش «محصول مستطیلی شکل با چهار گوشه گرد یکنواخت» قانون را زیر پا گذاشت.دادگاه، ادعای اپل برای داشتن مستطیل‌های گرد را رد کرد. اما سایر ادعاها را تأیید کرد و سامسونگ را به دلیل نقض patent به پرداخت 539 میلیون دلار جریمه کرد.طراحان کپی می‌کنند. ما مثل هنرمندان بزرگ دزدی می‌کنیم. اما وقتی نسخه‌ای از کارمان را می‌بینیم، عصبانی می‌شویم. جابز، درباره اندروید از محصولات گوگل گفته است: «اگر لازم باشد آخرین نفس خود را صرف می کنم و هر پِنی از ۴۰ میلیارد دلار اپل را در بانک خرج می کنم تا این اشتباه را اصلاح کنم. من قصد دارم اندروید را نابود کنم، زیرا یک محصول دزدیده شده است.»استیو جابز در تعهد رویایی خود به نوآوری بی‌بدیل بود. اما او هرگز با اجتناب‌ناپذیری کپی کردن کنار نیامد.داستان سومجان کارمک رابطه متفاوتی با کپی کردن داشت. برای او کپی کردن راهی برای یادگیری، چالشی برای برتری یافتن غلبه کردن و منبع ایده‌های جدید بود. Carmack در گذشته و تا به حال  یک کدنویس درخشان است. او بیشتر به خاطر برنامه‌سازی بازی‌های تیراندازی اول شخصِ پرخشونت و خشن مانند Doom و Quake شهرت دارد. آن بازی‌ها، مرزهای بازی‌های رایانه‌ای را جابجا کردند و یک ژانر جدیدی را تعریف کردند. اما اولین بازی موفقیت آمیز واقعی او ساده‌تر، زیباتر و عجیب‌تر بود که به آن Commander Keen می‌گفتند.من وقتی در اوایل دهه 90 بزرگ شدم، بازی Commander Keen را دوست داشتم. این یک بازی ماجراجویی و طنز است. شما یک پسر هشت ساله با کلاه ایمنی فوتبال و کفش‌های قرمز را در میان سیارات بیگانه راهنمایی می کنید، که آب نبات را جمع آوری می‌کند و هیولاها را با یک تفنگ لیزری از بین می‌برد.Keen زندگی خود را به عنوان یک کپی از یکی دیگر از بازی های مورد علاقه من آغاز کرد:  که Super MarioBros3 نام داشت.قبل از بازی  Commander Keen آقای Carmack برای یک شرکت نرم‌افزاری اشتراکی به نام Softdisk کار می‌کرد. Carmack و سایر برنامه نویسان در Softdisk این بازی‌ها را با سرعت فوق العاده ای تولید کردند: امروزه ساخت بازی های پرفروش بیش از پنج سال طول می‌کشد؛ در حالی که در آن زمان و در Softdisk هر ماه یک بازی کامل و کاملاً جدید تولید می‌کند.در سپتامبر 1990، کارمک تصمیم گرفت که برای بازی بعدی خود، سعی کند با یک چالش جدید و دلهره آور مقابله کند و آن هم به کمک استفاده از  فناوری scrolling بود. در آن زمان، تنها کنسول‌هایی مانند نینتندو قدرت محاسباتی کافی برای پیمایش آرام مناظر، شخصیت‌ها و دشمنان داشتند. رایانه های شخصی به بازی های ساده تک صفحه‌ای در یک زمان چسبیده بودند. اما اگر قرار بود کارمک میلیون‌ها بازی مانند نینتندو را با Super Mario Bros بفروشد، باید بفهمد که چگونه می‌تواند این اثر را بازسازی کند.بنابراین، در 19 سپتامبر 1990، Carmack و توسعه دهنده دیگری به نام Tom Hall تصمیم گرفتند که مرحله اول Super Mario Bros 3 را مهندسی معکوس کنند. Hall بین فریم‌های تصویر در صفحه تلویزیون و کامپیوترش جلو و عقب کرد و نسخه نینتندو را پخش کرد و مکث کرد تا تصاویر پیکسل به پیکسل را کپی کند.روز بعد نتیجه را به همکارنش نشان داد و آن‌ها بسیار شگفت زده شدند. هیچ کس تا به حال چنین بازی رایانه‌ای را ندیده بود. جان رومرو، نزدیک‌ترین همکار و همکار آینده کارمک در Doom and Quake، آن را «جالب‌ترین چیز روی کره زمین» نامید. او اصرار داشت که آنها به کپی کردن ادامه دهند تا زمانی که نسخه کامل بازی را تمام کنند. آنها قصد داشتند آن را به Nintendo بفرستند.با تاسف برای Carmack و تیمش، Nintendo علاقه‌ای به نسخه رایانه شخصی Super Mario نداشت (زیرا نسخه کنسول آنها به خوبی کار می کرد و به فروش می‌رفت).ناامید، اما شکست نخورده، تصمیم گرفتند نسخه بهتری از ماریو بسازند. با شروع کد Carmack برای اسکرول و متحرک کردن صفحه، کدنویس‌ها با مفهومی را که خود آن را ایده‌هایی از عمق می‌نامند و توسعه این بازی را از کارهای روزانه خود در Softdisk مخفی نگه می‌داشتند تا زمانی که نسخه Super Mario خود را در یک دگردیسی کامل قرار دادند. به جای ماریو، بیلی بلیز هشت ساله در آن بازی کرد. به جای لاک پشت ها و قارچ ها، دشمنان موجودات فضایی به نام Yorps بودند. بیلی بلیز به جای خوردن قارچ برای پریدن بالاتر، روی چوب پرید.اولین بازی Commander Keenبا نامِ Commander Keen در Invasion of the Vorticons دارای موفقیت بزرگی بود. بیش از 50000 نسخه فروخته شد و Keen را به یکی از پرفروش‌ترین بازی‌های PC در زمان خود تبدیل کرد.برخلاف استیو جابز، جان کارمک هرگز نظر خود را در مورد کپی کردن تغییر نداد. هنگامی که رئیس او در Softdisk به آنها پیشنهاد داد که تکنیک اسکرول رایانه شخصی Carmack را ثبت اختراع کنند، Carmack متعجب شد. او گفت: «اگر از من بخواهید حق امتیازی را ثبت کنم، من این شرکت و کار را رها خواهم کرد.»در سال 2005 در یک پست فروم، جان کارمک افکار خود را در مورد اختراعات توضیح داد. او نوشت، در حالی که پتنت‌ها به عنوان محافظ مخترعان در نظر گرفته می‌شوند، به ندرت از این طریق استفاده می‌شود. برنامه نویسان باهوشی که روی مشکلات سخت کار می کنند، معمولاً راه حل های مشابهی ارائه می دهند. اگر یکی از این برنامه نویسان راه حل خود را ثبت اختراع کند، کار بقیه با مشکل می‌شوند.او  گفت: من  هیچ بخشی از  (حق مالکیت) آن را ندارم.  زیرا این کار اساساً نابود کردن کسی دیگر است.»کارمک در بازی‌های خود پس از Keen پا را فراتر از ثبت نکردن اختراع خود گذاشت. او کد منبع را برای بزرگترین بازی های دهه 90 یعنی Wolfenstein 3D، Doom و Quake منتشر می‌کرد. همه‌ی افراد برای دانلود، تغییر یا کپی کردن آنها آزادند.داستان چهارمیک چیز دیگر در مورد کپی کردن وجود دارد و آن هم تشویق دیگران به کپی برداری از شما است. ریچارد استالمن از این هم فراتر رفت - او کپی کردن را به یک حق تبدیل کرد.در سال ۱۹۸۳، ریچارد استالمن قصد داشت یک سیستم عامل جدید بسازد. در آن زمان، یونیکس محبوب ترین و تاثیرگذارترین سیستم عامل بود، اما صدور مجوز برای آن گران بود. هزینه مجوزهای تجاری 20000 دلار است و این مبلغ 52028 دلار در سال 2020 است. با توجه داشت که یونیکس منبع بسته بود.بنابراین در ۲۷سپتامبر ۱۹۸۳، او این پیام را در صفحه پیام جادوگران یونیکس نوشت:یونیکس رایگان!

با شروع این روز شکرگزاری، می‌خواهم یک سیستم نرم‌افزاری کامل سازگار با یونیکس به نام GNU (برای Gnu&#039;s Not Unix) بنویسم و ​​آن را رایگان در اختیار همه کسانی که می‌توانند از آن استفاده کنند، بدهم. مشارکت زمان، پول، برنامه‌ها و تجهیزات بسیار مورد نیاز است.
اینکه استالمن نرم‌افزاری بنویسد و آن را به دیگران بدهد تا از آن استفاده کنند، یک تصور رادیکال بود. استالمن مانیفستی نوشت و ایده نرم‌افزار آزاد را تعریف کرد «نرم‌افزار آزاد نرم‌افزاری است که کاربران در توزیع و تغییر آن آزادی دارند». او مانیفست جنبش نرم‌افزار آزاد را آغاز کرد.نوآوری پایدار جنبش استالمن این بود که چگونه او و همدستانش از مجوزهای نرم‌افزاری استفاده کردند. آنها مجوزهای سنتی را بر سر آن گذاشتند: به جای ممنوعیت کپی یا توزیع نرم‌افزار، مجوز نرم افزار آزاد می‌توانست حق استفاده، تغییر، توزیع و یادگیری از کد آن را تضمین می‌کند.مجوز نرم افزار آزاد به جای ممنوعیت کپی یا توزیع نرم افزار، حق استفاده، تغییر، توزیع و یادگیری از کد آن را تضمین می کند.انواع جدید مجوزهای نرم افزاری تنها محصول جنبش نرم افزار آزاد نبودند. شاخه های ایدئولوژیک به سرعت به گروه های جدیدی مانند جنبش نرم افزار منبع باز تبدیل شدند. در حالی که جناح نرم افزار آزاد استالمن حول گروه کوچکی از کدنویسان مترقی و تندرو متمرکز بود، جنبش منبع باز گسترده و فراگیر بود و برخی از زبان سیاسی تر استالمن را برای گسترش بیشتر و یافتن مخاطبان جدید رها کرد.صدور مجوز مجاز و کنترل منبع توزیع شده موتور توسعه نرم افزار مدرن را تشکیل می دهد. آنها یک حلقه بازخورد، یا یک جفت همزیستی، یا یک موجود زنده، یا حتی یک ویروس ایجاد می کنند: ابزارهایی که توسعه‌دهندگان نرم‌افزار استفاده می کنند، خود محصول فلسفه منبع باز هستند. کد رایگان و منبع باز خود را تکرار می‌کند، جهش می‌یابد و فوراً در سراسر جهان پخش می‌شود.جنبش‌های نرم‌افزاری آزاد و متن‌باز (گاهی اوقات در یک مخفف واحد، FOSS ترکیب می‌شوند) با انقلاب دیگری در نحوه صدور مجوز آثار خلاقانه منعکس شد. در سال 2001، لارنس لسیگ، هال آبلسون و اریک الدرد Creative Commons را راه‌اندازی کردند، یک شبکه غیرانتفاعی و بین‌المللی که به ایجاد امکان اشتراک‌گذاری و استفاده مجدد از «خلاقیت و دانش از طریق ارائه ابزارهای قانونی رایگان» اختصاص داشت.تقریباً 20 سال بعد، نزدیک به نیم میلیون تصویر در Flickr دارای مجوز Creative Commons (یا CC) هستند. ویکی‌پدیا از مجوزهای CC در تمام عکس‌ها و آثار هنری خود استفاده می‌کند. MIT بیش از 2400 دوره را به صورت آنلاین تحت مجوز Creative Commons ارائه می دهد. میلیون ها اثر خلاقانه بی شماری از رویکرد منبع باز مجوزها و مجوزها بهره برده اند.یک دهه پیش، جنبش منبع باز به عرصه‌‌ی طراحی آمد. مایکل چو Unsplash را در سال 2013 برای به اشتراک گذاشتن چند عکس که فکر می کرد ممکن است برای طراحان استارت آپ مفید باشد را ایجاد کرد. تا سپتامبر 2020، Unsplash میزبان حدود ۲۱۷۸۵۷۹ عکس است و تعداد بارگیری‌های عکس در تمام زمان‌ها به بیش از ۲ میلیارد رسیده است. پابلو استنلی اخیراً Humaaans را منتشر کرده است، مجموعه‌ای از طرح‌های دارای مجوز Creative Commons که می‌توان آنها را مجدداً در گرافیک ویرایشی جمع‌آوری کرد. نمادهای Feather، Heroicons و Bootstrap Icons همگی مجموعه‌های متن‌باز و رایگانی از آیکون‌های UI هستند که توسط طراحان برای ساخت وب‌سایت‌ها و برنامه‌ها استفاده می‌شوند.در همین حال، انفجار منابع طراحی منبع باز توسط دسته جدیدی از ابزارها برای به اشتراک گذاری و همکاری در طراحی تقویت شده است. Abstract یک سیستم کنترل نسخه برای طراحی است که نوید «همکاری بدون هرج و مرج» را می‌دهد. با Abstract، بسیاری از طراحان می توانند بدون نگرانی در مورد بازنویسی تغییرات یکدیگر یا همیشه نیاز به دانلود آخرین نسخه ها، در یک فایل مشارکت کنند. Figma نیز به تازگی ویژگی جامعه خود را راه اندازی کرده است که به طراحان اجازه می دهد فایل ها را منتشر کرده و پروژه های یکدیگر را دانلود کنند. تصور اینکه چگونه در آینده نزدیک به نسخه طراح GitHub تبدیل خواهد شد، سخت نیست. سایر ابزارهای طراحی نیز از همین روش پیروی کرده اند: هر دو Sketch و Framer هاب های محتوای جامعه را راه اندازی کرده اند، که زمینه را برای کنترل منبع توزیع شده فراهم کرده اند.کپی کردن برای طراحی بسیار مهم است، درست مانند نرم افزار. ظهور مجوزهای مجاز و ابزارهای کنترل نسخه باعث می شود به نظر برسد کپی کردن یک ایده جدید است، یک رویکرد نوآورانه در صنعتی که با تازگی پیشرفت می کند. اما حقیقت این است که کپی کردن هزاران سال است که هنر و صنعت را متحول کرده است.داستان پنجمدر چین مفاهیم زیادی از یک کپی وجود دارد که هر کدام دارای زیرمتن مجزا هستند. فانگژیپین (仿製品) کپی‌هایی هستند که آشکارا با نسخه اصلی متفاوت هستند - مانند مدل های کوچک یادگاری یک مجسمه. فوژیپین (複製品) بازتولید دقیق و در اندازه واقعی از نسخه اصلی است. فوژیپین به اندازه نمونه های اصلی ارزشمند است و هیچ نکته منفی‌ای ندارد.در سال ۱۹۷۴، کشاورزان محلی در منطقه شیان چین مجسمه‌هایی از سربازان در اندازه واقعی از خاک رُس را کشف کردند. هنگامی که باستان شناسان چینی برای بررسی این مکان آمدند، چهره به چهره، از جمله اسب‌ها و ارابه‌ها را کشف کردند که همه جزئیات بسیار عالی بود. در مجموع، بیش از ۸۰۰۰ سرباز تراکوتا وجود داشتند. قدمت آنها به 210 قبل از میلاد می رسد.جنگجویان سفالی فوراً به گنجینه فرهنگی تبدیل شدند. موزه‌ای در محل حفاری ساخته شد، اما بسیاری از مجسمه‌ها نیز در نمایش‌های مسافرتی به نمایش گذاشته شدند. صدها هزار موزه‌دار در سرتاسر جهان در گالری‌ها صف کشیده‌اند تا سربازان را ببینند.سپس، در سال ۲۰۰۷، افشاگری موزه für Völkerkunde در هامبورگ، آلمان (جهان) را به لرزه درآورد: برخی از جنگجویان سفالی که به نمایش گذاشته شده بود، نمونه‌های اصلی کشف‌شده در مزرعه در شیان نبودند. آنها کپی بودند.مدیر موزه für Völkerkunde بدبین شد: «ما به این نتیجه رسیده‌ایم که برای حفظ شهرت موزه هیچ گزینه دیگری جز بستن کامل نمایشگاه وجود ندارد.» موزه به بازدیدکنندگان بازپرداخت صادر کرد. این رویداد باعث شروع موجی از انگشت نشان دادن ژئوپلیتیک شد: مقامات آلمانی شرمسار بودند و می گفتند فریب خورده‌اند. مقامات چینی دست های خود را شستند، زیرا از ابتدا هرگز ادعا نکردند که مجسمه‌ها اصلی هستند.مجسمه های موجود در موزه هامبورگ فوژیپین، کپی‌های دقیق بودند. آنها معادل نسخه اصلی بودند. از این گذشته، نسخه های اصلی خود محصولات تولید انبوه بودند که با ماژول ها و اجزای ساخته شده از قالب ساخته شده بودند. تقریباً به محض اینکه جنگجویان سفالی کشف شدند، صنعتگران چینی شروع به تولید ماکت کردند و به کاری که بیش از ۲۰۰۰ سال قبل شروع شده بود را ادامه دادند.به راحتی می توان این رویکرد را به کپی برداری به عنوان یک کنجکاوی فرهنگی نسبت داد، یک انحراف خاص در چین. اما کپی کردن به همان اندازه برای هنرمندان غربی حیاتی بود.هنر ژاپنی یکی از منابع اصلی الهام ونسان ون گوگ (Vincent van Gogh) بود که خود یکی از تأثیرگذارترین نقاشان اروپایی قرن نوزدهم، اگر نگوییم در تمام دوران ها بود. ون گوگ مجذوب نقاشی‌های چوبی هنرمندانی مانند هیروشیگه بود: سبک و واضح، آنها لحظات دراماتیکی را در داستان‌های متقاعدکننده ثبت کردند.علاقه ون گوگ فراتر از الهام بود. او برای مطالعه تکنیک‌هایی که توسط هنرمندان ژاپنی تسلط یافتند، از چاپ‌های Keisei Eisen و Utagawa Hiroshige کپی کرد. او سعی کرد خطوط پررنگ، ترکیبات پرانرژی و رنگ های قوی آنها را تکرار کند. ون گوگ برای نسخه‌ای از کتاب «یک اطلسان آیزن» با ردیابی طرح کلی پیکره زن جلیل‌التحریر مستقیماً از نسخه مه ۱۸۸۶ پاریس Illustré شروع کرد. او برای «درخت گلدار آلو» و «پل در باران»، که هر دو نسخه‌ای از چاپ هیروشیگه هستند، حاشیه‌هایی از خط ژاپنی را که روی چاپ‌های دیگر دیده بود، اضافه کرد.تمرین او با سبک های ژاپنی پیشرفت مهمی ایجاد کرد. ون گوگ شروع به صاف کردن مناظر کرد. او موضوعات خود را با خطوط مشکی برجسته ترسیم کرد. او با رنگ های چشم نواز نقاشی می کرد. تفاسیر او از واقعیت، دنیای هنر را آتش زد و هنرمندان و طراحان را تا به امروز تحت تأثیر قرار داد.با کپی برداری مستقیم از هنرمندان ژاپنی، آثار ون گوگ به آنچه امروز می شناسیم تبدیل شد.او در مورد این نفوذ واضح بود. او در نامه ای به برادرش تئو نوشت: تمام کارهای من تا حدی بر اساس هنر ژاپنی است.کلمه دیگری در زبان چینی برای کپی وجود دارد: shanzhai (山寨). این به انگلیسی به عنوان «جعلی» ترجمه شده است، اما مانند بسیاری از کلمات چینی، ترجمه‌ای وجود ندارد. شانزای در لغت به معنای دژ کوهستانی است. این کلمه یک نئولوژیسم است، یک اختراع اخیر، الهام گرفته از یک رمان معروف که در آن قهرمانان داستان در یک قلعه کوهستانی پنهان می شوند تا با یک رژیم فاسد مبارزه کنند. محصولات شانزای بازیگوش هستند و توجه را به این واقعیت جلب می کنند که اصلی نیستند و خلاقیت سازندگان خود را به نمایش می گذارند.رمان محبوب شانزای هری پاتر و عروسک چینی را در نظر بگیرید. در آن، هری به چین می رود تا ولدمورت و همتای چینی ولدمورت را متوقف کند. تظاهر به اصل بودن ندارد. تقلبی بودنش را بازی می‌کند: هری به روانی چینی صحبت می‌کند، اما در خوردن غذا با چاپستیک مشکل دارد.به راحتی می‌توان به شانزای به‌عنوان یک خصلت چینی فکر کرد، اما مشابه‌هایی در فرهنگ غربی وجود دارد. یکی از آنها به ویژه یکی از اجزای اصلی جامعه طراحی است: طراحی مجدد ناخواسته.طراحی مجدد ناخواسته ایده های یک طراح را برای بهبود یک وب سایت یا برنامه معروف نشان می دهد. آن‌ها از تغییرات زیبایی‌شناختی تک صفحه‌ای (مانند این برداشت در اینستاگرام) تا مطالعات موردی عمیق در UX، IA  و طراحی محتوا (مانند طراحی مجدد برنامه تلفن همراه Gmail) را شامل می‌شوند.بازطراحی‌های ناخواسته عناصر بصری نسخه اصلی را به عنوان نقطه شروع کپی می‌کنند، سپس آن عناصر را تغییر می‌دهند تا چیزی جدید تولید کنند. مانند ون گوگ که آیزن را ردیابی می کند، طراحان فقط با کپی کردن می‌توانند تکنیک‌ها و رویکردهای جدید را انتخاب کنند. اما وقتی یک طراح بر روی نسخه اصلی اصلاحیه می‌زند، می‌تواند چیزی جدید و الهام بخش خلق کند.جامعه طراحی رابطه پیچیده‌ای با طراحی مجدد ناخواسته دارد. از یک طرف، آنها ستون اصلی طراحان جوان با استعدادی هستند که به دنبال نشان دادن توانایی خود در تفکر انتقادی در مورد طراحی و به کارگیری مهارت های خود هستند. شرکت‌ها از طراحی مجدد ناخواسته استفاده کرده‌اند تا خود را به عنوان رهبر قرار دهند: در سال ۲۰۰۳، signals (خلق ابزار مدیریت پروژه محبوب Basecamp) طراحی‌های مجدد PayPal، Google و FedEx را ایجاد کرد که مورد تحسین منتقدان قرار گرفت: طراحی مجدد داشبورد ماشین آنلاین آنها می‌تواند برای اتومبیل‌هایی که TiVo برای تلویزیون انجام داد» جیسون کوتکه اعلام کرد:در موارد نادر، طراحی‌های مجدد ناخواسته به طرح‌های درخواستی تبدیل می‌شوند. در سال ۲۰۱۸، آدام فیشر طراحی مجددی از علائم دیجیتالی سیستم AirTrain در فرودگاه بین‌المللی جان اف کندی منتشر کرد. آژانسی که بر AirTrain نظارت دارد، طراحی مجدد را دید و Fisher-Cox را برای اجرای آن استخدام کرد.از سوی دیگر، طراحی مجدد ناخواسته اغلب با تحقیر دیده می شود. در مقاله‌ای در سال 2013 با عنوان «طراحی مجدد ناخواسته خود را برای خود نگه دارید»، اریک کارجالووتو استدلال کرد که بدون اذعان به محدودیت‌ها و مشوق‌هایی که یک طراحی اصلی را هدایت می‌کنند، طراحی مجدد «کاملاً مسخره» است. کسانی که روی بازطراحی‌های ناخواسته کار می‌کنند «باید این کار را بهتر از هدر دادن وقت خود بدانند». اقدامات بی‌شماری دیگر علیه طراحی مجدد ناخواسته در سراسر اینترنت وبلاگ‌های طراحی وجود دارد.در سال 2011، طراحی مجدد ناخواسته اندی راتلج در نیویورک تایمز توجه کارشناسان طراحی را در پست‌های وبلاگ و توییت‌های بی‌شماری به خود جلب کرد.اما اگر آنها با نتیجه‌گیری‌های راتلج مخالف بودند، بسیاری از رویکرد او دفاع کردند. Stijn Debrouwere می‌نویسد: «گاهی اوقات ما نیاز داریم که دیوانه شویم و چیزهایی را مسخره کنیم که نمی‌توانند مطلقاً به شکل خالص خود کار کنند، زیرا «یک بازنگری کامل ممکن است چیزی باشد که برای حرکت به جلو نیاز داریم.» حتی Khoi Vinh، مدیر طراحی سابق در تایمز، از این عمل حمایت کرد: «بازطراحی‌های ناخواسته فوق‌العاده، سرگرم‌کننده و مفید هستند و امیدوارم طراحان هرگز از انجام آن دست نکشند».رویکرد شانزای کپی کردن - یادگیری، اختراع، اظهار نظر، بیانیه - درست در غرب مانند چین است.داستان ششمکپی کردن می تواند آموزنده، چالش برانگیز، فریبنده یا انقلابی باشد. برای من کپی کردن لذت بخش است.وقتی جوان بودم دوست داشتم از روی نقاشی‌ها کپی برداری کنم. مادرم برای من کاغذ شفاف می‌خرید و من شخصیت‌های کتاب‌های مصور را خط به خط کپی می‌کردم. پس کشیدن کاغذ از طرح اصلی با عجله‌ میگفتم. من اینو کشیدم! با دست من! مطمئناً کپی بود، اما یک بار که نامم را در گوشه ای امضا کردم، کپی من بود.این روزها، تقریباً همه چیز محافظت خودکار از کپی وجود دارد. شما نمی توانید به راحتی فیلم‌ها و سریال‌های Netflix را کپی کنید، کتاب های Kindle را کپی کنید یا Adobe Creative Cloud را تورنت (torrent) کنید. اما طرح ها متفاوت است. برای کپی کردن یک طرح، تنها چیزی که نیاز دارید کاغذ و کاربُن جهت بازطراحی است.در واقع، شما حتی نیازی به کشیدن نقاشی ندارید. گوشی خود را بیرون بیاورید، عکس بگیرید و آن را در صفحه Pinterest خود ذخیره کنید. می‌توانید از یک انتخابگر رنگ برای استخراج سایه دقیق از طرح استفاده کنید، از ابزار اندازه‌گیری فیزیکی یا دیجیتالی برای بدست آوردن ابعاد پیکسل کامل استفاده کنید و از WhatTheFont برای یادگیری حروف در طراحی استفاده کنید.اگر به یک وب‌سایت نگاه می‌کنید، فقط می‌توانید روی «مشاهده منبع» کلیک کنید و تمام تصمیم‌های طراحی را با جزئیات مشخص ببینید. این دقیقاً همان راهی بود که من از ردیابی کتاب های مصور به یک طراح تبدیل شدم: طرح هایی را از وب سایت هایی که دوست داشتم کپی کردم و آنها را در وبلاگ Xanga خود قرار دادم.کپی کردم چون تونستمدر اولین کار طراحی ام، بی وقفه کپی می کردم. من با دوستانم یک مجله موسیقی درست کرده بودم و سعی کردم طرح‌بندی‌هایی را که در مگ‌های مورد علاقه‌ام می‌دیدم، بازسازی کنم. وایرد منبع دائمی الهام بود: من روی تایپوگرافی آنها وسواس داشتم. وقتی فهمیدم که آنها از Joshua Darden&#x27;s Freight Micro استفاده می کنند، مجله ما را نیز تغییر دادم تا از آن استفاده کنم.کپی کردن به من کمک کرد تا به عنوان یک طراح بدون نیاز به رفتن به مدرسه طراحی پیشرفت کنم. برای بسیاری از افرادی که برای برنامه های طراحی در سطح کالج بسیار جوان هستند، یا بدون ابزاری برای حضور در این مدارس یا بوت کمپ ها، کپی کردن همین کار را انجام می دهد.و سپس، وقتی افرادی مانند من در طراحی حرفه ای به پایان می رسند، متوجه می شویم که کپی کردن هنوز مفید است. من رنگ ها را از وب سایت های بازاریابی اپل چک می کنم. من پالت های رنگی خود را از نمونه های طراحی متریال گوگل شروع می کنم. من از طراحی مجدد فیس بوک اسکرین شات گرفته و از نو خلق می کنم.من دوست ندارم ون گوگ طراحی باشم، در رویکردم به کپی کردن، در سطح استالمن یا کارمک باشم، حتی یک صدم توانایی استیو جابز برای دزدی هنرمندانه یا حضور در آن را داشته باشم. به هیچ وجه قابل مقایسه با چارلز یا ری ایمز. اما من مطمئناً می توانم همه کارهای آنها را کپی کنم. من می توانم طرز فکر، روند و طرح آنها را کپی کنم.من می‌توانم فکس‌میل‌های ارزان و در مقیاس کوچک، fangzhipin بسازم تا کیفیت اصلی را نشان دهم. من می‌توانم کپی‌های دقیق، fuzhipin کامل پیکسلی بسازم تا یاد بگیرم نسخه‌های اصلی و سازندگان آنها چگونه کار می‌کنند. یا می‌توانم شانزهای، طراحی‌های ناخواسته، اظهار نظر و ریف کردن کارهای دیگران ایجاد کنم. همه این کپی ها نقش مهمی در روند طراحی دارند.فرقی نمی‌کند کپی کردن آن ارزشمند باشد یا بی‌ارزش، چه فکر کنید کپی‌ها بخش ارزشمندی از جامعه طراحی هستند یا یک بلا، از نرم‌افزار، سخت‌افزار، وب‌سایت‌ها و برنامه‌هایی استفاده می‌کنید که وجودشان را مدیون کپی کردن هستند.تا زمانی که طراحی وجود داشته باشد، کپی هم وجود خواهد داشت.منبع:https://matthewstrom.com/writing/copying/</description>
                <category>danny</category>
                <author>danny</author>
                <pubDate>Wed, 24 Jul 2024 22:43:09 +0330</pubDate>
            </item>
                    <item>
                <title>معرفی کتاب طراحی سیستم‌های نرم‌افزاری ۱</title>
                <link>https://virgool.io/@dany_kh/%D9%85%D8%B9%D8%B1%D9%81%DB%8C-%DA%A9%D8%AA%D8%A7%D8%A8-%D8%B7%D8%B1%D8%A7%D8%AD%DB%8C-%D8%B3%DB%8C%D8%B3%D8%AA%D9%85-%D9%87%D8%A7%DB%8C-%D9%86%D8%B1%D9%85-%D8%A7%D9%81%D8%B2%D8%A7%D8%B1%DB%8C-%DB%B1-mox8la8vlwz8</link>
                <description>معرفیلینک دانلود نسخه الکترونیکی.لینک خرید نسخه فیزیکی.به‌عنوان یک مهندسی نرم‌افزار تا حالا شده که یک مسئول طراحی یک سامانه نرم‌افزاری خاص مثلاً طراحی یک برنامه چت گروهی یا یک برنامه با میلیون‌ها کاربر شده باشید؟تا حالا شده از شما سؤال شده باشه که در پشت‌صحنه پلتفرم‌های معروف مثل اینستاگرام و تلگرام و یوتیوب چه می‌گذرد و به چه صورت کار می‌کنند؟آیا شده که توی مصاحبه‌های استخدامی سؤالاتی مربوط به طراحی یک سامانه نرم‌افزاری خاص مثل طراحی گوگل درایو از شما بپرسند؟قطعاً در بیشتر موارد پاسخ به سؤال مثبت هست.حالا کتابی می‌خواهم معرفی کنم مربوط به این موضوع هست و اولین‌بار هست که به فارسی ترجمه میشه:در هر فصل این کتاب به طراحی سیستم‌هایی زیر پرداخته شده هست.فصل ۱: Scale From Zero To Millions Of Users در این فصل به بررسی مقیاس‌پذیری یک اپلیکیشن جهت پاسخ دهی به میلیون‌ها کاربرِ در حال استفاده همزمان پرداخته شده است.فصل ۲: Back-Of-The-Envelope Estimation در این فصل به بررسی روش تخمین و محاسبات و برآورد منابع و هزینه‌ها جهت پیاده سازی یک سامانه نرم‌افزاری پیچیده پرداخته شده است.فصل ۳: A Framework For System Design Interviews در فصل سوم به نکات مهم و مهارت‌های نَرم در مصاحبه طراحی سامانه‌های نرم‌افزاری پرداخته شده است.فصل ۴: Design A Rate Limiter در این فصل به بررسی یک محدود کننده نرخ پرداخته شده و انواع روش‌های پیاده‌سازی آن مورد نقد و بررسی قرار گرفته است.فصل ۵: Design Consistent Hashing در این فصل به الگوریتم Consistent Hash پرداخته شده است که این الگوریتم در سیستم‌های توزیع شده بسیار پرکاربرد می‌باشد.فصل ۶: Design A Key-Value Store در این فصل یک ذخیره‌ساز یا پایگاه داده کلید-مقدار مورد بررسی قرار گرفته و پیاده‌سازی شده است.فصل ۷: Design A Unique Id Generator In Distributed Systems در این فصل یک تولید کننده شناسه در سیستم‌های توزیع پرداخته شده است.فصل ۸: Design A Url Shortener در اين فصل، به يک سؤال مصاحبه طراحی سیستمی جالب و کلاسیک پرداخته شده و آن هم طراحی يک سرويس کوتاه کننده  URL مانند  tinyurl است.فصل ۹: Design A Web Crawler در اين فصل، بر طراحی خزنده وب Web Crawler تمرکز شده است. خزنده وب يا  web crawler که بهعنوان يک ربات يا  spiderشناخته میشود که طرز گستردهای توسط موتورهای جستجو برای کشف محتوای جديد يا بهروز شده در وب استفاده می‌شود. محتوا میتواند يک صفحه وب، يک تصوير، يک ويدئو، يک فايل  PDF و غیره باشد.فصل ۱۰: Design A Notification System يک سیستم اعلان يا  notificationدر سالهای اخیر به يک ويژگی بسیار محبوب برای بسیاری از برنامه‌ها تبديل شده است. يک اعلان یا نوتیفیکیشن اطلاعات مهمی مانند اخبار فوری، به‌روزرسانی‌های محصول، رويدادها، پیشنهادها و غیره را به کاربر هشدار میدهد. اين مورد به بخشی ضروری از زندگی روزمره ما تبديل شده است. در اين فصل از شما خواسته میشود که يک سیستم اطلاع‌رسانی طراحی کنید.فصل ۱۱: Design A News Feed System در اين فصل از شما خواسته شده است که يک سیستم خوراک خبری يا فید خبررسانی که اساس يک اپلیکیشن شبکه اجتماعی است را طراحی کنید.فصل ۱۲: Design A Chat System در اين فصل به بررسی طراحی يک سیستم چت پرداخته شده است. امروزه تقريباً همه از يک برنامه چت به‌خصوص استفاده می‌کنند و روش‌های پیاده‌سازی آن در سمت سرور در این فصل توضیح داده شده است. فصل ۱۳: Design A Search Autocomplete System در این فصل به یک فاکتور بسیار مهم در پیاده سازی موتور‌های جستجو  پرداخته شده است.فصل ۱۴: Design youtube برای هر مهندس نرم‌افزاری پیاده‌سازی یک سامانه نرم‌افزاری مثل یوتیوب بسیار جاه طلبانه و شگفت‌انگیز است.فصل ۱۵: Design Google Drive در سالهای اخیر، سرويسهای ذخیره‌سازی ابری مانند Google Drive بسیار محبوب شدهاند. در اين فصل از شما خواسته‌ می‌شود تا گوگل درايو را طراحی کنید.فصل ۱۶: The Learning Continuesدر این فصل وبلاگ‌ها و منابع مهم در طراحی سامانه‌های نرم‌افزاری و سیستم‌های توزیع شده معرفی شده است.به عنوان مثال برای یک معماری مناسب در اپلیکیشن Rate Limiter الگوی زیر معرفی شده و هر جزیی از آن به طور مفصل توضح داده می‌شود.یا برای معماری تبدیل فرمت ویدیو در یوتیوب، دیاگرام پیشنهادی زیر رو داریم.یا بررسی فید در یک اپلیکشین مانند اینستاگرام معماری زیر در این کتاب پیشنهاد شده است.به طور کلی این کتاب دید عمیقی برای طراحی سامانه‌های نرم‌افزاری به مخاطب میده و بهترین حالت‌های ممکن جهت پیاده سازی معماری‌های معروف هر اپلیکیشن رو پیشنهاد میده، هر چند کتاب به بررسی مفصل در مورد این مباحث می پردازه ولی  هیچ کدام از اپلیکیشن‌های مورد رو بررسی رو در سطح کد پیاده سازی نمیکنه، البته که پیاده سازی این کار در یک کتاب غیر ممکن است.نکته جالب این هست که این کتاب ترجمه شده به صورت مجانی در این لینک قابل دانلود هست.همینطور اگر مباحث این کتاب براتون سنگین هست این کتاب یه کتاب مقدماتی هم داره که از این پست قابل بررسی و دانلود هست.لینک دانلود</description>
                <category>danny</category>
                <author>danny</author>
                <pubDate>Wed, 17 Jul 2024 18:47:36 +0330</pubDate>
            </item>
                    <item>
                <title>پاسخ دهی به ۱ میلیون درخواست فقط با ۲ گیگ رم</title>
                <link>https://virgool.io/codenevis/%D9%BE%D8%A7%D8%B3%D8%AE-%D8%AF%D9%87%DB%8C-%D8%A8%D9%87-%DB%B1-%D9%85%DB%8C%D9%84%DB%8C%D9%88%D9%86-%D8%AF%D8%B1%D8%AE%D9%88%D8%A7%D8%B3%D8%AA-%D9%81%D9%82%D8%B7-%D8%A8%D8%A7-%DB%B2-%DA%AF%DB%8C%DA%AF-%D8%B1%D9%85-zc2zg9cts4ht</link>
                <description>این مقاله نحوه عملکردی را برای مقیاس‌پذیری بک‌اند از ۵۰ هزار درخواست به ۱ میلیون درخواست (حدود ۱۶ هزار درخواست در دقیقه) با منابع محدود (۲ گیگابایت رم، ۱ هسته پردازنده و پهنای باند شبکه ۵۰-۱۰۰ مگابیت بر ثانیه) شرح می‌دهد.این مقاله فرض می‌کند که شما با بک‌اند و نوشتن API آشنایی دارید. همچنین خوب است کمی در مورد زبان برنامه نویسی Go بدانید. اما اگر هم نمی‌دانید، مشکلی نیست. هنوز هم می‌توانید مطالب را دنبال کنید، زیرا منابعی برای کمک به درک هر موضوع ارائه داده‌ام. (اگر GO را نمی‌شناسید، اینجا یک مقدمه‌ی کوتاه است)چکیده:اول، یک خط لوله‌ی مشاهده (observability pipeline) می‌سازیم که به ما در نظارت بر تمام جنبه‌های بک‌اند کمک می‌کند. سپس، تست استرس (stress testing) بک‌اند را تا تست شکست (breakpoint testing) تا زمانی که همه‌چیز در نهایت خراب می‌شود، شروع می‌کنیم.بررسی backendاجازه دهید توضیح مختصری در مورد بک‌اند ارائه دهم:این یک API مونولیتیک (monolithic) و RESTful است که با Golang نوشته شده است. با فریمورک GIN و از GORM به عنوان ORM استفاده می‌کند. از Aurora Postgres به عنوان تنها پایگاه داده اصلی خود که روی AWS RDS میزبانی می‌شود، استفاده می‌کند. بک‌اند docker شده است و ما آن را در نمونه‌ی t2.small روی AWS اجرا می‌کنیم. این نمونه دارای ۲ گیگابایت رم، پهنای باند شبکه ۵۰-۱۰۰ مگابیت بر ثانیه و ۱ هسته‌ی پردازنده است. بک‌اند احراز هویت، عملیات CRUD (ایجاد، خواندن، به‌روزرسانی، حذف)، push notification و به‌روزرسانی‌ها را ارائه می‌دهد برای به‌روزرسانی‌ها، یک اتصال وب‌سوکتی بسیار سبک‌وزن باز می‌کنیم که دستگاه را از به‌روزرسانی موجودیت‌ها مطلع می‌کند. برنامه‌ی ما بیشتر بر خواندن تمرکز دارد، اگر بخواهم نسبتی به شما بدهم، ۶۵٪ خواندن / ۳۵٪ نوشتن است.می‌توانم یک وبلاگ جداگانه در مورد اینکه چرا معماری مونولیتیک، Golang یا Postgress را انتخاب کرده‌ایم بنویسم، اما برای اینکه خلاصه‌اش را به شما بگویم، در MsquareLabs ما به «ساده نگه داشتن  و طراحی کدی که به ما امکان حرکت با سرعتی باورنکردنی را می‌دهد» اعتقاد داریم.بررسی داده‌هاقبل از هر گونه تولید بار مصنوعی (mock load generation)، ابتدا قابلیت مشاهده (observability) را در بک‌اند خود پیاده‌سازی کردم. این قابلیت شامل ردیابی (traces)، متریک‌ها (metrics)، پروفایل‌گیری (profiling) و لاگ‌ها (logs) می‌شود. این کار باعث می‌شود پیدا کردن مشکلات و تشخیص دقیق علت آن‌ها بسیار آسان شود. هنگامی که چنین نظارت قدرتمندی بر روی بک‌اند خود داشته باشید، ردیابی سریع‌تر مشکلات در محیط تولید نیز آسان‌تر خواهد بود.قبل از اینکه ادامه دهیم، اجازه دهید خلاصه‌ای از متریک‌ها، پروفایل‌گیری، لاگ‌ها و ردیابی ارائه دهم: لاگ‌ها: همه ما می‌دانیم لاگ‌ها چه هستند، آن‌ها پیام‌های متنی زیادی هستند که هنگام وقوع یک رویداد ایجاد می‌کنیم.ردیابی: این لاگ‌های ساختاریافته با قابلیت دید بالا هستند که به ما کمک می‌کنند یک رویداد را با ترتیب و زمان‌بندی صحیح کپسوله‌سازی کنیم. متریک‌ها: تمام داده‌های عددی پردازش‌شده مانند استفاده از CPU، درخواست‌های فعال و گوروتین‌های فعال (active goroutines).پروفایل‌گیری: متریکهای لحظه‌ای را برای کد ما و تأثیر آن‌ها بر روی سخت‌افزار را ارائه می‌دهد که به ما کمک می‌کند بفهمیم چه اتفاقی در حال رخ دادن است. برای اینکه درباره نحوه‌ی پیاده‌سازی observability در بک‌اند بیشتر بدانید،  این بخش را به وبلاگ دیگری منتقل کردم تا از سردرگمی خواننده جلوگیری کنم و فقط روی یک موضوع تمرکز کنیمکه آن هم بهینه‌سازی (OPTIMIZATION) است.تصویر زیر در مورد نحوه‌ی نمایش ردیابی، لاگ‌ها و متریکها است:بنابراین اکنون یک ابزار مانیتورینگ قوی + یک داشبورد مناسب برای شروع داریمشبیه‌سازی ۱۰۰۰۰۰ کاربر &quot;فقط زمانی که سرویس بک‌اند را تحت فشار شدید قرار می‌دهید، قدرتواقعی آن را پیدا می‌کنید ✨&quot; - گرافانا (Grafana) همچنین یک ابزار تست بار (load testing) را ارائه می‌دهد، بنابراین بدون فکر زیاد تصمیم گرفتم از آن استفاده کنم، زیرا فقط راه‌اندازی کمی با چند خط کد نیاز دارد و شما یک سرویس شبیه‌سازی آماده دارید.به جای دست زدن به تمام مسیرهای API، بر روی مهم‌ترین مسیرهایی تمرکز کردم که مسئول ۹۰ درصد ترافیک ما بودند.خلاصه‌ی کوتاهی در مورد k6، این یک ابزار تست مبتنی بر جاوااسکریپت و golang است، جایی که می‌توانید به سرعت رفتاری را که در نظر داردی را شبیه‌سازی و تعریف کنید. این ابزار مسئولیت تست بار را برعهده می‌گیرد. هر آنچه را که در تابع اصلی تعریف می‌کنید یک تکرار (iteration) نامیده می‌شود، k6 واحدهای کاربر مجازی (VU) متعددی را راه‌اندازی می‌کند که این تکرار را تا رسیدن به زمان یا تعداد تکرار مشخص پردازش می‌کند.هر تکرار شامل ۴ درخواست است: ایجاد تسک (Creating Task) -&gt;  به‌روزرسانی تسک (Updating Task) -&gt; دریافت تسک (Fetching the Task) -&gt; حذف تسک (Delete Task)با شروع آهسته، بیایید ببینیم برای حدود ۱۰ هزار درخواست -&gt;‌ ۱۰۰ واحد کاربر مجازی (VU) با ۳۰ تکرار -&gt; ۳۰۰۰ تکرار ‍× ۴ درخواست =&gt; که معادل ۱۲ هزار درخواست است، چطور عمل می‌کند.این کار بسیار راحت بود، هیچ نشانه‌ای از نشت حافظه، فشار بیش از حد CPU یا هر نوع گلوگاهی وجود نداشتو این عالی است!خلاصه‌ی k6 در تصویر زیر آمده است، ۱۳ مگابایت داده ارسال شده، ۸۹ مگابایت دریافت شده است و میانگین بیش از ۵۲ درخواست در ثانیه با میانگین تأخیر ۲۷۸ میلی‌ثانیه که با در نظر گرفتن اجرای همه این موارد روی یک ماشین نتیجه بدست آمده بد نیست.بیایید ۱۲ هزار درخواست را به ۱۰۰ هزار درخواست را افزایش دهیم، ۶۶ مگابایت ارسال شده، ۴۶۲ مگابایت دریافت شده، استفاده از  CPU به ۶۰ درصد و استفاده حافظه به ۵۰ درصد رسیده است و ۴۰ دقیقه طول کشید تا اجرا شود (میانگین ۲۵۰۰ درخواست در دقیقه)همه چیز خوب به نظر می رسید تا اینکه چیز عجیبی در لاگ هایمان دیدم، &quot;::gorm: Too many connections  ::&quot;، با بررسی سریع متریک‌های RDS تأیید شد که تعداد اتصالات باز به ۴۱۰ عدد رسیده است که این حداکثر تعداد مجاز برای اتصالات باز است. این مقدار توسط خود Aurora Postgres بر اساس حافظه‌ی در دسترس برای آن نمونه تنظیم می‌شود.select * from pg_settings where name=&#039;max_connections&#039;; ⇒ 410اینطور می‌توانید بررسی کنید:در واقع Postgres برای هر اتصال یک process ایجاد می‌کند که با در نظر گرفتن اینکه با هر درخواست جدید یک اتصال جدید باز می‌شود و کوئری قبلی هنوز در حال اجرا است کاری بسیار پرهزینه است. بنابراین، Postgres محدودیتی را برای تعداد اتصالات همزمان که می‌توانند باز شوند اعمال می‌کند. هنگامی که به این محدودیت رسید، هر تلاش دیگری برای اتصال به پایگاه داده برای جلوگیری از خرابی نمونه (که می‌تواند باعث از دست رفتن داده‌ها شود) مسدود می‌شود.بهینه‌سازی ۱: استخر اتصال (Connection Pooling) ⚡️استخر اتصال (Connection Pooling) یک تکنیک برای مدیریت اتصال به پایگاه داده است. این تکنیک، اتصالات باز را مجددا استفاده می‌کند و اطمینان می‌دهد که از مقدار آستانه تجاوز نمی‌کند. اگر کاربر درخواست اتصال بدهد و حداکثر تعداد اتصال رد شود، تا زمانی که یک اتصال آزاد شود یا درخواست رد شود، منتظر می‌ماند.در اینجا دو گزینه وجود دارد: استخر سمت کاربر (client-side) یا استفاده از یک سرویس جداگانه مانند pgBouncer (که به عنوان یک پروکسی عمل می‌کند). pgBouncer در واقع زمانی که در مقیاس بزرگ هستیم و یک معماری توزیع‌شده داریم که به همان پایگاه داده متصل می‌شود که گزینه بهتری است. بنابراین، برای سادگی و ارزش‌های اصلی‌مان، تصمیم گرفتیم با pooling سمت کاربر پیش برویم.خوشبختانه ORM ای  که از آن استفاده می‌کنیم (GORM) از connectionpooling پشتیبانی می‌کند، اما در لایه زیرین از database/SQL (بسته استاندارد golang ) برای مدیریت آن استفاده می‌کند.برای مدیریت این کار، روش‌های بسیار ساده‌ای وجود دارد: ‏SetMaxIdleConns -&gt; حداکثر تعداد اتصالات غیرفعال که باید در حافظه نگه داشته شود تا بتوانیم دوباره از آن‌ها استفاده کنیم (به کاهش تأخیر و هزینه باز کردن اتصال کمک می‌کند) ‏SetConnMaxIdleTime -&gt; حداکثر مدت زمانی که باید اتصال غیرفعال را در حافظه نگه داریم. ‏SetMaxOpenConns -&gt; حداکثر تعداد اتصال باز به پایگاه داده است، زیرا ما دو محیط را روی همان نمونه RDS اجرا می‌کنیم. ‏SetConnMaxLifetime -&gt; حداکثر مدت زمانی که هر اتصالی باز می‌ماند.حالا یک قدم دیگر به جلو می‌رویم، پس از ۵۰۰ هزار درخواست (۴۰۰۰ درخواست در دقیقه) در مدت ۲۰ دقیقه، سرور با مشکل مواجه شد . حالا بیایید بررسی کنیم.با نگاهی سریع به متریک‌ها مشکل شناسایی شد! استفاده از CPU و حافظه به طور ناگهانی افزایش یافته است. بار (Open Telemetry Collector) به جای container API ما، تمام CPU و حافظه را اشغال می‌کرد.بهینه‌سازی ۲: آزاد کردن منابع از بار مربوط به (Open Telemetry Collector)ما سه container درون نمونه کوچک از سرور t2 خود اجرا می‌کنیم: ‏API توسعه ‏API مرحله استقرار (Staging) ‏Alloy در واقع Alloy یک توزیع OpenTelemetry Collector منبع باز با Prometheus pipelines داخلی و پشتیبانی از متریک‌ها، لاگ‌ها، ردیابی‌ها و پروفایل کننده است.از آنجایی که بارهای زیادی را روی سرور توسعه‌مان می‌ریزیم، شروع به تولید لاگ + ردیابی با همان سرعت می‌کند و در نتیجه باعث افزایش تصاعدی استفاده از CPU و خروج شبکه می‌شود.بنابراین، مهم است که اطمینان حاصل شود alloy container هرگز از محدودیت‌های منابع عبور نمی‌کند و مانع سرویس‌های حیاتی نمی‌شود.از آنجایی که Alloy درون یک docker container اجرا می‌شود، اعمال این محدودیت آسان‌تر بود.همچنین، این دفعه لاگ‌ها خالی نبودند، چندین خطای لغو شدن context وجود داشت - دلیل آن این بود که درخواست دچار timed out شده بود و اتصال به طور ناگهانی بسته شده بود.و سپس تأخیر را بررسی کردیم، نتیجه دیوانه کننده بود! بعد از مدت معینی، میانگین تأخیر ۳۰ تا ۴۰ ثانیه بود. به لطف ردیابی‌ها (traces)، حالا می‌توانم دقیقاً مشخص کنم که چه چیزی باعث چنین تأخیرهای عظیمی شده است. سپس تأخیر را بررسی کردم که نتیجه دیوانه کننده بود 😲 بعد از یک دوره معین، متوسط ​​تأخیر 30 تا 40 ثانیه بود. به لطف ردیابی، اکنون می توانم دقیقاً مشخص کنم که چه چیزی باعث چنین تاخیرهای بزرگی شده است.کوئری‌های ما در عملیات GET بسیار کند بود، بیایید دستور EXPLAIN ANALYZE را روی این کوئری اجرا کنیم،دستور LEFT JOIN حدود ۱۴.۶ ثانیه و دستور LIMIT نیز ۱۴.۶ ثانیه دیگر طول کشید، چگونه می‌توانیم این را بهینه کنیم؟ قطعا به کمک با ایجاد فهرست (Indexing)بهینه‌سازی ۳: افزودن فهرست (Indexing)اضافه کردن فهرست (index) به فیلدهایی که اغلب در عبارات WHERE یا ORDER BY استفاده می‌شوند، می‌تواند عملکرد کوئری را تا ۵ برابر بهبود بخشد. بعد از افزودن index برای فیلدهای جدول LEFT JOIN و ORDER BY. همان کوئری قبلی حدود ۵۰ میلی‌ثانیه طول کشید. باور می‌کنید، از ۱۴.۶ ثانیه به ۵۰ میلی‌ثانیه رسید؟(اما مراقب باشید که به طور کورکورانه index اضافه نکنید، زیرا می‌تواند باعث کندی تدریجی عملیات CREATE/UPDATE/DELETE شود.)این کار همچنین اتصالات را سریعتر آزاد می‌کند و به بهبود ظرفیت کلی برای مدیریت بارهای همزمان عظیم کمک می‌کند.بهینه‌سازی ۴: اطمینان حاصل کنید که در حین تست، تراکنش‌ها block نشده باشداز لحاظ فنی این یک بهینه‌سازی نیست، بلکه یک رفع مشکل است، با این حال باید این موضوع را به خاطر داشته باشید. کد شما نباید در هنگام تست استرس، همزمان یک موجودیت (entity) را به‌روزرسانی یا حذف کند.در حین بررسی کد، یک باگ پیدا کردم که باعث می‌شد در هر درخواست، موجودیت کاربر به‌روزرسانی شود و از آنجایی که هر فراخوانی برای به‌روزرسانی (UPDATE) درون یک تراکنش اجرا می‌شد که یک قفل (LOCK) ایجاد می‌کند، تقریباً همه فراخوانی‌های UPDATE توسط فراخوانی‌های به‌روزرسانی قبلی مسدود می‌شدند.تنها همین رفع مشکل، توان عملیاتی را تا ۲ برابر افزایش داد.بهینه‌سازی ۵: رد کردن تراکنش پیش فرض GORMبه طور پیش فرض، GORM هر کوئری را درون یک تراکنش اجرا می‌کند که می‌تواند عملکرد را آهسته کند، زیرا ما یک مکانیزم تراکنش بسیار قوی داریم، احتمال اینکه تراکنشی در یک ناحیه حیاتی از دست برود تقریباً غیرممکن است (مگر اینکه کارآموز باشید! ).ما یک واسط (middleware) برای ایجاد تراکنش قبل از رسیدن به لایه مدل و یک تابع مرکزی برای اطمینان از انجام commit/rollback آن تراکنش در لایه کنترلر خود داریم.با غیرفعال کردن این مورد، می‌توانیم حداقل ۳۰ درصد افزایش عملکرد داشته باشیم.&quot;دلیل اینکه روی ۴-۵ هزار درخواست در دقیقه گیر کرده بودیم همین بود و من فکر می‌کردم این مشکل بخاطر پهنای باند شبکه‌ی لپ‌تاپم است.&quot; تمام این بهینه‌سازی‌ها منجر به افزایش ۵ برابری توان عملیاتی شد، حالا به تنهایی لپ‌تاپ من می‌تواند ترافیک ۱۲ تا ۱۸ هزار درخواست در دقیقه ایجاد کند.یک میلیون درخواست  یک میلیون درخواست حدوداً با ۱۰ تا ۱۳ هزار درخواست در دقیقه، حدود ۲ ساعت طول کشید، این کار باید زودتر انجام می‌شد، اما به دلیل راه‌اندازی مجدد Alloy(به دلیل محدودیت منابع)، تمام متریک‌ها با آن از بین رفتند.آنچه مرا شگفت‌زده کرد این بود که حداکثر استفاده از CPU در آن مدت زمان ۶۰ درصد و استفاده از حافظه فقط ۱۵۰ مگابایت بود.اینکه Golang چقدر عملکرد خوبی دارد و بار را به زیبایی مدیریت می‌کند، دیوانه‌کننده است. این زبان ردپای حافظه کمی دارد. عاشق Golang هستمهر کوئری برای تکمیل شدن ۲۰۰ تا ۴۰۰ میلی‌ثانیه طول می‌کشید، قدم بعدی کشف دلیل این زمان است، حدس من این است که connection pooling و مسدود شدن IO باعث کند شدن کوئری می‌شوند.میانگین تأخیر به حدود ۲ ثانیه کاهش یافت، اما هنوز جای زیادی برای بهبود وجود دارد.بهینه‌سازی ضمنیبهینه‌سازی ۶: افزایش محدودیت حداکثر توصیف‌گر فایلبا توجه به اینکه بک‌اند ما را در یک سیستم عامل لینوکس اجرا می‌کنیم، هر اتصال شبکه‌ای که باز می‌کنیم یک توصیف‌گر فایل (file descriptor) ایجاد می‌کند، به طور پیش فرض لینوکس این مقدار را به ازای هر process به ۱۰۲۴ محدود می‌کند که مانع رسیدن به عملکرد نهایی می‌شود.از آنجایی که ما اتصالات web-socket متعددی را باز می‌کنیم، اگر ترافیک همزمان زیادی وجود داشته باشد، به راحتی به این محدودیت برخورد می‌کنیم.‏Docker Compose یک سطح انتزاع خوبی روی آن ارائه می‌دهد:بهینه‌سازی ۷: از اضافه بار گذاشتن روی Goroutine خودداری کنید.به عنوان یک توسعه‌دهنده Go، ما اغلب Goroutine را نادیده می‌گیریم و فقط کارهای غیر بحرانی زیادی را در داخل یک Goroutine اجرا می‌کنیم، قبل از یک تابع کلمه go (برای راه اندازی Goroutine) را اضافه می‌کنیم و سپس اجرای آن را فراموش می‌کنیم، اما در شرایط بحرانی می‌تواند به یک گلوگاه تبدیل شود.برای اطمینان از اینکه هرگز  به گلوگاه تبدیل نمی‌شود، برای سرویس‌هایی که اغلب در Goroutine اجرا می‌شوند، از یک صف درون حافظه (in-memory queue) با n-worker برای اجرای یک کار استفاده می‌کنم.قدم‌های بعدیپیشرفت‌ها: انتقال از t2 به t3 یا t3a این t2 نسل قدیمی ماشین‌های چندمنظوره AWS است، در حالی که t3 و t3a، t4g نسل جدیدتر هستند. این ماشین‌ها نمونه‌های قابل تست در شرایط بحرانی (burstable) هستند که پهنای باند شبکه و عملکرد بسیار بهتری را برای استفاده طولانی‌مدت از CPU نسبت به t2 ارائه می‌دهند.درک نمونه‌های Burstableبه طور کلی AWS نوع نمونه‌های burstable را عمدتا برای کارهایی معرفی کرد که برای اکثر مواقع به ۱۰۰ درصد CPU نیاز ندارند. بنابراین، این نمونه‌ها با عملکرد پایه (۲۰ تا ۳۰ درصد) کار می‌کنند. آن‌ها یک سیستم اعتباری را نگهداری می‌کنند که هر زمان که نمونه‌های شما به CPU نیاز نداشته باشند، اعتبار مالی شما جمع و حفظ می‌شود. هنگامی که جهش CPU رخ می‌دهد، از آن اعتبارها استفاده می‌کند. این کار هزینه و اتلاف محاسبات برای AWS شما را کاهش می‌دهد.انتخاب خانواده t3a به خاطر نسبت هزینه به بازده بهتر در بین خانواده‌های نمونه‌های burstable، انتخاب خوبی است.اینجا یک بلاگ خوب برای مقایسه t2 و t3 وجود دارد.بهبود‌ها: کوئری (Query)برای بهبود سرعت، کارهای زیادی می‌توانیم روی کوئری و اسکما انجام دهیم، برخی از آن‌ها عبارتند از:- دسته‌ای کردن (Batching) رکوردهای INSERT در جداول با حجم بالای ورودی یاINSERTها- اجتناب از LEFT JOIN با غیرنرمال سازی Denormalization- لایه کش (Caching)-‏ Sharding و Partitioning پروفایل‌گیری (Profiling)قدم بعدی برای بهبود کارایی برنامه، فعال کردن profiling و کشف دقیق اتفاقات در زمان اجرا است.تست Breakpoint Testingبرای کشف محدودیت‌ها و ظرفیت سرور  Breakpoint Testing، قدم بعدی است.یادداشت پایانیاگر تا انتها خوانده‌اید، عالی است، تبریک می‌گم!منبعموارد بیشتر system-design.ir</description>
                <category>danny</category>
                <author>danny</author>
                <pubDate>Mon, 17 Jun 2024 11:52:04 +0330</pubDate>
            </item>
                    <item>
                <title>Cloud Design Patterns - Sidecar pattern</title>
                <link>https://virgool.io/codenevis/cloud-design-patterns-sidecar-pattern-tamz0nilpyqb</link>
                <description>معرفی:این متن بخشی از کتاب معماری‌های میکروسرویس ( دیزاین پترن‌های ابری ) است.برای دسترسی به نسخه فارسیِ پیش از انتشار کتاب به آدرس زیر مراجعه کنید.https://github.com/DannyRavi/cloud_software_farsiمقدمه:اجزای یک برنامه کاربردی را در یک process یا container جداگانه برای ایجاد جداسازی و کپسوله سازی قرار دهید. این الگو همچنین می تواند برنامه ها را قادر سازد که از اجزا و فناوری های ناهمگن(heterogeneous) تشکیل شده باشند.این الگوی Sidecar نامیده می شود زیرا شبیه یک کابین کناری متصل به موتور سیکلت است. در  این الگو، Sidecar به یک برنامه والد متصل شده است و ویژگی های پشتیبانی را برای برنامه ارائه می دهد. سایدکار همچنین چرخه عمر یکسانی با برنامه والد دارد و در کنار والدین ایجاد و بازنشسته(retired) می شود. الگوی Sidecar گاهی اوقات به عنوان الگوی sidekick نامیده می شود و یک الگوی تجزیه(decomposition) است.طرح صورت مسئله:برنامه ها و سرویس ها اغلب به عملکردهای مرتبط مانند monitoring, logging, configuration و networking service نیاز دارند. این وظایف جانبی را می توان به عنوان اجزا یا سرویس های جداگانه پیاده سازی کرد.اگر عملکردهای گفته شده به شدت با برنامه ادغام شوند، می توانند در همان فرآیند برنامه اجرا شوند و از منابع مشترک به صورت بهینه استفاده کنند. با این حال، این بدان معناست که آنها به خوبی ایزوله نیستند و قطع شدن یکی از این اجزا می تواند سایر اجزا یا کل برنامه را تحت تأثیر قرار دهد. همچنین، معمولاً باید با استفاده از همان زبان برنامه والد پیاده سازی شوند. در نتیجه، مؤلفه و برنامه دارای وابستگی متقابل نزدیک به یکدیگر هستند.اگر برنامه به سرویس‌هایی تجزیه شود، هر سرویس می تواند با استفاده از زبان ها و فناوری های مختلف ساخته یا نوشته شود. این حالت انعطاف‌پذیری(flexibility) بیشتری می‌دهد و به این معنی است که هر component معمولا dependencyهای خاص خود را دارد و برای دسترسی به پلتفرم زیربنایی، هر resources shared که با برنامه والد به اشتراک گذاشته شده است، به language-specific libraries  نیاز دارد. علاوه بر این، استقرار این ویژگی‌ها به عنوان سرویس‌های جداگانه می‌تواند latency را به برنامه اضافه کند. مدیریت کد و dependencyها برای این language-specific interface نیز می‌تواند پیچیدگی قابل‌توجهی را به خصوص برای hosting، deployment و management اضافه کند.راه حل:مجموعه منسجمی از taskها را با برنامه اصلی قرار دهید و آنها را در داخل process یا container خود قرار دهید و یک رابط همگن(homogeneous interface) برای platform services فراهم  کنید.یک سرویس sidecar لزوماً بخشی از برنامه نیست، بلکه به آن متصل است. هر جا که برنامه والد می رود به دنبال آن می رود. sidecarها processها یا serviceهایی را پشتیبانی می کنند که با برنامه اصلی deploy می شوند. در موتور سیکلت، sidecar به یک موتور سیکلت متصل می شود و هر موتورسیکلت می تواند sidecar مخصوص به خود را داشته باشد. به همین ترتیب، یک سرویس sidecar در سرنوشت برنامه اصلی خود سهیم است. برای هر نمونه از برنامه، یک نمونه از sidecar مستقر شده و در کنار آن میزبانی می شود.مزایای استفاده از الگوی سایدکار عبارتند از:یک sidecar از نظر runtime environment و زبان برنامه نویسی از primary application  مستقل است، بنابراین نیازی به توسعه یک sidecar برای هر زبان ندارید.سایدکار می‌تواند به resources مشابه برنامه اصلی دسترسی داشته باشد. برای مثال، یک سایدکار می‌تواند منابع سیستمی را که هم توسط سایدکار و هم برنامه اصلی استفاده می‌شود را monitor کند.به دلیل نزدیکی آن به برنامه اولیه، هیچ تأخیر قابل توجهی در برقراری ارتباط بین آنها وجود ندارد.حتی برای برنامه‌هایی که مکانیسم توسعه‌پذیری(extensibility) ارائه نمی‌دهند، می‌توانید از یک sidecar برای گسترش عملکرد با پیوست کردن آن به عنوان process خود در همان host یا sub-container برنامه اصلی استفاده کنید.الگوی سایدکار اغلب با کانتینرها استفاده می شود و به آن کانتینر سایدکار یا کانتینر کناری می گویند.مسائل و ملاحظات:نوع و نحوه deployment و packaging را که برای deploy services و processها یا کانتینرها استفاده خواهید کرد را در نظر بگیرید. کانتینرها به ویژه با sidecar pattern متناسب هستند.هنگام طراحی یک سرویس سایدکار، در مورد مکانیسم ارتباط بین فرآیندی با دقت تصمیم بگیرید. سعی کنید از فناوری‌های مبتنی بر زبان یا framework استفاده کنید، مگر اینکه الزامات عملکردی خاصی آن را غیرعملی کند.قبل از قرار دادن عملکردی در یک سایدکار، در نظر بگیرید که عملکرد مورد نظر آیا به عنوان  یک separate service  عملکرد بهتری از یک traditional daemon دارد یا خیر؟همچنین در نظر بگیرید که آیا این عملکرد می تواند به عنوان یک کتابخانه پیاده سازی شود یا با استفاده از مکانیزم توسعه سنتی، Language-specific libraries ممکن است سطح عمیق تری از یکپارچگی به همراه سربار شبکه کمتری داشته باشند.چه زمانی از این الگو استفاده کنیم؟از این الگو زمانی استفاده کنید که:برنامه اصلی شما از مجموعه ای مختلفی  از زبان ها و framework ها استفاده می کند. یک component واقع در یک سرویس sidecar می تواند توسط برنامه های کاربردی نوشته شده به زبان های مختلف با استفاده از framework های مختلف استفاده شود.یک component متعلق به یک تیم remote یا سازمان دیگری است.یک component یا feature باید در همان host برنامه قرار گیرد.شما به سرویسی نیاز دارید که lifecycle کلی برنامه اصلی شما را به اشتراک بگذارد، اما بتواند به طور مستقل به روز شود.شما به کنترل دقیقی بر resource limit برای یک resource یا component خاص نیاز دارید. برای مثال، ممکن است بخواهید مقدار حافظه استفاده شده از یک component خاص را محدود کنید. می توانید component را به عنوان یک سایدکار مستقر کنید و مصرف حافظه را مستقل از برنامه اصلی مدیریت کنید.این الگو ممکن است مناسب نباشد:زمانی که ارتباطات بین فرآیندی(interprocess) باید بهینه شود. ارتباط بین یک برنامه والد و سرویس sidecar شامل مقداری سربار است، به ویژه latency در فراخوانی‌ها و این ممکن است یک trade-off مناسب برای chatty interfaces نباشد.برای small applications که در آن هزینه resource برای deploy یک سرویس sidecar برای هر instance ارزش استفاده از مزایای isolation را ندارد.زمانی که سرویس نیاز به scale متفاوت یا مستقل از برنامه های اصلی دارد. اگر چنین است، شاید بهتر باشد که این ویژگی را به عنوان یک سرویس جداگانه اجرا کنید.مثال:الگوی sidecar برای بسیاری از سناریوها قابل استفاده است. چند مثال رایج:مورد Infrastructure API. تیم توسعه زیرساخت یک سرویس ایجاد می کند که در کنار هر برنامه کاربردی مستقر می شود، به جای یک language-specific client library برای دسترسی به زیرساخت. این سرویس به‌عنوان سایدکار بارگیری می‌شود و یک لایه مشترک برای سرویس infrastructure، از جمله logging، environment data، configuration store، discovery، health checks، و watchdog services فراهم می‌کند. سایدکار همچنین محیط host برنامه والد و process (یا container) را monitors می کند و اطلاعات را در یک سرویس متمرکز ثبت می کند.مدیریت NGINX/HAProxy: همیشه NGINX  را با یک سرویس sidecar استقرار دهید که وضعیت environment را monitor می کند، سپس فایل پیکربندی NGINX را به روز می کند و در صورت نیاز به تغییر وضعیت، فرآیند را recycles می کند.روش Ambassador sidecar: یک سرویس ambassador را به عنوان یک sidecar  مستقر(Deploy) کنید. برنامه از طریق Ambassador ارتباط می گیرد، که ثبت requestها، logging، routing و circuit breaking و سایر ویژگی های مرتبط با اتصال را مدیریت می کند.روش Offload proxy: یک پروکسی NGINX را در مقابل یک نمونه سرویس node.js قرار دهید تا محتوای فایل‌های static را برای سرویس ارائه دهد.منابع مرتبط:Ambassador patternStrangler Fig pattern - Azure Architecture Center&amp;amp;lt;br/&amp;amp;gt;Anti-corruption Layer pattern - Azure Architecture Center&amp;amp;lt;br/&amp;amp;gt;Circuit Breaker pattern - Azure Architecture Center&amp;amp;lt;br/&amp;amp;gt;Bulkhead pattern - Azure Architecture Center</description>
                <category>danny</category>
                <author>danny</author>
                <pubDate>Fri, 30 Sep 2022 20:58:16 +0330</pubDate>
            </item>
                    <item>
                <title>Cloud Design Patterns - Leader Election pattern</title>
                <link>https://virgool.io/codenevis/cloud-design-patterns-leader-election-pattern-mqo0rbtvo9ma</link>
                <description>معرفی:این متن بخشی از کتاب معماری‌های میکروسرویس ( دیزاین پترن‌های ابری ) است.برای دسترسی به نسخه فارسیِ پیش از انتشار کتاب به آدرس زیر مراجعه کنید.https://github.com/DannyRavi/cloud_software_farsiمقدمه:به کمک رای گیری/انتخاب یک نمونه از بین نمونه هایی که در یک برنامه distributed  به هم وابستگی و collaborating  دارند به عنوان مدیر و leader بقیه نمونه ها، هدف اصلی این روش است . این ایده باعث می  شود که دیگر نمونه ها با یک دیگر conflict نداشته باشند، conflict ای که باعث ایجاد اختلاف برای مصرف منابع مشترک(shared resources) می‌شود، یا به طور ناخواسته در کاری که نمونه‌های دیگر انجام می‌دهند تداخل(interfere) ایجاد می‌کنند.طرح صورت مسئله:یک cloud application معمولی وظایف زیادی دارد که به صورت هماهنگ عمل می کنند. این وظایف همگی می‌توانند نمونه‌هایی باشند که کد یکسانی را اجرا می‌کنند و نیاز به دسترسی به منابع یکسانی دارند، یا ممکن است به طور موازی با هم کار کنند تا بخش‌های جداگانه یک محاسبه پیچیده را انجام دهند.نمونه‌های هر task ممکن است برای بیشتر اوقات به طور جداگانه اجرا شوند، اما ممکن است لازم باشد اقدامات هر نمونه با نمونه دیگر نیازمند هماهنگی باشد تا اطمینان حاصل شود که آنها دچار conflict نیستند یا باعث ایجاد اختلاف برای منابع مشترک نمی‌شوند، یا به طور تصادفی در اجرای task خود دچار تداخلی با سایر نمونه‌ها ایجاد نمی‌شوند.مثلا:در یک سیستم cloud-based که horizontal scaling را پیاده‌سازی می‌کند، چندین نمونه از یک task می‌توانند همزمان با هر instance serving با کاربرهای متفاوتی اجرا شوند. اگر این نمونه‌ها در یک shared  resource قابلیت ذخیره سازی و write  داشته باشند، لازم است اقدامات آنها هماهنگ(coordinate) شود تا از بازنویسی یا ذخیره مجدد تغییرات ایجاد شده توسط سایر نمونه‌ها جلوگیری شود.اگر taskها عناصر تکی یک محاسبات پیچیده را به صورت موازی انجام می دهند، نتایج باید پس از تکمیل همه آنها جمع شوند (aggregator).نمونه‌های هر  task  منحصرد به فرد هستند، بنابراین یک leader وجود ندارد که بتواند به عنوان هماهنگ‌کننده(coordinator) یا جمع‌کننده(aggregator) عمل کند.راه حل:فقط یک نمونه task  باید انتخاب شود تا به عنوان leader عمل کند، و این نمونه باید اقدامات سایر موارد زیرمجموعه را هماهنگ(coordinate) کند. اگر همه  taskها یک کد را اجرا کنند، هر کدام می‌توانند به عنوان leader عمل کنند. بنابراین، فرآیند انتخابات(election) باید با دقت مدیریت شود تا از تصاحب همزمان دو یا چند task به عنوان leader جلوگیری شود.سیستم باید مکانیزمی قوی برای انتخاب leader فراهم کند. این روش باید با رویدادهایی مانند قطع شبکه یا process failures مقابله کند. در بسیاری از راه‌حل‌ها، task instanceهای فرعی؛ leader را از طریق نوعی روش heartbeat method یا با polling نظارت(monitor) می‌کنند. اگر leader تعیین‌شده به‌طور غیرمنتظره‌ای خاتمه یابد، یا خرابی شبکه، leader را برایsubordinate task instanceها از دسترس خارج کند، لازم است که leader جدیدی انتخاب کنند.چندین استراتژی برای انتخاب یک leader از میان مجموعه ای از وظایف در یک distributed environment شده وجود دارد، از جمله:انتخاب task instance با کمترینinstance rank  یاprocess ID.مسابقه برای به دست آوردن یک mutex مشترک و توزیع شده. اولین نمونه وظیفه ای که mutex را بدست می آورد leader است. با این حال، سیستم باید اطمینان حاصل کند که در صورت پایان یا قطع ارتباط leader با بقیه سیستم، mutex آزاد می شود تا به task instance دیگری اجازه دهد تا leader شود.پیاده سازی یکی از الگوریتم های رایج انتخاب رهبر مانند Bully Algorithm یا Ring Algorithm. این الگوریتم‌ها فرض می‌کنند که هر نامزد در انتخابات یک شناسه منحصربه‌فرد(unique ID) دارد و می‌تواند به طور قابل اعتماد با سایر نامزدها ارتباط برقرار کند.مسائل و ملاحظات:هنگام تصمیم گیری در مورد نحوه اجرای این الگو به نکات زیر توجه کنید:فرآیند انتخاب leader باید در برابر شکست های گذرا و مداوم (transient and persistent failures) مقاوم باشد.تشخیص اینکه چه زمانی leader دچار failed شده است یا  unavailable شده (مثلاً به دلیل نقص ارتباطات) باید امکان پذیر باشد. سرعت تشخیص مورد نیاز به سیستم بستگی دارد. برخی از سیستم ها ممکن است بتوانند برای مدت کوتاهی بدون leader کار کنند، که در طی آن ممکن است یک خطای گذرا برطرف شود. در موارد دیگر، ممکن است لازم باشد فوراً leader failure را تشخیص داده و یک انتخابات/election جدید راه اندازی شود.در سیستمی که horizontal autoscaling را پیاده‌سازی می‌کند، اگر سیستم کوچک(scales back) شود و برخی از منابع محاسباتی را خاموش کند، leader می‌تواند terminated شود.استفاده از یک mutex مشترک و توزیع شده یک وابستگی به سرویس خارجی ارائه دهنده mutex ایجاد می کند. سرویس یک نقطه شکست واحد را تشکیل می دهد. اگر به هر دلیلی از دسترس خارج شود، سیستم قادر به انتخاب leader نخواهد بود.استفاده از یک فرآیند اختصاصی واحد (single dedicated process) به عنوان leader یک رویکرد  خیلی ساده بوده و با این حال، اگر process با fail شود، ممکن است تاخیر قابل توجهی در هنگام restartedوجود داشته باشد. latency حاصل می تواند بر عملکرد و زمان پاسخ سایر فرآیندها تأثیر بگذارد، اگر آنها منتظر leader برای هماهنگی (coordinate) عملیات باشند.پیاده‌سازی یکی از leader election algorithm ها به صورت دستی، بیشترین انعطاف‌پذیری را برای تنظیم و بهینه‌سازی کد فراهم می‌کند.چه زمانی از این الگو استفاده کنیم؟از این الگو زمانی استفاده کنید که taskها در یک distributed application، مانند راه‌حل cloud-hosted، نیاز به هماهنگی دقیق دارند و هیچ leader دقیقی وجود ندارد.از تبدیل شدن leader به گلوگاه(bottleneck) در سیستم اجتناب کنید. هدف leader هماهنگ کردن subordinate taskهاست و لزوماً لازم نیست که خود در این کار شرکت کند - اگرچه اگر task به عنوان leader انتخاب نشود باید بتواند این کار را انجام دهد.چه زمانی نباید از این الگو استفاده کنیم؟یک leader  یا process اختصاصی وجود دارد که همیشه می تواند به عنوان leader عمل کند. برای مثال، ممکن است بتوان یک singleton process را پیاده سازی کرد که task instanceها را هماهنگ می کند. اگر این process به نوعی fail  یا unhealthy شود، سیستم می تواند آن را خاموش کرده و دوباره راه اندازی کند.هماهنگی بین taskها را می توان با استفاده از روشی سبک تر به دست آورد. به عنوان مثال، اگر چندین task instance به سادگی نیاز به دسترسی هماهنگ به یک shared resource دارند، راه حل بهتر استفاده از optimistic or pessimistic locking برای کنترل دسترسی است.معمولا راه حل‌های third-party مناسب تر است. به عنوان مثال، سرویس Microsoft Azure HDInsight (بر اساس Apache Hadoop) از سرویس ارائه شده توسط Apache Zookeeper برای هماهنگ کردن نقشه (coordinate the map) و reduce task که باعث جمع آوری و خلاصه کردن داده ها می‌شود، استفاده می‌کند.مثال:پروژه DistributedMutex در راه‌حل LeaderElection (نمونه‌ای که نشان می‌دهد این الگو در GitHub موجود است) نشان می‌دهد که چگونه می‌توان با استفاده از یک Azure Storage blob برای ارائه مکانیزمی برای اجرای یک mutex مشترک و توزیع‌شده استفاده کرد. این mutex می تواند برای انتخاب یک leader در میان گروهی از role instanceها در  Azure cloud service استفاده شود. اولین role instance که lease را به دست می آورد، به عنوان leader انتخاب می شود و تا زمانی که lease را آزاد نکند یا نتواند مجوز را تمدید کند، leader باقی می‌ماند. در صورتی که leader دیگر در دسترس نباشد، سایر role instanceها می‌توانند به monitor کردن blob lease ادامه دهند.یک blob lease یک قفل نوشتن انحصاری روی یک blob است. یک blob می تواند تنها موضوع یک lease در هر نقطه از زمان باشد. یک role instance می تواند یک lease را روی یک blob مشخص درخواست کند، و اگر هیچ role instance دیگری lease را روی همان blob lease نداشته باشد، به آن lease داده می شود. در غیر این صورت درخواست یک استثنا ایجاد می کند.برای جلوگیری از یکrole instance معیوب که lease را به طور نامحدود حفظ می کند، محدودیت مادام العمر را برای lease تعیین کنید. وقتی این مدت منقضی شد، lease در دسترس می شود. با این حال، در حالی که یک role instance یک  lease را نگه می دارد، می تواند درخواست تمدید lease را داشته باشد وleaseبرای مدت زمان بیشتری به آن اعطا می شود. اگر role instance بخواهدlease را حفظ کند، می تواند به طور مداوم این فرآیند را تکرار کند. برای اطلاعات بیشتر در مورد نحوه lease a blob مقاله؛ Lease Blob (REST API) را ببینید.کلاس BlobDistributedMutex در مثال سی شارپ زیر حاوی متد RunTaskWhenMutexAcquired است که یک role instance را قادر می‌سازد تا یک lease را روی یک blob مشخص به دست آورد. هنگامی که شی BlobDistributedMutex ایجاد می شود، جزئیات blob (نام، container و حساب ذخیره سازی) به سازنده در یک شی BlobSettings منتقل می شود (این شی یک ساختار ساده است که در کد نمونه گنجانده شده است). سازنده همچنین Task را می پذیرد که به کدی ارجاع می دهد کهrole instance باید اجرا کند در صورتی که  lease را با موفقیت در blob به دست آورد و leader انتخاب شد. توجه داشته باشید که کدی که جزئیات سطح پایین کسب lease را مدیریت می کند در یک کلاس کمکی جداگانه به نام BlobLeaseManager پیاده سازی شده است.public class BlobDistributedMutex{  ...  private readonly BlobSettings blobSettings;  private readonly Func&lt;CancellationToken, Task&gt; taskToRunWhenLeaseAcquired;  ...  public BlobDistributedMutex(BlobSettings blobSettings,           Func&lt;CancellationToken, Task&gt; taskToRunWhenLeaseAcquired)  {    this.blobSettings = blobSettings;    this.taskToRunWhenLeaseAcquired = taskToRunWhenLeaseAcquired;  }  public async Task RunTaskWhenMutexAcquired(CancellationToken token)  {    var leaseManager = new BlobLeaseManager(blobSettings);    await this.RunTaskWhenBlobLeaseAcquired(leaseManager, token);  }  ...متد RunTaskWhenMutexAcquired در نمونه کد بالا روش RunTaskWhenBlobLeaseAcquired را که در نمونه کد زیر نشان داده شده است فراخوانی می کند تا در واقع lease را بدست آورد. متد RunTaskWhenBlobLeaseAcquired به صورت ناهمزمان اجرا می شود. اگر lease با موفقیت به دست آید، role instance به عنوان leader انتخاب شده است. هدف از taskToRunWhenLeaseAcquired نماینده انجام کاری است که سایر role instance را هماهنگ می کند. اگر lease تملک نشود، role instance دیگری به عنوان رهبر انتخاب شده است و  role instance فعلی تابع باقی می ماند. توجه داشته باشید که روش TryAcquireLeaseOrWait یک روش کمکی است که از شی BlobLeaseManager برای به دست آوردن lease استفاده می کند.private async Task RunTaskWhenBlobLeaseAcquired(    BlobLeaseManager leaseManager, CancellationToken token)  {    while (!token.IsCancellationRequested)    {      // Try to acquire the blob lease.      // Otherwise wait for a short time before trying again.      string leaseId = await this.TryAcquireLeaseOrWait(leaseManager, token);      if (!string.IsNullOrEmpty(leaseId))      {        // Create a new linked cancellation token source so that if either the        // original token is canceled or the lease can&#x27;t be renewed, the        // leader task can be canceled.        using (var leaseCts =          CancellationTokenSource.CreateLinkedTokenSource(new[] { token }))        {          // Run the leader task.          var leaderTask = this.taskToRunWhenLeaseAcquired.Invoke(leaseCts.Token);          ...        }      }    }    ...  }یک task آغاز شده توسط leader نیز به صورت ناهمزمان اجرا می شود. در حالی که این کار در حال اجرا است، روش RunTaskWhenBlobLeaseAcquired نشان داده شده در نمونه کد زیر به صورت دوره ای سعی می کند lease را تمدید کند. این کمک می کند تا اطمینان حاصل شود که role instance به عنوان leader باقی می ماند. در راه حل نمونه، تاخیر بین درخواست های تمدید کمتر از زمان مشخص شده برای مدت lease است تا از انتخاب role instance دیگری به عنوان leader جلوگیری شود. اگر تمدید به هر دلیلی ناموفق باشد، کار لغو می شود.اگر lease تمدید نشد یا کار لغو شد (احتمالاً در نتیجه خاموش شدن role instance)، lease آزاد می شود. در این مرحله، این یا role instance دیگری ممکن است به عنوان leader انتخاب شود. استخراج کد زیر این بخش از فرآیند را نشان می دهد.private async Task RunTaskWhenBlobLeaseAcquired(    BlobLeaseManager leaseManager, CancellationToken token)  {    while (...)    {      ...      if (...)      {        ...        using (var leaseCts = ...)        {          ...          // Keep renewing the lease in regular intervals.          // If the lease can&#x27;t be renewed, then the task completes.          var renewLeaseTask =            this.KeepRenewingLease(leaseManager, leaseId, leaseCts.Token);          // When any task completes (either the leader task itself or when it          // couldn&#x27;t renew the lease) then cancel the other task.          await CancelAllWhenAnyCompletes(leaderTask, renewLeaseTask, leaseCts);        }      }    }  }  ...}متد KeepRenewingLease یکی دیگر از روش های کمکی است که از شی BlobLeaseManager برای تمدید lease استفاده می کند. متد CancelAllWhenAnyCompletes وظایف مشخص شده به عنوان دو پارامتر اول را لغو می کند. نمودار زیر استفاده از کلاس BlobDistributedMutex را برای انتخاب leader و اجرای task ای که عملیات را هماهنگ می کند، نشان می دهد.مثال کد زیر نحوه استفاده از کلاس BlobDistributedMutex را در نقش worker نشان می دهد. این کد بر روی bolb به نام MyLeaderCoordinatorTask در lease&#x27;s container در development storage، مجوز می‌گیرد و مشخص می‌کند که اگر role instance به عنوان leader انتخاب شود، کد تعریف‌شده در متد MyLeaderCoordinatorTask باید اجرا شود.var settings = new BlobSettings(CloudStorageAccount.DevelopmentStorageAccount,  &quot;leases&quot;, &quot;MyLeaderCoordinatorTask&quot;);var cts = new CancellationTokenSource();var mutex = new BlobDistributedMutex(settings, MyLeaderCoordinatorTask);mutex.RunTaskWhenMutexAcquired(this.cts.Token);...// Method that runs if the role instance is elected the leaderprivate static async Task MyLeaderCoordinatorTask(CancellationToken token){  ...}در مورد کد نمونه بالا به نکات زیر توجه کنید: یک blob یک نقطه به شدت failure است. اگر سرویس blob در دسترس نباشد، یا غیر قابل دسترسی باشد، leader نمی تواند lease را تمدید کند و هیچ role instance دیگری نمی تواندlease را به دست آورد. در این صورت، هیچ role instance نمی تواند به عنوان leader عمل کند. با این حال، سرویس blob به گونه ای طراحی شده است که انعطاف پذیر باشد، بنابراین شکست کامل سرویس blob بسیار بعید در نظر گرفته می شود.اگر task ای که توسط leader انجام می شود متوقف شود، leader ممکن است به تمدید lease ادامه دهد و از گرفتن lease و به عهده گرفتن نقش leader به منظور هماهنگ کردن task ها جلوگیری کند. در دنیای واقعی، health  بودن  leader باید در فواصل زمانی مکرر بررسی شود.روند انتخابات/election غیر قطعی است. شما نمی توانید هیچ فرضی در مورد اینکه کدام role instance  در نهایت  blob lease را به دست می آورد و leader می شود، ندارید.همیشه blob مورد استفاده به عنوان هدف blob lease نباید برای هیچ هدف دیگری استفاده شود. اگر یک role instance تلاش کند داده ها را در این blob ذخیره کند، این داده ها قابل دسترسی نخواهند بود مگر اینکه role instance یک  leader باشد و blob lease را نگه دارد.مراحل بعدی:راهنمایی زیر ممکن است هنگام اجرای این الگو نیز مرتبط باشد:این الگو دارای نمونه کاربردی قابل دانلود می باشد.راهنمایAutoscaling Guidance. با تغییر load روی برنامه، می‌توان نمونه‌های task host را شروع و متوقف کرد. Autoscaling می تواند به حفظ توان و عملکرد در زمان اوج پردازش کمک کند.راهنمای پارتیشن بندی(Compute Partitioning Guidance) را محاسبه کنید. این راهنما نحوهallocate task به host ها در یک سرویس ابری را توضیح می دهد به گونه ای که به حداقل رساندن هزینه های جاری و حفظ scalability، performance، در availability و امنیت سرویس کمک می کند.الگویTask-based Asynchronous pattern..مثالی که Bully Algorithm را نشان می دهد.مثالی که Ring Algorithm را نشان می دهد.استفاده از Apache Curator یک کتابخانه client برای Apache ZooKeeper.مقاله Lease Blob (REST API) در MSDN.</description>
                <category>danny</category>
                <author>danny</author>
                <pubDate>Fri, 30 Sep 2022 19:48:56 +0330</pubDate>
            </item>
                    <item>
                <title>Cloud Design Patterns - Gateway Routing pattern</title>
                <link>https://virgool.io/@dany_kh/cloud-design-patterns-gateway-routing-pattern-swkawy5gliac</link>
                <description>در این الگو باید requestها را با استفاده از یک endpoint به چندین سرویس یا چندین instance از سرویس هدایت کنید. این الگو زمانی مفید است که می خواهید:چندین سرویس را در یک endpoint واحد نشان دهید و بر اساس request به سمت سرویس مورد نظر برویم.چندین instance از یک سرویس را در یک endpoint برای load balancing یا availability در  قرار دهیم.نسخه‌های مختلف یک سرویس را در یک endpoint و ترافیک مسیر در نسخه‌های مختلف نشان دهیم.طرح صورت مسئله:هنگامی که یک client نیاز به استفاده چندین سرویس دارد(چندین instance از یک سرویس یا ترکیبی از سرویس‌های مختلف) در این حالت client باید از وضعیت ارتباطی سرویس ها آگاه باشد. به عنوان مثال سناریوهای زیر را در نظر بگیرید.یک - Multiple disparate services ( چندین سرویس متفاوت) :  یک برنامه تجارت الکترونیک (e-commerce application) ممکن است خدماتی مانند جستجو، بررسی، سبد خرید، تسویه حساب و تاریخچه سفارش ارائه دهد. هر سرویس دارای یک API متفاوت است که کلاینت باید با آن تعامل داشته باشد و کلاینت باید در مورد نحوه ارتباطی هر endpoint برای اتصال به سرویس ها بداند. اگر یک API تغییر کند، کلاینت نیز باید update شود. اگر یک سرویس را به دو یا چند سرویس جداگانه تغییر دهید، کد باید هم در سرویس و هم در کلاینت تغییر کند.دو - Multiple instances of the same service (چندین نمونه از یک سرویس): سیستم می تواند نیاز به اجرای چندین instance از یک سرویس در جایی مشابه یا متفاوت داشته باشد. اجرای چندین instance را می توان برای اهداف load balancing یا برای برآوردن نیازهای   availability انجام داد. هر بار که یک instance برای مطابقت با  تعداد درخواست‌های بالا یا پایین روی application تغییر می‌کند در این حالت client باید update شود.سه - Multiple versions of the same service (چندین ورژن از یک سرویس) : به عنوان بخشی از استراتژی deployment، ورژن های جدید یک سرویس را می توان در کنار ورژن های موجود deploy کرد که این به عنوان استقرار سبز آبی شناخته می شود. در این سناریوها، client باید هر بار که تغییراتی در درصد ترافیک هدایت شده به نسخه جدید و endpoint موجود ایجاد می‌شود، به‌روزرسانی  شود.راه حل:یک gateway در جلوی مجموعه ای از برنامه ها، سرویس ها، deploymentها قرار دهید. از مسیریابی لایه ۷ اپلیکیشن برای مسیریابی request به instance های مناسب استفاده کنید.با استفاده از این الگو، برنامه client فقط باید در مورد یک endpoint واحد بداند و با یک endpoint واحد ارتباط برقرار کند. موارد زیر نشان می‌دهد که چگونه الگوی gateway routing به سه سناریویی که در بخش طرح صورت مسئله شده‌اند، می‌پردازد.روش Multiple disparate servicesالگوی gateway routing در این سناریو که یک client  از چندین سرویس را استفاده می کند مناسب است. اگر یک سرویس یکپارچه، تجزیه یا جایگزین شود، client لزوماً نیازی به updating ندارد و می‌تواند به requestهایی روی gateway ادامه دهد و فقط مسیریابی تغییر می‌کند.یک gateway همچنین این امکان را می دهد که  backend service را از کلاینت ها abstract کنید و به شما این امکان را می دهد که فراخوانی‌های client را ساده نگه دارید و در عین حال تغییرات را در سرویس های backend در پشت gateway کنترل کنید.  فراخوانی‌های client را می‌توان به هر سرویس یا سرویسی که برای مدیریت رفتار مورد انتظار client نیاز دارد هدایت کرد و  این امکان را می‌دهد که سرویس را در پشت gateway بدون تغییر در سمت client به راحتی؛ اضافه، تقسیم و سازماندهی مجدد کنید.روش Multiple instances of the same serviceکلید واژه Elasticity کلمه بسیار مهمی در رایانش ابری است. سرویس‌ها را می توان برای پاسخگویی به تقاضای فزاینده زیاد (spun up) کرد و یا زمانی که تقاضا کم است برای صرفه جویی در هزینه ها کاهش (spun down) داد. پیچیدگی ثبت و لغو ثبت service instance در gateway خلاصه  شده است. client از افزایش یا کاهش تعداد serviceها بی اطلاع است.همیشه Service instances ها می توانند در یک جا یا چند جا روی سرورهای مختلف مستقر شوند. الگوی Geode pattern توضیح می‌دهد که چگونه deployment چند ناحیه/node/ سرور و ... می‌تواند latency را بهبود بخشد و availability بودن یک سرویس را افزایش دهد.روش Multiple versions of the same serviceاین الگو را می توان برای deployment استفاده کرد و این امکان را می دهد که نحوه به روز رسانی به کاربران را مدیریت کنید. هنگامی که یک نسخه جدید از سرویس شما مستقر می شود، می توان آن را به موازات نسخه موجود مستقر کرد. مسیریابی به شما امکان می‌دهد تا کنترل کنید چه نسخه‌ای از سرویس به مشتریان ارائه می‌شود، و به شما این امکان را می‌دهد که از استراتژی‌های انتشار مختلف استفاده کنید، چه به‌روزرسانی‌های incremental، parallel یا complete rollouts. هر مشکلی که پس از استقرار سرویس جدید مشاهده شود، می‌تواند به سرعت با ایجاد یک تغییر پیکربندی در gateway، بدون تأثیر بر کلاینت‌ها، بازگردانده شود.مسائل و ملاحظات:سرویس gateway می تواند یک نقطه failure را ایجاد کند. مطمئن شوید که به درستی طراحی شده است تا نیازهایavailability بودن برنامه را برآورده کند. قابلیت انعطاف پذیری(resiliency) و تحمل خطا را در اجرا در نظر بگیرید.سرویس gateway می تواند یک گلوگاه(bottleneck) ایجاد کند. اطمینان حاصل کنید که دروازه عملکرد مناسبی برای handle کردن load دارد و به راحتی می تواند مطابق با انتظارات  scale مقیاس شود.تست load را در برابر دروازه انجام دهید تا مطمئن شوید که خرابی های زنجیره‌ای و دنباله دار برای سرویس ها ایجاد نمی کند.مسیریابی Gateway در شبکه در لایه سطح 7 است که می تواند بر اساس IP، port، header یا URL باشد.به طور کلی Gateway service می تواند global یا regional ای باشد. Azure Front Door یک global gateway  است، در حالی که Azure Application Gateway به صورت regional است. اگر راه حل شما به deployment service به صورت  multi-region نیاز دارد، از یک global gateway استفاده کنید. اگر workload به شکل  regional دارید که به کنترل دقیق نحوه balance ترافیک نیاز دارد از Application Gateway استفاده کنید. به عنوان مثال؛ وقتی می خواهید ترافیک بین ماشین های مجازی را balance کنید.سرویس gateway یک public endpoint برای سرویس‌هایی است که در جلو آن قرار دارد. محدود کردن دسترسی public network به backend services را در طراحی در نظر بگیرید آن هم فقط به صورت  ایجاد دسترسی به سرویس‌ها فقط از طریق gateway یا از طریق یک private virtual network.چه زمانی از این الگو استفاده کنیم؟یک client نیاز به استفاده از چندین سرویس دارد که در پشت یک gateway قابل دسترسی است.وقتی که می خواهیم برنامه های client را با استفاده از یک endpoint ساده کنید.وقتی که  requestها را از externally addressable endpoints به internal virtual endpoints هدایت یا مسیردهی کنید، مانند قرار دادن پورت‌های یک VM برای cluster کردن آدرس‌های IP مجازی.یک client باید سرویس‌هایی را که در چندین ناحیه مختلف (فیزیکی/مجازی) اجرا می شود برای رسیدن به latency یا  availability مناسب، استفاده کند.یک client باید تعداد مختلفی از service instanceها را مورد استفاده قرار دهد.وقتی که می خواهیم یک deployment strategy را پیاده سازی کنیم که در آن clientها به چندین ورژن از سرویس به طور همزمان دسترسی داشته باشند.مثال:با استفاده از Nginx به عنوان router؛ مثال زیر یک فایل پیکربندی ساده برای سروری است که درخواست‌های برنامه‌های موجود در virtual directoriesهای مختلف را به ماشین‌های مختلف در backend هدایت می‌کند.server {    listen 80;    server_name domain.com;    location /app1 {        proxy_pass http://10.0.3.10:80;    }    location /app2 {        proxy_pass http://10.0.3.20:80;    }    location /app3 {        proxy_pass http://10.0.3.30:80;    }}برای پیاده سازی الگوی gateway routing می توان از خدمات Azure زیر استفاده کرد:An Application Gateway instance, which provides regional layer-7 routing.An Azure Front Door instance, which provides global layer-7 routing. منابع  مرتبط:Backends for Frontends patternGateway Aggregation patternGateway Offloading pattern</description>
                <category>danny</category>
                <author>danny</author>
                <pubDate>Tue, 27 Sep 2022 13:51:25 +0330</pubDate>
            </item>
                    <item>
                <title>Cloud Design Patterns - Gateway Offloading pattern</title>
                <link>https://virgool.io/@dany_kh/cloud-design-patterns-gateway-offloading-pattern-cruveu9lm1v5</link>
                <description>عملکرد specialized service functionality را به صورت یک پروکسی gateway بارگیری کنید. این الگو می‌تواند توسعه برنامه را با انتقال shared service functionality، مانند استفاده از گواهی‌های SSL، از سایر بخش‌های برنامه به درون gateway ساده کند.طرح صورت مسئله:برخی از ویژگی‌ها معمولاً در چندین سرویس استفاده می‌شوند و این ویژگی‌ها نیاز به پیکربندی، مدیریت و نگهداری دارند. یک سرویس توزیع شده(distributed) به صورت shared یا specialized  با هر deploy شدن مجدد برنامه administrative overhead و خطای deployment  ا را افزایش می دهد .. هرگونه به‌روزرسانی برای یک ویژگی shared باید در همه سرویس‌هایی که آن ویژگی را به اشتراک می‌گذارند، اجرا شود.مدیریت صحیح مسائل امنیتی (تأیید اعتبار رمز، رمزگذاری، مدیریت گواهینامه SSL) و سایر task پیچیده می تواند به اعضای تیمی نیازمند شود  که مهارت های بسیار تخصصی داشته باشند. به عنوان مثال، گواهی مورد نیاز یک برنامه کاربردی باید پیکربندی و در تمام نمونه های برنامه مستقر شود. با هر استقرار جدید، گواهی باید مدیریت شود تا از منقضی نشدن آن اطمینان حاصل شود. هر گواهی متداول که به زودی منقضی می شود باید در هر استقرار برنامه به روز، آزمایش و تأیید شود.سایر سرویس‌های رایج مانند authentication, authorization, logging, monitoring  یا throttling ممکن است برای پیاده‌سازی و مدیریت در تعداد زیادی از deploymentها دشوار باشد. شاید بهتر باشد که این نوع عملکرد را یکپارچه کنید تا سربار و احتمال خطا کاهش یابد.راه حل:برخی از ویژگی ها را در یک gateway بارگذاری کنید، به ویژه نگرانی هایی مانند مدیریت گواهی، احراز هویت، خاتمه SSL، نظارت، ترجمه پروتکل یا throttling.نمودار زیر gateway ای را نشان می دهد که اتصالات SSL ورودی را خاتمه می دهد. داده‌ها را از طرف درخواست‌کننده اصلی از هر سرور HTTP بالادست gateway درخواست می‌کند.مزایای این الگو عبارتند از:توسعه serviceها را با حذف نیاز به توزیع و نگهداری منابع پشتیبانی، مانند گواهی‌های وب سرور و پیکربندی برای وب‌سایت‌های امن، ساده کنید. پیکربندی ساده‌تر منجر به مدیریت و مقیاس‌پذیری آسان‌تر می‌شود و ارتقای serviceها را ساده‌تر می‌کند.به تیم‌های تخصصی اجازه دهید تا ویژگی‌هایی را اجرا کنند که به  تخصصی خاصی مانند امنیت نیاز دارند. این به تیم اصلی شما اجازه می دهد تا روی عملکرد برنامه تمرکز کند و این نگرانی های تخصصی اما مقطعی را به کارشناسان مربوطه واگذار کند.برای ثبت request و logging response و monitoring مقداری ثبات و صبر داشته باشید. حتی اگر یک سرویس به درستی تنظیم نشده باشد، gateway را می توان برای اطمینان از حداقلی سطح monitoring و logging پیکربندی کرد.مسائل و ملاحظات:اطمینان حاصل کنید که gateway بسیار در دسترس است و در برابر failure و خطا  مقاوم است. با اجرای چندین نمونه از gateway خود از نقاط failure اجتناب کنید.اطمینان حاصل کنید که gateway برای capacity و scaling مورد نیاز برنامه و endpoints شما به درستی طراحی شده است. اطمینان حاصل کنید که gateway به یک bottleneck برای برنامه تبدیل نمی شود و به اندازه کافی مقیاس پذیر (scalable) است.فقط ویژگی هایی را بارگیری کنید که توسط کل برنامه استفاده می شود، مانند امنیت یا انتقال داده.مورد Business logic هرگز نباید در gateway بارگذاری شود.اگر نیاز به track کردن تراکنش‌ها دارید، شناسه‌های (IDs) منحصر به فردی را برای اهداف ورود به سیستم ایجاد کنید.چه زمانی از این الگو استفاده کنیم؟از این الگو زمانی استفاده کنید که:استقرار (deployment) برنامه یک نگرانی مشترک مانند گواهینامه های SSL یا رمزگذاری دارد.یک ویژگی که در بین deployment برنامه‌هایی که ممکن است نیازمندی منابع متفاوتی داشته باشند، مانند منابع حافظه، ظرفیت ذخیره‌سازی یا اتصالات شبکه، رایج است.زمانی که می خواهیم مسئولیت مسائلی مانند امنیت شبکه، throttling، یا سایر نگرانی های مربوط به مرز شبکه را به یک تیم تخصصی تر منتقل کنید.این الگو در حالت coupling across services م مناسب نیست.مثال:با استفاده از Nginx به عنوان ابزار offload SSL، پیکربندی زیر یک اتصال SSL ورودی را خاتمه می دهد و اتصال را به یکی از سه سرور HTTP بالادستی توزیع می کند.upstream iis {        server  10.3.0.10    max_fails=3    fail_timeout=15s;        server  10.3.0.20    max_fails=3    fail_timeout=15s;        server  10.3.0.30    max_fails=3    fail_timeout=15s;}server {        listen 443;        ssl on;        ssl_certificate /etc/nginx/ssl/domain.cer;        ssl_certificate_key /etc/nginx/ssl/domain.key;        location / {                set $targ iis;                proxy_pass http://$targ;                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;                proxy_set_header X-Forwarded-Proto https;proxy_set_header X-Real-IP $remote_addr;                proxy_set_header Host $host;        }}در Azure، با تنظیم setting up SSL termination on Application Gateway   می توان به این امر دست یافت.منابع مرتبط:Backends for Frontends patternGateway Aggregation patternGateway Routing pattern</description>
                <category>danny</category>
                <author>danny</author>
                <pubDate>Mon, 26 Sep 2022 00:07:34 +0330</pubDate>
            </item>
                    <item>
                <title>Cloud Design Patterns - Gateway Aggregation pattern</title>
                <link>https://virgool.io/@dany_kh/cloud-design-patterns-gateway-aggregation-pattern-fo7vnuqdocyx</link>
                <description>از یک gateway برای تجمیع چندین requests  منحصر به فرد در یک request استفاده کنید. این الگو زمانی مفید است که یک کلاینت برای انجام یک عملیات باید چندین تماس با سیستم‌های backend مختلف برقرار کند.طرح صورت مسئله:برای انجام یک task واحد، یک کلاینت ممکن است مجبور باشد چندین فراخونی با سرویس های مختلف backend برقرار کند. برنامه‌ای که برای انجام یک task به serviceهای زیادی متکی است، باید resourceهای را برای هر request مصرف کند. هنگامی که هر ویژگی یا سرویس جدیدی به برنامه اضافه می شود، request های اضافی مورد نیاز است که نیاز به منابع و فراخوانی‌های شبکه را بیشتر می کند. این ارتباط بین یک client و یک backend می تواند بر performance و scale برنامه تأثیر منفی بگذارد. معماری‌های میکروسرویس این مشکل را رایج‌تر کرده‌اند، زیرا برنامه‌های کاربردی ساخته‌شده پیرامون بسیاری از سرویس‌های کوچک‌تر،  تعداد فراخوانی متقابل سرویس بیشتری دارند.در نمودار زیر client برای هر سرویس request ارسال می کند (1،2،3). هر سرویس request را پردازش می کند و پاسخ را به برنامه  برمی‌گرداند (4،5،6). در یک شبکه سلولی با latency معمولاً بالا، استفاده از requestهای مستقل به این شیوه ناکارآمد است و می‌تواند منجر به قطع اتصال یا requestهایهای ناقص شود. در حالی که هر requestهای ممکن است به صورت موازی انجام شود، برنامه باید داده ها را برای هر request ارسال و سپس صبر کند و در نهایت پردازش کند و چون همه‌ی در اتصالات و ارتباطات جداگانه و مجزا است احتمال خطا و failure  را افزایش می دهد.راه حل:از یک gateway برای کاهش chattiness و ارتباط بین client و serviceها استفاده کنید. gateway همیشه requestهای client را دریافت می‌کند، requestها را به سیستم‌های backend مختلف ارسال(dispatche) می‌کند و سپس نتایج را جمع‌آوری می‌کند و آنها را برای client درخواست‌کننده ارسال می‌کند.این الگو می‌تواند تعداد requestهایی را که برنامه برای backend service ارائه می‌کند کاهش دهد و عملکرد برنامه را در شبکه‌های با high-latency بهبود بخشد.در نمودار زیر اپلیکیشن درخواستی را به gateway (1) ارسال می کند.  request شامل بسته ای از  request های اضافی است. gateway اینها را تجزیه و آنالیز می کند و هر درخواست را با ارسال آن به سرویس مربوطه پردازش می کند (2). هر سرویس یک پاسخ به gateway (3) برمی گرداند. gateway پاسخ های هر سرویس را ترکیب می کند و پاسخ را به برنامه می فرستد (4). برنامه تنها یک request می دهد و تنها یک پاسخ از gateway دریافت می کند.مسائل و ملاحظات:به هیچ وجه gateway نباید با سرویس  backend به صورت service coupling across ارتباط داشته باشد .همیشه gateway باید در نزدیکی backend services قرار گیرد تا latency تا حد امکان کاهش یابد.سرویس gateway ممکن است به یک نقطه bottleneck تبدیل شود. اطمینان حاصل کنید که gateway به درستی طراحی شده است تا نیازهای در دسترس بودن برنامه شما را برآورده کند. ممکن است gateway یک bottleneck ایجاد کند. اطمینان حاصل کنید که دروازه عملکرد مناسبی برای تحمل load دارد و می تواند برای برآورده کردن رشد و توسعه پیش بینی شده شما جهت توسعه نرم افزار scaled شود.تست scaled را در برابر gateway انجام دهید تا مطمئن شوید که خرابی های متوالی و دنباله دار برای سرویس ها ایجاد نمی کنید.با استفاده از تکنیک هایی مانند bulkheads, circuit breaking, retry و timeouts، نرم افزاری با انعطاف پذیری را اجرا کنید.اگر یک یا چند فراخوانی از سرویس بیش از حد طول بکشد، ممکن است زمان سپری شده و بازگرداندن مجموعه ای تا حدی قابل قبول باشد. در نظر بگیرید که برنامه شما چگونه با این سناریو برخورد خواهد کرد.از ورودی/خروجی ناهمزمان (asynchronous I/O) استفاده کنید تا اطمینان حاصل کنید که تاخیر در backend باعث مشکلات عملکرد در برنامه نمی شود.پیاده سازی tracing توزیع شده با استفاده از شناسه های(IDs) منحصر به فرد برای track کردن هر فراخوانی جداگانه.متریک‌های request و اندازه response را Monitor کنید.بازگرداندن داده های کش(cached) را به عنوان یک استراتژی شناسایی شکست برای مدیریت failure شدن درخواست‌های ارتباطی در نظر بگیرید.به جای ایجاد تجمیع(aggregation) در gateway، قرار دادن یک سرویس تجمیع(aggregation) در پشت gateway را در نظر بگیرید. Request aggregation احتمالاً نیازمند resourceهای متفاوتی نسبت به سایر serviceهای در gateway خواهد بود و ممکن است بر عملکرد مسیریابی و بارگذاری دروازه تأثیر بگذارد.چه زمانی از این الگو استفاده کنیم؟از این الگو زمانی استفاده کنید که:یک کلاینت برای انجام یک عملیات باید با چندین سرویس backend ارتباط برقرار کند.کلاینت ممکن است از شبکه هایی با latency قابل توجه مانند شبکه های سلولی استفاده کند.این الگو ممکن است زمانی مناسب نباشد که:زمانی که می خواهید تعداد فراخوانی های بین یک کلاینت و یک سرویس را در چندین عملیات کاهش دهید. در آن سناریو، ممکن است بهتر باشد یک عملیات دسته ای/گروهی به سرویس اضافه شود.کلاینت یا برنامه در نزدیکی سرویس backend قرار دارد و تأخیر عامل مهمی نیست.مثال:مثال زیر نحوه ایجاد یک سرویس NGINX تجمیع(aggregation) در gateway ساده با استفاده از زبان برنامه نویسی Lua را نشان می دهد.worker_processes  4;events {  worker_connections 1024;}http {  server {    listen 80;    location = /batch {      content_by_lua &#x27;        ngx.req.read_body()        -- read json body content        local cjson = require &quot;cjson&quot;        local batch = cjson.decode(ngx.req.get_body_data())[&quot;batch&quot;]        -- create capture_multi table        local requests = {}        for i, item in ipairs(batch) do          table.insert(requests, {item.relative_url, { method = ngx.HTTP_GET}})        end        -- execute batch requests in parallel        local results = {}        local resps = { ngx.location.capture_multi(requests) }        for i, res in ipairs(resps) do          table.insert(results, {status = res.status, body = cjson.decode(res.body), header = res.header})        end        ngx.say(cjson.encode({results = results}))      &#x27;;    }    location = /service1 {      default_type application/json;      echo &#x27;{&quot;attr1&quot;:&quot;val1&quot;}&#x27;;    }    location = /service2 {      default_type application/json;      echo &#x27;{&quot;attr2&quot;:&quot;val2&quot;}&#x27;;    }  }}منابع مرتبط:Backends for Frontends patternGateway Offloading patternGateway Routing pattern</description>
                <category>danny</category>
                <author>danny</author>
                <pubDate>Sun, 25 Sep 2022 23:33:09 +0330</pubDate>
            </item>
                    <item>
                <title>Cloud Design Patterns - Compute Resource Consolidation</title>
                <link>https://virgool.io/@dany_kh/cloud-design-patterns-compute-resource-consolidation-zqqcdxzkfzlc</link>
                <description>چندین کار یا عملیات را در یک واحد محاسباتی ادغام کنید. این  کار می تواند استفاده از منابع محاسباتی را افزایش دهد و هزینه ها و سربار مدیریت مربوط به انجام پردازش محاسباتی در برنامه های کاربردی cloud-hosted  را کاهش دهد.طرح صورت مسئله:یک برنامه ابری اغلب عملیات های مختلفی را پیاده سازی می کند. در برخی راه‌حل‌ها، منطقی است که در ابتدا از اصل طراحی جداسازی نگرانی‌ها (separation of concerns) پیروی کنیم و این عملیات را به واحدهای محاسباتی جداگانه تقسیم کنیم که به صورت جداگانه میزبانی و deploy می‌شوند (مثلاً به عنوان برنامه‌های وب سرویس App جداگانه یا ماشین‌های مجازی جداگانه). با این حال، اگرچه این استراتژی می تواند به ساده سازی طراحی منطقی راه حل کمک کند، استقرار تعداد زیادی از واحدهای محاسباتی به عنوان بخشی از همان برنامه می تواند هزینه های میزبانی زمان اجرا را افزایش دهد و مدیریت سیستم را پیچیده تر کند.به عنوان مثال، شکل زیر ساختار ساده شده یک  cloud-hosted را نشان می دهد که با استفاده از بیش از یک واحد محاسباتی پیاده سازی شده است. هر واحد محاسباتی در محیط مجازی خود اجرا می شود. هر تابع به عنوان یک وظیفه مجزا (با برچسب وظیفه A تا Task E) در واحد محاسباتی خود اجرا شده است.هر واحد محاسباتی منابع chargeable را مصرف می‌کند، حتی زمانی که بی‌حرکت باشد یا کم استفاده شود. بنابراین، این همیشه مقرون به صرفه ترین راه حل نیست.در در بیشتر سامانه‌های ارايه دهنده خدمات ابری مثل azure این نگرانی در مورد App Services و Container Apps و ماشین های مجازی وجود دارد. این موارد در محیط خودشان اجرا می شوند. اجرای مجموعه‌ای از وب‌سایت‌ها، میکروسرویس‌ها یا ماشین‌های مجازی مجزا که برای انجام مجموعه‌ای از عملیات به‌خوبی تعریف شده طراحی شده‌اند، اما نیاز به ارتباط و همکاری به عنوان بخشی از یک راه‌حل واحد دارند  و اختلال در این مورد می‌تواند باعث استفاده ناکارآمد از منابع شود.راه حل:برای کمک به کاهش هزینه ها، افزایش استفاده، بهبود سرعت ارتباط و کاهش مدیریت، می توان چندین کار یا عملیات را در یک واحد محاسباتی ادغام کرد.وظایف را می توان بر اساس معیارهایی بر اساس ویژگی های ارائه شده توسط environment و هزینه های مرتبط با این ویژگی ها گروه بندی کرد. یک رویکرد متداول این است که به دنبال کارهایی بگردید که مشخصات مشابهی در مورد lifetime و scalability و processing requirements دارند. گروه بندی اینها با هم به آنها اجازه می دهد تا به عنوان یک واحد معین مقیاس یا متریک شوند. خاصیت elasticity ارائه شده توسط بسیاری از محیط های ابری باعث می شود که نمونه های اضافی از یک واحد محاسباتی بر اساس حجم کار شروع و متوقف شوند. برای مثال، Azure مقیاس خودکار را ارائه می‌کند که می‌توانید آن را برای سرویس‌های برنامه و مجموعه‌های مقیاس ماشین مجازی اعمال کنید. برای اطلاعات بیشتر، به راهنمای Autoscaling Guidance مراجعه کنید.به عنوان مثالی متقابل برای نشان دادن اینکه چگونه می توان از مقیاس پذیری برای تعیین اینکه کدام عملیات نباید با هم گروه بندی شوند استفاده کرد، دو وظیفه زیر را در نظر بگیرید:وظیفه 1 - استفاده از polls برای پیام های نادر(infrequent) و حساس به زمان ارسال شده به یک صف.وظیفه 2 - بررسی  کردن  حجم درخواست های بسیار  بالا در ترافیک شبکه.وظیفه دوم نیاز به elasticity دارد که می تواند شامل شروع و توقف تعداد زیادی از نمونه های واحد محاسباتی باشد. استفاده از همان scaling برای اولین کار به سادگی منجر به وظایف بیشتری برای listening به پیام های نادر(infrequent) در همان queue می شود و این کار برابر با اتلاف منابع است.در بسیاری از محیط‌های ابری، می‌توان منابع موجود برای یک واحد محاسباتی را از نظر تعداد هسته‌های CPU، حافظه، فضای دیسک و غیره مشخص کرد. به طور کلی، هر چه منابع بیشتر مصرف شود، هزینه بیشتر می شود. برای صرفه جویی در هزینه، مهم است که کار یک واحد محاسباتی گران قیمت را به حداکثر برسانید و اجازه ندهید برای مدت طولانی غیرفعال شود.اگر کارهایی وجود دارد که به مقدار زیادی توان CPU در فاصله‌های کوتاه نیاز دارند، توصیه می شود این تسک‌ها را در یک واحد محاسباتی ادغام کنید که توان لازم را فراهم کند. بهینه کردن این نیاز برای مشغول نگه داشتن منابع گران قیمت در برابر احتمالاتی که در صورت فشارهای پیش بینی نشده دیگر  که روی CPU ممکن است رخ دهد بسیار مهم است. به عنوان مثال، کارهای طولانی مدت و فشرده نباید واحد محاسباتی یکسانی را به اشتراک بگذارند.مسائل و ملاحظات:در اجرای این الگو به نکات زیر توجه کنید:مورد اول- Scalability and elasticity: بسیاری از راه حل های ابری scalability و elasticity را در سطح واحد محاسباتی با شروع و توقف instanceهای  واحدها پیاده سازی می کنند. از گروه بندی task های که دارای الزامات مقیاس پذیری متناقض هستند در یک واحد محاسباتی خودداری کنید.مورد دوم - Lifetime :  زیرساخت ابری به صورت دوره ای محیط مجازی را که میزبان یک واحد محاسباتی است، بازرسی می کند. هنگامی که long-running tasks  زیادی در داخل یک واحد محاسباتی وجود دارد، ممکن است لازم باشد که واحد را پیکربندی مجدد کنید تا از recycled آن جلوگیری شود تا زمانی که این tasks به پایان برسد. روش دیگر؛ طراحی tasks با استفاده از یک رویکرد check-pointing که آنها را قادر می سازد به طور مناسب متوقف شوند و در نقطه ای که هنگام راه اندازی مجدد واحد محاسباتیوارد وقفه شد، ادامه دهند.مورد سوم - Fault tolerance :اگر یک task در یک واحد محاسباتی با شکست مواجه شود یا رفتار غیرعادی داشته باشد، می‌تواند بر سایر task در حال اجرا در همان واحد تأثیر بگذارد. برای مثال، اگر یک کار به درستی شروع نشود، می‌تواند باعث شود کل منطق راه‌اندازی واحد محاسباتی با شکست مواجه شود و از اجرای سایر وظایف در همان واحد جلوگیری کند.مورد چهارم - Contention :از ایجاد conflict بین task که برای منابع در یک واحد محاسباتی با هم رقابت می کنند خودداری کنید. در حالت ایده آل، وظایفی که واحد محاسباتی یکسانی دارند باید ویژگی های استفاده از منابع متفاوتی را نشان دهند. به عنوان مثال؛ دو کار فشرده محاسباتی احتمالاً نباید در یک واحد محاسباتی قرار داشته باشند، و همچنین نباید دو task که مقدار زیادی از حافظه را مصرف می‌کنند در یک واحد محاسباتی باشند. با این حال، اختلاط یک کار محاسباتی فشرده با یک کار که به مقدار زیادی حافظه نیاز دارد، ترکیبی قابل اجرا است.مورد پنجم - Complexity:ترکیب چند task در یک واحد محاسباتی به  پیچیدگی کد موجود می‌افزاید و احتمالاً test و اشکال‌زدایی و نگهداری آن برنامه را دشوارتر می‌کند.مورد ششم - Stable logical architecture:برای هر task کد برنامه را ويژه و مناسب طراحی و پیاده سازی کنید به طوری که نیازی به تغییرات کد حتی در صورت  تغییر محیط فیزکی اجرا نداشته باشد.مورد هفتم - Other strategies:ادغام منابع محاسباتی تنها یکی از راه‌های کمک به کاهش هزینه‌های مرتبط با اجرای چندین task به طور همزمان است. این نیاز به برنامه ریزی و نظارت دقیق دارد تا اطمینان حاصل شود که یک رویکرد موثر باقی می ماند. بسته به ماهیت کار و محل قرارگیری کاربرانی که این وظایف در حال اجرا هستند، استراتژی‌های دیگر ممکن است مناسب‌تر باشند. به عنوان مثال، تجزیه عملکردی حجم کاری (همانطور که توسط راهنمای پارتیشن بندی Compute Partitioning Guidance محاسبه شده است) ممکن است گزینه بهتری باشد.چه زمانی از این الگو استفاده کنیم؟از این الگو برای کارهایی استفاده کنید که اگر در واحدهای محاسباتی خودشان اجرا شوند مقرون به صرفه نیستند. اگر یک کار بیشتر زمان خود را بیکار می گذراند، اجرای این کار در یک واحد اختصاصی می تواند گران باشد.این الگو ممکن است برای کارهایی که عملیات حساس fault-tolerant را انجام می‌دهند، یا کارهایی که داده‌های بسیار حساس یا خصوصی را پردازش می‌کنند و به زمینه امنیتی خاص خود نیاز دارند، مناسب نباشد. این وظایف باید در محیط ایزوله خود، در یک واحد محاسباتی جداگانه اجرا شوند.انتخاب platform:در این مورد گزینه های ارائه شده در Azure  را بررسی می‌کنیم:یک - Azure App Service و Azure Functions: برنامه های مشترک App Service را که نشان دهنده زیرساخت hosting server است را اجرا کنید. یک یا چند برنامه را می توان پیکربندی کرد تا بر روی همان منابع محاسباتی (یا در همان برنامه خدمات برنامه) اجرا شوند.دو - برنامه‌های کانتینر Azure: برنامه‌های کانتینر را در همان محیط‌های مشترک مستقر کنید. به خصوص در شرایطی که نیاز به مدیریت خدمات مرتبط دارید یا نیاز به استقرار برنامه های مختلف در یک شبکه مجازی دارید.سه - سرویس Azure Kubernetes (AKS): AKS یک زیرساخت میزبانی مبتنی بر کانتینر است که در آن برنامه‌های کاربردی یا مؤلفه‌های برنامه را می‌توان پیکربندی کرد تا در منابع محاسباتی (گره‌ها) به صورت مشترک اجرا شوند، که بر اساس نیازهای محاسباتی مانند نیازهای CPU یا حافظه گروه‌بندی می‌شوند ( استخرهای گره).چهار - ماشین‌های مجازی: مجموعه‌ای از ماشین‌های مجازی را برای استفاده همه tenant ها مستقر کنید، به این ترتیب هزینه‌های مدیریت در بین tenant ها تقسیم می‌شود. Virtual Machine Scale Sets یک ویژگی است که از مدیریت منابع مشترک، load-balancing و horizontal scaling ماشین های مجازی پشتیبانی می کند.مباحث مرتبط:Autoscaling Guidance.Compute Partitioning Guidance.Architectural approaches for compute in multitenant solutions. Edge Workload Configuration pattern - Cloud Design Patterns&lt;br/&gt; Geode pattern - Azure Architecture Center Scheduler Agent Supervisor pattern - Azure Architecture Center&lt;br/&gt; External Configuration Store pattern - Azure Architecture Center&lt;br/&gt; Choreography pattern - Azure Architecture Center&lt;br/&gt; Leader Election pattern - Azure Architecture Center&lt;br/&gt; Valet Key pattern - Azure Architecture Center Index Table pattern - Azure Architecture Cente</description>
                <category>danny</category>
                <author>danny</author>
                <pubDate>Sun, 25 Sep 2022 19:48:47 +0330</pubDate>
            </item>
                    <item>
                <title>Cloud Design Patterns - CQRS</title>
                <link>https://virgool.io/@dany_kh/cloud-design-patterns-cqrs-fd2qjvfxnrbr</link>
                <description> در این قسمت به سراغ پترن CQRS می رویم، CQRS مخفف Command and Query Responsibility Segregation است، الگویی که عملیات خواندن و به روز رسانی را برای  ذخیره داده‌ها جدا می کند. پیاده سازی CQRS در برنامه شما می تواند performance، scalability و امنیت آن را به حداکثر برساند. انعطاف‌پذیری ایجاد شده توسط CQRS به سیستم اجازه می‌دهد در طول زمان بهتر تکامل یابد و از ایجاد merge conflicts   توسط  به‌روزرسانی‌ها جلوگیری می‌کند.طرح صورت مسئله:در معماری‌های قدیمی‌تر نرم افزار، از  data model یکسانی  برای query و به روز رسانی پایگاه داده استفاده می شود. این روش خیلی ساده بوده و برای عملیات اولیه و معمولی CRUD به خوبی کار می کند. با این حال، در برنامه های پیچیده تر، این روش خوب نیست. به عنوان مثال: در سمت خواندن پایگاه داده، برنامه ممکن است queryهای مختلفی را انجام دهد و data transfer objects (DTO) را با اشکال مختلف برگرداند. Object mapping می تواند پیچیده شود. در سمت نوشتن، مدل ممکن است validation  و business logic پیچیده‌ای را پیاده سازی کند. در نتیجه؛   با یک مدل بیش از حد پیچیده روبرو می‌شویم که بیش از حد کار می کند و به نوعی تحت فشار است. حجم عملیات  خواندن و نوشتن  نامتقارن و نابرابر است و به جهت مشکلات performance در این موارد نیاز به scale برنامه بوجود می ‌آید.معمولا یک عدم تطابق بین نمایش خواندن و نوشتن داده ها وجود دارد، مانند ستون ها یا ویژگی های اضافی که باید به درستی به روز شوند، حتی اگر به عنوان بخشی از یک عملیات مورد نیاز نباشند.زمانی که عملیات به صورت موازی روی یک مجموعه از داده ها انجام شود، اختلاف داده ها ممکن است منجر به conflict شود.رویکرد قدیمی می تواند به دلیل بارگذاری روی ذخیره داده ها و لایه دسترسی به داده ها و پیچیدگی queryهای مورد نیاز برای بازیابی اطلاعات، تأثیر منفی بر performance داشته باشد.مدیریت امنیت و permissions می‌تواند پیچیده شود، زیرا هر entity تابع عملیات خواندن و نوشتن است، که ممکن است داده‌ها را در context اشتباه نشان دهد.راه حل:به طور کلی CQRS خواندن و نوشتن را در مدل‌های مختلف جدا می‌کند و از دستورات برای به‌روزرسانی داده‌ها و پرس و جو برای خواندن داده‌ها استفاده می‌کند.دستورات باید task-based باشند، نه داده محور (data centric).  (&quot;Book hotel room&quot;, not &quot;set ReservationStatus to Reserved&quot;).دستورات ممکن است در یک queue برای پردازش ناهمزمان قرار گیرند، نه اینکه به صورت همزمان پردازش شوند.کوئری ها هرگز پایگاه داده را تغییر نمی دهند. یک پرس و جو یک DTO را برمی گرداند که هیچ domain knowledge را کپسوله نمی کند.سپس می توان مدل ها را جدا کرد، همانطور که در نمودار زیر نشان داده شده است.داشتن مدل های پرس و جو و به روز رسانی جداگانه، طراحی و پیاده سازی را ساده می کند. با این حال، یک نقطه ضعف این است که کد CQRS نمی تواند به طور خودکار از یک طرح پایگاه داده با استفاده از مکانیسم هایی مانند ابزارهای O/RM تولید شود.برای جداسازی بیشتر، می توانید داده های خوانده شده را از داده های نوشتن به صورت فیزیکی جدا کنید. در آن صورت، پایگاه داده خوانده شده می تواند از طرح داده های خود استفاده کند که برای پرس و جوها بهینه شده است. به عنوان مثال، می تواند یک نمای مادی از داده ها را ذخیره کند تا از اتصالات پیچیده یا O/RM mapping پیچیده جلوگیری کند. حتی ممکن است از نوع دیگری از ذخیره داده استفاده کند. به عنوان مثال، پایگاه داده نوشتن ممکن است relational باشد، در حالی که پایگاه داده خوانده شده یک پایگاه document database است.اگر از پایگاه‌های داده خواندن و نوشتن جداگانه استفاده می‌شود، باید آنها را sync نگه داشت. این حالت معمولاً با publish شدن یک event توسط مدل نوشتن  زمانی که پایگاه داده را به روز شود، انجام می شود. برای اطلاعات بیشتر در مورد استفاده از رویدادها، به سبک معماری Event-driven architecture style مراجعه کنید. به روز رسانی پایگاه داده و publish شدن event باید در یک تراکنش (transaction) انجام شود.ذخیره داده های خواندن می‌تواند یک (replica)کپی read-only  از ذخیره داده های نوشتن باشد، یا ذخیره  داده های خواندن و نوشتن می‌توانند ساختار متفاوتی داشته باشند. استفاده از چند replica  به صورت read-only می تواند performance query را افزایش دهد، به خصوص در سناریوهای distributed شده که در آن replica های فقط خواندنی نزدیک به  برنامه در حال اجرا قرار دارند.جداسازی ذخیره داده‌های خواندن و نوشتن  اجازه می‌دهد تا هر کدام به‌طور مناسب برای مطابقت با load برنامه و دستورات، scale شوند. به عنوان مثال، ذخیره داده های خواندن معمولاً با load بسیار بالاتری نسبت به ذخیره داده‌های نوشتن مواجه می شوند.برخی از پیاده سازی های CQRS از الگوی Event Sourcing استفاده می کنند. با این الگو، وضعیت برنامه به عنوان یک دنباله‌ای از eventها ذخیره می شود. هر event نشان دهنده مجموعه ای از تغییرات در داده ها است. وضعیت فعلی با پخش مجدد رویدادها ساخته می شود. در  موضوع CQRS، یکی از مزایای Event Sourcing این است که از همان رویدادها می توان برای اطلاع رسانی (notify) به اجزای دیگر استفاده کرد - به ویژه برای اطلاع رسانی(notify) به مدل خوانده شده(read model). مدل خواندن از eventها برای ایجاد یک snapshot از وضعیت فعلی استفاده می کند که برای پرس و جوها کارآمدتر است. با این حال، Event Sourcing پیچیدگی را به طراحی اضافه می کند.مزایای CQRS عبارتند از:مقیاس بندی مستقل (Independent scaling): CQRS اجازه می دهد تا حجم کار خواندن و نوشتن به طور مستقل scale شود و ممکن است منجر به conflict در داده‌ها کمتر شود.حالت Optimized data schemas: سمت خواندن داده ها  می تواند از طرحی استفاده کند که برای queryها بهینه شده است، در حالی که سمت نوشتن داده ها از طرحی استفاده می کند که برای به روز رسانی بهینه شده است.امنیت (Security): اطمینان از اینکه فقط موجودیت های(entities)  مناسب روی نوشتن داده‌ها  در پایگاه داده انجام می گیرد.تفکیک نگرانی ها(Separation of concerns): جداسازی دو طرف خواندن و نوشتن می‌تواند منجر به مدل‌هایی شود که قابلیت نگهداری و انعطاف‌پذیری بیشتری دارند. بیشتر منطق پیچیده کسب و کار وارد مدل نوشتن می شود. مدل خواندن می تواند نسبتا ساده باشد.پرس و جوهای ساده تر  (Simpler queries): با ذخیره به صورت materialized view در پایگاه داده‌ای ‌ که جهت خواندن داده طراحی  شده، برنامه می تواند از اتصالات پیچیده هنگام query زدن جلوگیری کند.مسائل و ملاحظات:برخی از چالش های اجرای این الگو عبارتند از:پیچیدگی (Complexity): ایده اصلی CQRS ساده است. اما می‌تواند منجر به طراحی اپلیکیشن پیچیده‌تر شود، به‌ویژه اگر شامل الگوی Event Sourcing باشد.پیام رسانی (Messaging): اگرچه CQRS به messaging نیازی ندارد، استفاده از messaging برای پردازش دستورات و publish update events متداول است. در آن صورت، برنامه باید با failure شدن پیام ها یا پیام های تکراری مقابله کند. برای برخورد با دستوراتی که اولویت های متفاوتی دارند، راهنمای Priority Queues را ببینید.استحکام  احتمالی (Eventual consistency): اگر پایگاه داده‌های خواندن و نوشتن ‌ را از هم جدا کنید، داده های خوانده شده ممکن است قدیمی شده باشند یا به روز نباشند. دیتابیس مربوط به خواندن باید بروز رسانی شود  تا تغییرات  در دریتابیس نوشتن را منعکس کند و تشخیص زمانی که کاربر براساس داده‌های خوانده شده قدیمی درخواستی صادر کرده است و این به اصطلاح sync   شدن داده ها در دیتابیس بیس خواندن و نوشتن ایجاد کند، می‌تواند دشوار باشد.چه زمانی از این الگو استفاده کنیم؟برای CQRS  سناریوهای زیر را در نظر بگیرید:دامنه های مشارکتی که در آن بسیاری از کاربران به طور موازی به داده های مشابه دسترسی دارند. CQRS به شما اجازه می دهد تا دستوراتی را با جزئیات کافی تعریف کنید تا merge conflicts را در سطوح مختلف به حداقل برسانید و تداخل هایی که به وجود می آیند را می توان با command هایی merged کرد.رابط های کاربری Task-based که در آن کاربران از طریق یک فرآیند پیچیده به عنوان یک سری مراحل یا با domain models پیچیده  هدایت می شوند. write model دارای یک command-processing stack کامل با business logic و  validation ورودی و business validation است. write model ممکن است مجموعه‌ای از objects مرتبط را به‌عنوان یک  واحد برای تغییرات داده‌ها (یک aggregate، در اصطلاح DDD) در نظر بگیرد و اطمینان حاصل کند که این object همیشه در یک حالت ثابت هستند. read model هیچ business logic یا validation stack ندارد و فقط یک DTO را برای استفاده در یک view model برمی گرداند. read model در نهایت با write model سازگار است.سناریوهایی که عملکرد خواندن داده ها باید جدا از عملکرد نوشتن داده ها تنظیم شود به خصوص زمانی که تعداد خواندن ها بسیار بیشتر از تعداد نوشتن ها باشد. در این سناریو، می توانید read model را scale out کنید، اما write model را فقط در چند instances محدود اجرا کنید. تعداد کمی از نمونه های write model نیز به به حداقل رساندن وقوع merge conflicts کمک می کند.سناریوهایی که در آن یک تیم از توسعه دهندگان می توانند بر روی domain model پیچیده که بخشی از write model است تمرکز کنند، و تیم دیگری می توانند بر روی read model و رابط های کاربری تمرکز کنند.سناریوهایی که در آن انتظار می‌رود سیستم در طول زمان تکامل یابد و ممکن است چندین ورژن از model را داشته باشد  یا business rules به طور منظم تغییر می‌کنند.ادغام با سیستم های دیگر، به ویژه در ترکیب با event sourcing  که در آن خرابی موقت یک زیرسیستم نباید بر در دسترس بودن سایر سیستم ها تأثیر بگذارد.این الگو در موارد زیر توصیه نمی شود:دامنه یا business rules ساده است.یک رابط کاربری ساده به سبک CRUD و عملیات دسترسی به داده برای برنامه مورد نظر مناسب باشد.استفاده از CQRS را در بخش های محدودی از سیستم خود در نظر بگیرید که در آن بیشترین ارزشو حساسیت را دارد.معرفی Event Sourcing and CQRS pattern:الگوی CQRS اغلب همراه با الگوی Event Sourcing استفاده می شود. سیستم‌های مبتنی بر CQRS از مدل‌های داده خواندن و نوشتن جداگانه استفاده می‌کنند که هر کدام برای وظایف مربوطه طراحی شده‌اند و اغلب در ذخیره سازی فیزیکی مجزا قرار دارند. هنگامی که با الگوی Event Sourcing استفاده می شود، ذخیره رویدادها write model است و منبع official source داده‌ها است. read model یک سیستم مبتنی بر CQRS  که materialized views داده‌ها  معمولاً به صورت viewsهای بسیار denormalized شده ارائه می‌کند. این viewها بر اساس واسط ها و الزامات نمایش برنامه طراحی شده اند که به  حداکثر رساندن performance نمایش و query کمک می کند.استفاده از stream of events به‌عنوان ذخیره‌سازی نوشتن به‌جای داده‌های واقعی در یک نقطه خاصی از زمان قطعا از update conflicts در یک aggregate اجتناب می‌کند و performance و scalability را به حداکثر می‌رساند. از eventها می توان برای تولید ناهمزمان materialized views داده هایی که برای پر کردن ذخیره‌سازی خوانده استفاده می شود استفاده کرد.از آنجایی که ذخیره‌سازی رویداد (event store) منبع رسمی اطلاعات داده‌هاست، می‌توان  materialized views را حذف کرد و همه رویدادهای گذشته را مجدداً پخش کرد تا زمانی که سیستم تکامل می‌یابد یا زمانی که مدل read model باید تغییر کند یا نمایش جدیدی از وضعیت فعلی ایجاد شود. materialized views یافته در واقع یک حافظه cache پنهان read-only از داده ها هستند.هنگام استفاده از CQRS همراه با الگوی Event Sourcing، موارد زیر را در نظر بگیرید:مانند هر سیستمی که دیتابیس ذخیره‌ داده‌های نوشتن و خواندن آن مجزا هستند، سیستم‌های مبتنی بر این الگو تنها eventually consistent هستند و بین ایجاد رویداد و به‌روزرسانی ذخیره‌ داده ها تأخیر و ناهمزمانی وجود خواهد داشت.این الگو پیچیدگی می‌افزاید، زیرا کد باید برای شروع و مدیریت رویدادها، و جمع‌آوری یا به‌روزرسانی view یا objects مناسب مورد نیاز کوئری‌ها یا مدل خوانده شده ایجاد شود. پیچیدگی الگوی CQRS هنگامی که با الگوی Event Sourcing استفاده می‌شود، می‌تواند implementation موفقیت‌آمیز را دشوارتر کند و نیاز به رویکرد متفاوتی برای طراحی سیستم‌ها دارد. با این حال،  Event Sourcing می‌تواند model domain را آسان‌تر کند، و بازسازی viewها یا ایجاد viewهای جدید را آسان‌تر می‌کند زیرا هدف از تغییرات در داده‌ها حفظ می‌شود.ایجاد materialized views برای استفاده در read model  یا پیش بینی داده ها با replaying  و handling رویدادها برای entities  یا مجموعه های خاص می تواند به زمان پردازش و استفاده از منابع سخت افزاری قابل توجهی نیاز داشته باشد. این امر به ویژه در صورتی صادق است که به جمع بندی یا آنالیز مقادیر در زمان‌های طولانی نیاز داشته باشد، زیرا ممکن است همه رویدادهای مرتبط نیاز به بررسی داشته باشند. این مشکل را با implementing snapshots از داده‌ها در فواصل زمانی برنامه‌ریزی‌شده مانند شمارش کل تعداد یک عمل خاص که رخ داده است (total count of the number of a specific action that has occurred) یا وضعیت فعلی یک entity، حل کنید.مثالی از الگوی CQRS:کد زیر چکیده ای از پیاده سازی CQRS را نشان می دهد که از تعاریف مختلفی برای مدل های خواندن و نوشتن استفاده می کند. رابط‌های مدل هیچ ویژگی ذخیره‌سازی داده‌های زیربنایی را تعیین نمی‌کنند و می‌توانند به طور مستقل توسعه یافته و تنظیم شوند زیرا این رابط‌ها از هم جدا هستند.کد زیر تعریف مدل خوانده شده را نشان می دهد.// Query interfacenamespace ReadModel{  public interface ProductsDao  {    ProductDisplay FindById(int productId);    ICollection&lt;ProductDisplay&gt; FindByName(string name);    ICollection&lt;ProductInventory&gt; FindOutOfStockProducts();    ICollection&lt;ProductDisplay&gt; FindRelatedProducts(int productId);  }  public class ProductDisplay  {    public int Id { get; set; }    public string Name { get; set; }    public string Description { get; set; }    public decimal UnitPrice { get; set; }    public bool IsOutOfStock { get; set; }    public double UserRating { get; set; }  }  public class ProductInventory  {    public int Id { get; set; }    public string Name { get; set; }    public int CurrentStock { get; set; }  }}این سیستم به کاربران اجازه می دهد تا محصولات را رتبه بندی کنند. کد برنامه این کار را با استفاده از دستور RateProduct نشان داده شده در کد زیر انجام می دهد.public interface ICommand{  Guid Id { get; }}public class RateProduct : ICommand{  public RateProduct()  {    this.Id = Guid.NewGuid();  }  public Guid Id { get; set; }  public int ProductId { get; set; }  public int Rating { get; set; }  public int UserId {get; set; }}این سیستم از کلاس ProductsCommandHandler برای کنترل دستورات ارسال شده توسط برنامه استفاده می کند. کلاینت ها معمولاً دستورات را از طریق یک سیستم messaging مانند queue به دامنه ارسال می کنند. کنترل کننده فرمان این دستورات را می پذیرد و متدهای رابط دامنه را فراخوانی می کند. جزئیات هر فرمان به گونه ای طراحی شده است که شانس درخواست های conflict را کاهش دهد. کد زیر یک طرح کلی از کلاس ProductsCommandHandler را نشان می دهد.public class ProductsCommandHandler :    ICommandHandler&lt;AddNewProduct&gt;,    ICommandHandler&lt;RateProduct&gt;,    ICommandHandler&lt;AddToInventory&gt;,    ICommandHandler&lt;ConfirmItemShipped&gt;,    ICommandHandler&lt;UpdateStockFromInventoryRecount&gt;{  private readonly IRepository&lt;Product&gt; repository;  public ProductsCommandHandler (IRepository&lt;Product&gt; repository)  {    this.repository = repository;  }  void Handle (AddNewProduct command)  {    ...  }  void Handle (RateProduct command)  {    var product = repository.Find(command.ProductId);    if (product != null)    {      product.RateProduct(command.UserId, command.Rating);      repository.Save(product);    }  }  void Handle (AddToInventory command)  {    ...  }  void Handle (ConfirmItemsShipped command)  {    ...  }  void Handle (UpdateStockFromInventoryRecount command)  {    ...  }}مراحل بعدیالگوها و راهنمایی های زیر هنگام اجرای این الگو مفید هستندمورد  Data Consistency Primer. مشکلاتی را که معمولاً به دلیل سازگاری نهایی بین ذخیره‌های داده‌های خواندن و نوشتن در هنگام استفاده از الگوی CQRS با آن مواجه می‌شوند و اینکه چگونه می‌توان این مسائل را حل کرد، توضیح می‌دهد.مورد Horizontal, vertical, and functional data partitioning. بهترین روش‌ها را برای تقسیم داده‌ها به پارتیشن‌هایی توصیف می‌کند که می‌توانند به طور جداگانه مدیریت شوند و به آن‌ها دسترسی داشته باشیم تا مقیاس‌پذیری را بهبود ببخشیم، اختلافات را کاهش دهیم و عملکرد را بهینه کنیم.الگوها و شیوه‌های راهنمایی  CQRS Journey.  به طور خاص، معرفی الگویIntroducing the Command Query Responsibility Segregation pattern و زمان مفید بودن آن را بررسی می‌کند و Epilogue: Lessons Learned به شما کمک می‌کند تا برخی از مسائلی را که هنگام استفاده از این الگو پیش می‌آیند، درک کنید.مراجع مرتبطالگوی موجود در لینک Event Sourcing pattern با جزئیات بیشتری توضیح می دهد که چگونه می توان از Event Sourcing با الگوی CQRS برای ساده کردن وظایف در حوزه های پیچیده و در عین حال بهبود عملکرد، مقیاس پذیری و پاسخگویی استفاده کرد. و همچنین نحوه ارائه یکپارچگی برای transactional data را نشان میدهد.الگوی Materialized View pattern. یک read model پیاده سازی CQRS می تواند حاوی materialized views یافته از داده های write model باشد، یا مدل  read model شده می تواند برای تولید materialized views استفاده شود.munication in a microservice architectureSaga pattern - Azure Design PatternsEvent Sourcing pattern - Azure Architecture CenterDesigning a DDD-oriented microservice</description>
                <category>danny</category>
                <author>danny</author>
                <pubDate>Sun, 25 Sep 2022 17:22:15 +0330</pubDate>
            </item>
                    <item>
                <title>Cloud Design Patterns - Backends for Frontends</title>
                <link>https://virgool.io/@dany_kh/cloud-design-patterns-backends-for-frontends-j1w15tl5lxku</link>
                <description>در این حالت backend servicesهای جداگانه ایجاد کنید تا توسط frontend applications یا interface  های  خاص مصرف شود. این الگو زمانی مفید است که بخواهید از سفارشی سازی یک Backend برای چندین interface یا رابط کاربری اجتناب کنید. این الگو اولین بار توسط Sam Newman توصیف شد.صورت مسئله:هدف گذاری تولید یک نرم افزار می تواند بر اساس یک رابط کاربری مبتنی بر desktop application  یا web ui  باشد.معمولا، یک سرویس backend به طور همزمان با سرویس frontend توسعه می یابد که که هر دوی این سرویس ها ویژگی های وابسته هم را ایجاد می کنند به طوری که اجرای صحیح یکی به دیگری وابسته است. همانطور که توسعه  برنامه رشد می کند، نیازمندی هایی جدیدی بوجود می آید که در روزهای اولیه طراحی نرم افزار در نظر گرفته نشده بودند مثلا یک برنامه mobile application هم در کنار دو سرویس قبلی شروع به توسعه می‌کند که باید با همان Backend تعامل داشته باشد. سرویس Backend به یک Backend همه منظوره تبدیل می‌شود که باید نیازهای رابط  desktop/web UI  و موبایل را برآورده کند.اما قابلیت های یک دستگاه تلفن همراه از نظر اندازه صفحه نمایش، عملکرد و محدودیت های نمایش به طور قابل توجهی با یک مرورگر دسکتاپ متفاوت است. در نتیجه، الزامات یک برنامه mobile application با رابط کاربری desktop/web UI متفاوت است.این تفاوت ها منجر به الزامات مختلفی برای backend می شود. سرویس backend نیاز به تغییرات منظم و قابل توجهی دارد تا هم به رابط کاربری وب دسکتاپ و هم به اپلیکیشن موبایل ارائه شود. اغلب، تیم‌های رابط جداگانه روی هر فرانت‌اند (موبایل و وب) کار می‌کنند و باعث می‌شوند که backend به گلوگاهی در فرآیند توسعه تبدیل شود. الزامات به‌روزرسانی متناقض، و نیاز به کارکردن سرویس برای هر دو فرانت‌اند، می‌تواند منجر به صرف تلاش زیادی برای سرویس backend شود.از آنجایی که فعالیت توسعه بر روی سرویس Backend متمرکز است، ممکن است یک تیم جداگانه برای مدیریت و نگهداری Backend ایجاد شود. در نهایت، این منجر به قطع ارتباط بین تیم‌های توسعه رابط کاربری و Backend می‌شود و باری را بر دوش تیم Backend می‌گذارد تا بین نیازهای رقابتی تیم‌های مختلف UI تعادل برقرار کند. هنگامی که یک تیم frontend به تغییراتی در Backend نیاز دارد، این تغییرات باید قبل از اینکه بتوان آنها را در Backend ادغام کرد، با سایر تیم‌های frontend در  mobile/web UI  هماهنگ شود.راه حل:برای هر رابط کاربری یک backend ایجاد کنید. رفتار و عملکرد هر backend را طوری تنظیم کنید که به بهترین وجه با نیازهای frontend مطابقت داشته باشد، بدون اینکه نگران تأثیرگذاری بر سایر frontend های دیگر باشید.از آنجایی که هر backend مخصوص یک frontend است، می توان آن را برای آن frontend بهینه کرد. در نتیجه، کوچک‌تر، پیچیده‌تر و احتمالاً سریع‌تر از یک Backend همه کاره است که سعی می‌کند الزامات همه frontend ها در mobile/web UI را برآورده کند. هر تیم رابط برای کنترل Backend خود استقلال دارد و به یک تیم توسعه بک‌اند متمرکز متکی نیست. این به تیم frontend انعطاف‌پذیری در انتخاب زبان، آهنگ انتشار، اولویت‌بندی حجم کار و یکپارچه‌سازی ویژگی‌ها در Backend خود می‌دهد. برای اطلاعات بیشتر دیدن این لینک توصیه می شود.مسائل و ملاحظات:در نظر بگیرید که چه تعداد Backend باید مستقر کنید.اگر frontendهای مختلف (مانند کلاینت‌های موبایل) درخواست‌های یکسانی ارائه می‌دهند، در نظر بگیرید که آیا لازم است یک Backend برای هر frontend پیاده‌سازی شود یا اینکه یک Backend واحد کافی است.هنگام پیاده سازی این الگو، احتمال تکرار کد در بین سرویس ها بسیار زیاد است.همینطور backend services متمرکز بر frontend فقط باید logic و behavior مربوط به client-specific را پیاده سازی کند. منطق business logic و سایر global features ها باید در جای دیگری از برنامه  مدیریت شوند.به این فکر کنید که چگونه این الگو ممکن است در مسئولیت های یک تیم توسعه منعکس شود و تاثیرگذار باشد.در نظر بگیرید که اجرای این الگو چقدر طول می کشد و هزینه زمانی ایجاد می کند. آیا تلاش برای ساخت بک‌اندهای جدید بدهی فنی بیشتری را به همراه داره نسبت به حالت یک backend همه منظوره؟چه زمانی از این الگو استفاده کنیم؟یک سرویس backend مشترک یا همه‌منظوره باید با سربار و مشکلات قابل توجهی  هنگام توسعه  حفظ شود.شما می خواهید backend را برای نیازهای frontend های specific client بهینه کنید.سفارشی‌سازی‌ها در یک backend همه‌منظوره برای تطبیق چندین frontend مختلف.این الگو در حالت‌های زیر مناسب نیست:هنگامی که frontend ها request های  مشابهی را به backend ارسال و دریافت می کنند.زمانی که تنها از یک frontend برای تعامل با backend استفاده می شود.</description>
                <category>danny</category>
                <author>danny</author>
                <pubDate>Sun, 25 Sep 2022 12:04:07 +0330</pubDate>
            </item>
                    <item>
                <title>Cloud Design Patterns - Anti corruption Layer</title>
                <link>https://virgool.io/@dany_kh/cloud-design-patterns-anti-corruption-layer-vu7oi4vhmuzn</link>
                <description>یک لایه façade  یا adapter بین زیرسیستم های مختلف که معنایی یکسانی ندارند پیاده سازی کنید. این لایه درخواست هایی را که یک زیر سیستم می کند به زیرسیستم دیگر ترجمه می کند. از این الگو استفاده کنید تا اطمینان حاصل کنید که طراحی یک برنامه توسط وابستگی به زیرسیستم های خارجی محدود نمی شود. این الگو اولین بار توسط Eric Evans در طراحی دامنه محور توصیف شد.طرح صورت مسئله:اکثر برنامه ها برای برخی داده ها یا عملکردها به سیستم های دیگر متکی هستند. به عنوان مثال، هنگامی که یک برنامه قدیمی به یک سیستم مدرن منتقل می شود، ممکن است همچنان به منابع قدیمی موجود نیاز داشته باشد. ویژگی های جدید باید قادر به فراخوانی سیستم قدیمی باشند. این به ویژه در مورد مهاجرت های تدریجی صادق است، جایی که ویژگی های مختلف یک برنامه بزرگتر به مرور زمان به یک سیستم مدرن منتقل می شود.اغلب این سیستم های قدیمی از مشکلات کیفی مانند طراحی داده های پیچیده و در هم تنیده یا API های منسوخ رنج می برند. ویژگی‌ها و فناوری‌های مورد استفاده در سیستم‌های قدیمی می‌تواند به طور گسترده‌ای با سیستم‌های مدرن‌تر متفاوت باشد. برای تعامل با سیستم قدیمی، برنامه جدید ممکن است نیاز به پشتیبانی از زیرساخت‌های قدیمی، پروتکل‌ها، مدل‌های داده، APIها یا سایر ویژگی‌هایی داشته باشد.حفظ دسترسی بین سیستم‌های جدید و قدیمی می‌تواند سیستم جدید را مجبور کند حداقل به برخی از APIهای سیستم قدیمی یا دیگر معنایی‌ها پایبند باشد. وقتی این ویژگی‌های قدیمی مشکلات کیفی دارند، توسعه برنامه مدرن که وابستگی به برنامه قدیمی را دارد تحت تاثیر قرار میدهد و کیفیت نهایی بخاطر مشکل طرح قدیمی، مطلوب نیست.مشکلات مشابهی ممکن است در مورد هر سیستم خارجی که تیم توسعه شما کنترل نمی کند، نه فقط سیستم های قدیمی، ایجاد شود.راه حل:زیرسیستم های مختلف را با قرار دادن یک لایه anti-corruption بین آنها جدا کنید. این لایه ارتباطات بین دو سیستم را ترجمه می کند و به یک سیستم اجازه می دهد بدون تغییر بماند در حالی که دیگری می تواند از به خطر افتادن طراحی و رویکرد تکنولوژیکی خود جلوگیری کند.Anti-corruption Layer pattern   نمودار بالا یک برنامه کاربردی با دو زیرسیستم را نشان می دهد. زیرسیستم A از طریق یک لایهanti-corruption به زیر سیستم B فراخوانی می کند. ارتباط بین زیرسیستم A و لایه anti-corruption همیشه از مدل داده و معماری زیرسیستم A استفاده می کند. تماس ها از لایه anti-corruption به زیر سیستم B مطابق با مدل یا روش های داده آن زیر سیستم است. لایه anti-corruption حاوی تمام منطق لازم برای ترجمه بین دو سیستم است. لایه را می توان به عنوان یک جزء در برنامه یا به عنوان یک سرویس مستقل پیاده سازی کرد.مسائل و ملاحظات:لایه anti-corruption ممکن است به تماس های برقرار شده بین دو سیستم تاخیر بیافزاید.لایه anti-corruption یک سرویس اضافی اضافه می کند که باید مدیریت و نگهداری شود.در نظر بگیرید که لایه anti-corruption شما چگونه scale خواهد شد.در نظر بگیرید که آیا به بیش از یک لایه anti-corruption نیاز دارید یا خیر. ممکن است بخواهید با استفاده از فناوری ها یا زبان های مختلف عملکرد را به چندین سرویس تجزیه کنید، یا ممکن است دلایل دیگری برای تقسیم لایه anti-corruption وجود داشته باشد.در نظر بگیرید که چگونه لایه anti-corruption در رابطه با سایر برنامه ها یا خدمات شما مدیریت می شود. چگونه در فرآیندهای نظارت، انتشار و پیکربندی شما یکپارچه خواهد شد؟اطمینان حاصل کنید که تراکنش ها و داده ها سازگاری دارند و قابل نظارت هستند.در نظر بگیرید که آیا لایه anti-corruption نیاز به مدیریت همه ارتباطات بین زیرسیستم های مختلف دارد یا فقط زیر مجموعه ای از ویژگی ها.اگر لایه anti-corruption بخشی از یک استراتژی ارتقا برنامه است، در نظر بگیرید که آیا دائمی خواهد بود یا پس از انتقال همه عملکردهای قدیمی بازنشسته می شود.چه زمانی از این الگو استفاده کنیم؟از این الگو زمانی استفاده کنید که:اینکه پروسه migrate  و ارتقا دادن برنامهاز حالت قدیم به جدید یک پروسه چند مرحله‌ای برنامه ریزی شده است، با توجه به اینکه یکپارچگی بین سیستم های جدید و قدیمی باید حفظ شود.دو یا چند زیرسیستم semantic متفاوتی دارند، اما همچنان نیاز به ارتباط دارند.اگر تفاوت semantic قابل توجهی بین سیستم های جدید و قدیمی وجود نداشته باشد، ممکن است این الگو مناسب نباشد.</description>
                <category>danny</category>
                <author>danny</author>
                <pubDate>Fri, 23 Sep 2022 22:13:23 +0330</pubDate>
            </item>
                    <item>
                <title>Cloud Design Patterns - Ambassador pattern</title>
                <link>https://virgool.io/@dany_kh/cloud-design-patterns-ambassador-pattern-rawsa2ulfe1e</link>
                <description>توی این پست می‌خوام در مورد دیزاین پترن های کاربردی در cloud software engineer یا  Cloud Design Patterns کلیاتی رو مطرح کنم. با توجه به انقلاب جدید در صنعت نرم افزار در حوزه پردازش ابری و محاسبات لبه و میکروسرویس و استفاده از ابزارهای مثل kubernetes , docker swarm , mesos نیازمند این هستیم که معماری مناسبی  رو برای این نوع برنامه‌ها پیش ببریم.در این پست از Cloud Design Patterns ها به سراغ Ambassador pattern میریم که در دو دسته Design and Implementation, Operational Excellence قرار میگیره و به طور خلاصه تعریفش میشه: سرویس‌های helper ایجاد کنیم که درخواست های شبکه را از طرف یک consumer service یا application ارسال کند.یک سرویس ambassador را می توان به عنوان یک پروکسی out-of-process در نظر گرفت که در کنار client قرار می گیرد. این الگو می‌تواند برای بارگیری وظایف مشترک اتصال client مانند monitoring، logging، مسیریابی، امنیت (مانند TLS) و الگوهای انعطاف‌پذیر  مفید باشد. اغلب با برنامه‌های قدیمی یا سایر برنامه‌هایی که اصلاح آن‌ها دشوار است، به منظور گسترش قابلیت‌های ارتباطی آنها استفاده می‌شود.طرح صورت مسئله:در cloud-based applications با قابلیت انعطاف عملکرد بالا، به ویژگی‌هایی مانند circuit breaking  routing، metering و monitoring  و توانایی ایجاد به‌روزرسانی‌های پیکربندی مرتبط با شبکه نیاز دارند. ممکن است به‌روزرسانی برنامه‌های قدیمی یا کتابخانه‌های کد موجود برای افزودن این ویژگی‌ها دشوار یا غیرممکن باشد، زیرا توسعه کد دیگر پشتیبانی نمی‌شود یا نمی‌توان آن را به راحتی توسط تیم توسعه اصلاح کرد.فراخوانی و درخواست های مکرر روی شبکه ممکن است به پیکربندی قابل توجهی برای connection, authentication, authorization نیاز داشته باشند. اگر این درخواست‌ها در چندین برنامه کاربردی که با استفاده از چندین زبان و framework ساخته شده‌اند، استفاده می‌شوند، درخواست‌ها باید برای هر یک از این حالت‌ها پیکربندی شوند. علاوه بر این، عملکرد شبکه و امنیت آن ممکن است نیاز به مدیریت یک تیم حرفه ای داشته باشد و این فقط تمام ماجرا نیست و معمولا در این شرایط یک پایگاه کد بزرگ هم داریم که به‌روزرسانی و کدهای اون سختی زیاد داره.راه حل:کتاب‌خانه‌ها و frameworks های client را در یک فرآیند خارجی قرار بدیم که به عنوان یک پروکسی بین برنامه شما و خدمات خارجی عمل می کنه. پروکسی را در همان محیط host برنامه خودمان مستقر کنیم تا امکان کنترل مسیریابی، انعطاف پذیری، ویژگی های امنیتی و جلوگیری از هرگونه محدودیت دسترسی مربوط به host را فراهم کند. همچنین می توانیم از الگوی ambassador برای استانداردسازی و گسترش دقیق سایر بخش‌های برنامه و ماژول های جدیدتر استفاده کنیم. پروکسی می‌تواند معیارهای عملکرد مانند latency یا استفاده از resource usage را monitor کند و این monitor  در همان محیط host برنامه انجام می‌شود.ambassador ایی از الگوی ویژگی هایی که برای ambassador واگذار می شوند را می توان مستقل از برنامه مدیریت کرد. می‌توانید بدون ایجاد اختلال در عملکرد قدیمی برنامه، ambassador را به‌روزرسانی و اصلاح کنید. همچنین به تیم‌های مجزا و تخصصی اجازه می‌دهد تا ویژگی‌های security, networking, or authentication که به ambassador منتقل شده‌اند را پیاده‌سازی و حفظ کنند. سرویس Ambassador را می توان به عنوان یک سرویس جانبی برای متصل کردن با  consuming application  یا سرویس های دیگر  استفاده کرد. از طرف دیگر، اگر یک Ambassador توسط چندین فرآیند جداگانه در یک host مشترک به اشتراک گذاشته شود، می تواند به عنوان یک daemon مستقر یا deploy شود. اگر سرویس مصرف کننده کانتینری باشد، Ambassador باید به عنوان یک کانتینر جداگانه در همان host ایجاد شود، با linkهای مناسبی برای ارتباط با سایر سرویس‌ها پیکربندی شده باشد.مسائل و ملاحظات:پروکسی مقداری سربار latency اضافه می کند. در نظر بگیرید که آیا interface یا کتابخانه client  که مستقیماً توسط برنامه فراخوانی می شود، رویکرد بهتری است یا خیر.تأثیر احتمالی گنجاندن ویژگی های تعمیم یافته یا ویژگی هایی که درآینده اضافه می شود را در پروکسی را در نظر بگیرید. مکانیزمی را در نظر بگیرید که به client اجازه می‌دهد تا مقداری context را به پروکسی و همچنین به client بازگرداند. برای مثال، headers های درخواست HTTP را برای انصراف از تلاش مجدد اضافه کنید یا حداکثر تعداد دفعات امتحان مجدد را مشخص کنید.نحوه package  و deploy پروکسی را در نظر بگیرید.در نظر بگیرید که آیا از یک نمونه مشترک برای همه clients استفاده کنید یا یک نمونه برای هر client. چه زمانی از این الگو استفاده کنیم؟از این الگو زمانی استفاده کنید که:نیاز به ایجاد مجموعه ای مشترک از ویژگی های ارتباطی با client  برای حالتی که چندین زبان برنامه نویسی یا framework های مختلف داریم.نیاز به کاهش مشکلات ارتباطی client  با نرم افزار  و جداسازی وظایف بین توسعه دهندگان زیرساخت باسایر تیم های تخصصی تر.نیاز به پشتیبانی یا راه اندازی cloud یا cluster ای در یک برنامه قدیمی یا برنامه ای که تغییر آن در ساختار cloud  دشوار است.این الگو ممکن است مناسب نباشد در حالتی که:زمانی که latency در درخواست شبکه بسیار مهم است. یک پروکسی مقداری سربار را ایجاد می‌کند، هرچند حداقل، و در برخی موارد ممکن است روی برنامه تأثیر بگذارد.وقتی در توسعه نرم افزار فقط از یک framework یا فقط از یک زبان برنامه نویسی خاص استفاده شده باشد. در آن صورت، یک گزینه بهتر ممکن است یک کتابخانه یا interface  برای client  باشد که به عنوان یک package بین تیم های توسعه استفاده شود.هنگامی که ویژگی های ارتباطی قابل تعمیم و سازگاری نیستند و نیاز به یکپارچگی عمیق تر با برنامه مشتری دارند.مثال:نمودار زیر برنامه‌ای را نشان می‌دهد که از طریق یک پراکسی ambassador به یک سرویس راه دور درخواست می‌دهد. Ambassador مواردی مثل routing, circuit breaking, logging به سیستم را فراهم می کند. سرویس راه دور را فراخوانی می کند و سپس پاسخ را به برنامه مشتری برمی گرداند.</description>
                <category>danny</category>
                <author>danny</author>
                <pubDate>Fri, 23 Sep 2022 18:33:15 +0330</pubDate>
            </item>
                    <item>
                <title>ماشین انیگما</title>
                <link>https://virgool.io/codenevis/%D9%85%D8%A7%D8%B4%DB%8C%D9%86-%D8%A7%D9%86%DB%8C%DA%AF%D9%85%D8%A7-okkybdxvaan1</link>
                <description>فیلم Imitation Game  رو به تازگی دیدم و  این فیلم در مورد ماشین انیگما که یه سیستم رمز گذاری برای ارتباط مخابراتی بین نظامی‌های آلمانی در جنگ جهانی دوم و شکستن این رمز توسط انگیسی‌ها به کمک آلن تورینگ بود.با توجه به چیزی که بالا نوشتم و سعی کردم یه نگاه دقیق‌تر به این ماشین رمزگذار بندازم. دستگاه نظامی Enigma، مدل &quot;Enigma I&quot;، در اواخر دهه ۱۹۳۰ و در طول جنگ استفاده می‌شدمنابعخب مهم‌ترین چیز در مورد این تحقیق منابع اون هستند و من برای سر در آوردن از طرز کار این ماشین این منابع رو بررسی کردم. ۱. لینک یوتیوب که یه مفهوم تصویری از این ماشین به ما میده۲. مقاله۳. ویکی‌پدیا که البته نگاه انداختن بهش در این مورد بسیار پرفایده هست.۴. مقالهحتما و حتما منبع شماره یک رو کامل ببینید در غیر این صورت، متوجه شدن مکانیزم این ماشین سخته. اگر هم خوندن این متن براتون سخته می‌تونید بعد از دیدن منبع شماره یک چند لحظه به آخرین عکس موجود در در این گزارش دقت کنید و متوجه بشید عملکرد این سیستم رو.متنی که در ادامه می‌نویسم از ترکیبی از چهار منبع بالا هست و تمرکز بیشتر روی منبع شماره ۴ هست که کد هم داره.خب اصلا ماشین انیگما دقیقا چیه؟ماشین‌های انیگما مجموعه‌ای از ماشین‌های رمز روتور الکترومکانیکی هستند. اولین ماشین ها در پایان جنگ جهانی اول توسط مهندس آلمانی آرتور شربیوس اختراع شد و عمدتاً برای محافظت از ارتباطات تجاری، دیپلماتیک و نظامی استفاده می شد. ماشین‌های انیگما پیچیده‌تر و پیچیده‌تر شدند و در طول جنگ جهانی دوم به‌شدت توسط ارتش آلمان برای رمزگذاری سیگنال‌های رادیویی مورد استفاده قرار گرفتنداز دستگاه انیگما برای رمزگذاری یا رمزگشایی پیام های انیگما استفاده می شد (رمزگذاری انیگما متقارن است، به این معنی که از تنظیمات یکسانی می توان برای رمزگذاری یا رمزگشایی یک پیام استفاده کرد).در این چالش ما یک برنامه رمزگذار انیگما برای رمزگذاری و رمزگشایی پیام ها با استفاده از تنظیمات خاص Enigma ایجاد می‌کنیم. اما قبل از انجام این کار، باید درک بهتری از نحوه عملکرد ماشین انیگما به دست بیاریم. برای این کار می‌تونیم از شبیه ساز آنلاین Enigma ما برای شروع رمزگذاری یا رمزگشایی پیام های مخفی استفاده کنیم که آخر مطلب لینک‌هاش رو گذاشتم.ماشین انیگما یک ماشین رمزگذاری نسبتاً پیچیده است که از چهار بخش اصلی تشکیل شده است:۱− صفحه کلیدصفحه کلید برای گرفتن ورودی پیام از کاربر استفاده می شود. ماشین انیگما یک ماشین رمزگذاری متقارن است. به این معنی که می توان از آن برای رمزگذاری یا رمزگشایی یک پیام با استفاده از تنظیمات یا کلید یکسان و مشابه استفاده کرد. بنابراین از صفحه کلید برای وارد کردن متن ساده ای که باید رمزگذاری شود یا متن رمزی که باید رمزگشایی شود استفاده می شود پس متوجه شدیم که اگر تنظیمات دو تا انیگما یکسان باشه از یکی شون  برای رمز گذاری و از اون یکی برای رمزگشایی استفاده کرد (البته میشه با همونی که رمز می‌کنه هم رمز گشایی کرد) .صفحه کلید آنها از 26 کلید برای هر حرف الفبا تشکیل شده است. یعنی پیام های رمزگذاری شده بدون هیچ فاصله یا علامت نقطه گذاری به یکدیگر متصل می شوند.توجه کنید که  صفحه کلید با حروف QWERTZ به جای QWERTY شروع می شود. بخاطر اینکه که در زبان آلمانی از حرف Z بیشتر از حرف ‌Y استفاده می شود.۲− صفحه سیم‌بندیهنگامی که یک کلید روی صفحه کلید فشار داده می شود، از صفحه سیم‌بندی عبور می کند که اولین مرحله از فرآیند رمزگذاری را فراهم می کند. این بر اساس اصول رمز جایگزین، نوعی رمزگذاری جابجایی است. برای راه‌اندازی صفحه‌کلید، از سیم‌های کوتاه برای اتصال جفت‌هایی از حروف استفاده می‌شود که جایگشت می‌شوند. به عنوان مثال در تصویر زیر حرف W با یک D جایگزین می شود و حرف D با یک W به عنوان سیم (قرمز) برای اتصال این دو حرف / دوشاخه استفاده می شود. به همین ترتیب حرف V به حرف Z و Z تبدیل به V می شود.در code book  تنظیمات صفحه سیم‌بندی یا پلاگین به صورت رو به رو ثبت می شود (با توجه به تصویر بالا) : DW VZ  در واقع code book  یا کتاب کد انیگما  لیستی از تنظیمات کلید روزانه و اسناد کمکی اون برای رمزگذاری یا رمز گشایی هست و برای تحقیق بیشتر این لینک رو ببینید.۳- چرخ‌دنده‌ها (روتورها)بعد از  صفحه سیم‌بندی، متن یا پیام به ترتیب از سه روتور عبور می کنه (از راست به چپ) که هر کدام با استفاده از ترکیب رمز جابجایی و رمز سزار آن را به طور متفاوت تغییر می ده! در engima M3 سه شیار روتور و سه یا پنج روتور برای انتخاب وجود دارد. هر روتور با استفاده از یک عدد رومی از I تا V شناسایی می‌شود. این موارد تنظیمات ماشین انیگما را فراهم می‌کنه: از کدام روتورها استفاده کنیم به چه ترتیبی آنها را قرار بدیم (در کتاب کد، این حالت به عنوان IV II III (روتورهای چپ، میانی و راست) ثبت میشه)  هر یک از پنج روتور با استفاده از یک رمز جابجایی/جایگزینی، حرف را به طور متفاوتی رمزگذاری می‌کنند و می‌توانند در دستگاه انیگما با تنظیمات حلقه متفاوت متصل شوند. تنظیم دیگر موقعیت اولیه روتورها است که  قرار است هر روتور را با کدام حروف شروع کنیم (مثلاً A/B/C../Z که گاهی اوقات در کتاب کد با استفاده از اعداد ثبت می شود (01 برای A، 02 برای B تا 26 برای Z) این یک تغییر در  Caesar Cipher ایجاد می‌کند. در دستگاه Enigma می توانیم با چرخاندن سه چرخ موقعیت روتورها را تغییر بدیم.  نسخه‌های مختلف Enigma (به عنوان مثال M4) شامل چهار روتور بود که فرآیند رمزگذاری و تعداد تنظیمات ممکن را حتی بیشتر می‌کرد.چیزی که شکستن کد انیگما را سخت می کنه این هست که با هر بار فشار دادن یک کلید، روتور سمت راست به اندازه 1 حرف می چرخد. این بدان معنی است که تنظیمات رمزگذاری به طور مداوم برای هر حرف از یک پیام تغییر می کند. همچنین به این معنی است که یک حرف متن ساده بسته به موقعیت آن در پیام به طور متفاوتی رمزگذاری می شود. روتورها نیز به یکدیگر متصل شده اند تا وقتی روتوری که در سمت راست قرار دارد به حرف خاصی برسد، روتور را در وسط فعال می کند تا یک حرف بچرخد. به طور مشابه وقتی روتور در وسط به یک حرف خاص می رسد، روتور سمت چپ را فعال می کند تا یک حرف بچرخد. اطلاعات بیشتر در مورد نحوه عملکرد روتورها را در این صفحه ویکی پدیا هستش.عمل scrambling روتورهای Enigma برای دو حرف متوالی نشان داده شده‌است که روتور سمت راست در حال حرکت در یک موقعیت بین آنها است.۴− بازتابندهرفلکتور نوع دیگری از ساختار مکمل چرخ دنده‌ها یا روتور داخل دستگاه هست. هنگامی که متن پیام از میان سه روتور از راست به چپ عبور میکنه، بازتابنده جریان الکتریکی را از طریق روتورها منعکس می‌کند و نامه رمزگذاری شده را از طریق روتورها از چپ به راست برای 3 مرحله دیگر رمزگذاری و سپس دوباره از طریق صفحه سیم‌بندی برای رمزگذاری ارسال می‌کند. رمز جایگزینی نهایی هنگام عبور از بازتابنده، یک رمز جایگشت نیز به حرف اعمال می‌کند.نسخه های مختلف بازتابنده در نسخه های مختلف ماشین های انیگما استفاده شد. هر بازتابنده رمز جایگشت متفاوتی را اعمال می کند. ماشین‌های Enigma M3 به یک بازتابنده UKW-B یا UKW-C مجهز بودند.۵- صفحه نمایش لامپیتخته چراغ آخرین مرحله از فرآیند رمزگذاری است و برای نشان دادن خروجی (حروف رمزگذاری شده) استفاده می‌شود. این لامپ از 26 لامپ برای هر حرف الفبا تشکیل شده است. نمودار زیر سفر یک نامه را از طریق فرآیند رمزگذاری Enigma M3 نشان میده و اگر بهش خوب دقت کنیم بدون درک عمیق موارد بالا میشه مکانیزم کلی ماشین انیگما رو از روی تصویر پایین متوجه شد.نمای کلی از فشار دادن یک کلید تا روشن شدن مقدار رمز شده آن در صفحه و مسیر حرکت طی شده جهت رمزگذاریکدهادر این مرحله سراغ کدهای اجرایی میریم که نمونه کد اجرایی  روی colab از این لینک و gist  این پروژه رو از این لینک می‌تونید ببینید</description>
                <category>danny</category>
                <author>danny</author>
                <pubDate>Sun, 20 Mar 2022 11:34:50 +0330</pubDate>
            </item>
                    <item>
                <title>رزپبری‌پای 4!!!    همه چیز در یک چیز</title>
                <link>https://virgool.io/codenevis/%D8%B1%D8%B2%D9%BE%D8%A8%D8%B1%DB%8C%D9%BE%D8%A7%DB%8C-4-%DB%8C%DA%A9-%D8%AA%D8%AC%D8%B1%D8%A8%D9%87-%D8%AC%D8%AF%DB%8C%D8%AF-jegpiokezo8p</link>
                <description> میخوام در مورد تجربه کار با یه محصول سخت افزاری جدید صحبت کنم و اون چیزی نیست جز    raspberry_pi4 یا به اصلاح rpi:در ابتدا لازمه بگم زمانی که من این به اصلاح embedded board  رو خریده بودم، قطعات جانبی مثل آداپتور و جعبه و فن و هیت‌سینک مناسب براش کم بود، اون اوایل خیلی هم سخت گیر می‌آمد این قطعات جانبی و مثلا آداپتور 5 ولت 3 آمپر رو به سختی تهیه کردم و به نوعی با دستکاری محدودی به این دستگاه وصل کردم.از مزایای این بورد بخوام براتون بگم اینکه بین ۲ تا ۸ گیگ بسته به بودجه و نیازتون رم داره‌ و یه پردازنده arm  از نوع ۶۴ بیتی هم داره و قابلیت ارتباط با دو تا مانیتور هم زمان رو هم داره و وای فای و بلوتوث و کلی gpio   همینطور می‌تونید کلی سیستم عامل مبتنی بر معماری ARM از اندروید گرفته تا ubuntu arm و kali arm  رو نصب کنید روش و به عنوان یه دسکتاپ یا یه سرور شخصی ازش استفاده کنید.تصویر RPI4 به طور کلی برای کارای روتین‌ و وب گردی و فیلم دیدن یا صرفا بازی کردن و انجام کارای روزانه مثل نوشتن گزارش و... می‌تونه گزینه خوبی باشه خصوصاً به عنوان دانلود سنتر، اگه دانلود زیاد دارید و به صرف نیست لپتاپ یا PC رو روشن نگه دارید.به عنوان معرفی بد نیست ببینید که  در این تصویر یه نوع دبیان مخصوص خودش رو که بهش raspian میگند رو داریم. Raspbian 2019.04 Desktop  در اینجا تصاویری از محیط سیستم عامل retroPie رو داریم که با استفاده از بر اساس retroarch هست کلی کنسول بازی رو بهمون میده.retropie menuو در این تصویر محیط یک بازی رو داریم، البته از آتاری گرفته تا بازی های ps2 (شایدم ps3 ) رو میدونم میشه روی این سیستم اجرا کرد، البته بعد از نصب retropie باید دنبال rom یا به اصطلاح «رام» اون بازی ها تو سطح نت بگردید و به دایرکتوری کنسول اون بازی اضافه‌اش کنید.در نهایت اگه دنبال برنامه نویسی هم هستید می تونید ادیتور مورد علاقه تون رو روش بریزید و تقریبا به اکثر زبان های برنامه نویسی مثل جاوا/پایثان(پایتون)/ سی++/راست و... کد بزنید ادیتور vs code  روی رسپبری پایاگر به طور خلاصه مزایا یا معایب این سری جدید رزپبری‌پای رو بخوام بگم ایناست:مزایا:- یه جور دسکتاپ خونگی برای کارای معمولی خصوصا این روزا که PC و LapTop  گرون شده.- یه سیستم کم صدا و جمع و جور برای دانلود.- هوم سنتر برای بازی یا فیلم دیدن یا تبدیل تلویزیون معمولی به هوشمند.- اگه برنامه نویسی معمولا زبان‌های اسکریپتی کار میکنید گزینه خوبیه برای برنامه نویسی.- ارزون در میاد حدودا نسبت به کاربردی که داره بسته به مقدار RAM اش، من خودم با رم 2 گیگ و سایر همه ابزار جانبی مثل فن و کارت حافظه و... حدود 1.3 میلیون برام هزینه داشت و الان کمتر کاری هست که ازش نکشم از برنامه نویسی گرفته تا وب گردی و فیلم دیدن و... - کارهای مرتبط با هوش مصنوعی و ماشین لرنینگ و خصوصا اینترنت اشیا و در نهایت شیطنت های سخت   افزاری و سرور خونگی.معایب:- راه انداختنش شبیه موبایل نیست اینکه فقط لازم باشه دکمه روشن شدن رو چند ثانیه نگه دارید و نیاز به کمی فنی بودن داره.- نیاز به خرده ریز داره مثلا منبع تغذیه مناسب و هیت سینک و مبدل hdmi و فن، کارت حافظه و... کلا باید یه کمی مطالعه داشته باشید که کدوم قطعاتش رو کجا گیر بیارید یه جورایی مثل این هست که بخواین PC جمع کنید و باید جزییات خرید رو بدونید.- اینکه یک سری باگ‌های ریز داره و به مرور زمان با اینجور باگ ها و برطرف کردنش آشنا می‌شوید.در نهایت فکر می‌کنم  در آینده نزدیک این سیستم یه تحویل بزرگی در حوزه کامپیوتر ها اجرا کنه و باع بشه لپتاپ‌ها و PC فوق ارزون قیمت و کم مصرف و پر بازدهی رو داشته باشم، مثلا یه نمونه اش  این لینک هستش که بر مبنی یه نوع embedded board  مثل همینه.مواد لازم: لازم دونستم لیست قطعات و وسایل لازم جهت راه اندازی‌اش رو هم اضافه کنم، اکثر مواقع از همون جایی که بوردش رو تهیه میکنید وسایل جانبی اش رو هم دارند که توی زیر مینویسم چیاست:1-  سه یا چهار عدد هیت سینک2- فن مخصوص رسپبری3- مبدل VGA به میکرو HDMI شبیه این لینک و  اگه پیدا نشد این مدل هم بد نیست ولی یه مبدل HDMI  به میکرو HDMI  این مدلی هم باید بخرید.4- آداپتور 3 آمپر دارای خروجی USB-C . در ضمن آداپتور اصلی راسپبری یه مقداری گرونه ولی جایگزین ارزون ترش هم میشه استفاده کرد.5- کارت حافظه پرسرعت و مرغوب ترجیحا 8 گیگ به بالا.6- جعبه رزبپری پای ترجیحا روزنه هوا برای نصب فن هم داشته باشه و همینطور نصب هیت سینک توش ممکن باشه.7- موس و کیبورد ترجها wireless یا  مینی کیبورد تهیه کنید.</description>
                <category>danny</category>
                <author>danny</author>
                <pubDate>Sat, 08 Aug 2020 00:08:55 +0430</pubDate>
            </item>
                    <item>
                <title>ریموت خودرو با WIFI (یک پروژه از نوع IOT)</title>
                <link>https://virgool.io/@dany_kh/%DB%8C%DA%A9-%D9%BE%D8%B1%D9%88%DA%98%D9%87-%D8%A7%D8%B2-%D9%86%D9%88%D8%B9-iot-ygdygavqw6p3</link>
                <description>این پروژه یک نوع ریموت ماشین هست که توسط گوشی کنترل میشه، اصل برنامه تو این لینک وجود داره و فیلم اجرای این برنامه هم تو این لینک هست ولی مسئله ای هست که برنامه مذکور برای کنترل روشنایی خونه به کار میره و نیاز به وصل شدن به یه مودم به عنوان Host رو داره ولی در اینجا اون مشکل رو برطرف کردیم خب! برای باز کردن درب ماشین مودمی که باید Host باشه رو از کجا گیر بیاریم!!!؟ این یعنی یعنی سیستم مذکور توسط ماژول وای فای node mcu و وای فای خود گوشی کنترل میشه و به چیز دیگه ای نیاز نیست، در نهایت یه رمز و ورود هم به برنامه گذاشیم چون ممکنه گوشی دزدیده بشه و هر کسی بتونه درهای ماشین رو باز و بسته کنه.مواد لازم:1 عدد node mcu 1 عدد گوشی1 عدد کابل usb اندرویدمحیط توسعه آردواینومراحل اجرا:ابتدا باید وسایل مورد نیاز بالا رو تهیه کرد و خیلی راحت میشه فروشگاه هایی رو جهت خرید موارد بالا در سطح اینترنت پیدا کرد.بعد به محیط توسعه آردواینو میریم و طبق این دستورالعمل کتابخونه پیکج راه اندازی node mcu یا esp8266 رو راه می‌اندازیم.حالا می‌تونیم توسعه و ریفکتور پروژه که نوشتم رو در اینجا بیابید و ازش استفاده کنید. اگه مشکلی در راه اندازی اش داشتید تو صفحه گیتهاب پروژه مطرح اش کنید.عکس های از پروژه :عکس صفحه لاگینعکس صفحه کنترل</description>
                <category>danny</category>
                <author>danny</author>
                <pubDate>Mon, 18 Feb 2019 23:35:14 +0330</pubDate>
            </item>
            </channel>
</rss>