<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
    <channel>
        <title>نوشته های AmirHossein JavanAmoli</title>
        <link>https://virgool.io/feed/@amsjavan</link>
        <description></description>
        <language>fa</language>
        <pubDate>2026-06-17 21:55:51</pubDate>
        <image>
            <url>https://files.virgool.io/upload/users/2826/avatar/OnfCE6.jpeg?height=120&amp;width=120</url>
            <title>AmirHossein JavanAmoli</title>
            <link>https://virgool.io/@amsjavan</link>
        </image>

                    <item>
                <title>چرا گوگل از ریپوزیتوری مشترکی با حجم ۸۶ ترابایت استفاده می‌کند</title>
                <link>https://virgool.io/baleacademy/%DA%86%D8%B1%D8%A7-%DA%AF%D9%88%DA%AF%D9%84-%D8%A7%D8%B2-%D8%B1%DB%8C%D9%BE%D9%88%D8%B2%DB%8C%D8%AA%D9%88%D8%B1%DB%8C-%D9%85%D8%B4%D8%AA%D8%B1%DA%A9%DB%8C-%D8%A8%D8%A7-%D8%AD%D8%AC%D9%85-%DB%B8%DB%B6-%D8%AA%D8%B1%D8%A7%D8%A8%D8%A7%DB%8C%D8%AA-%D8%A7%D8%B3%D8%AA%D9%81%D8%A7%D8%AF%D9%87-%D9%85%DB%8C%DA%A9%D9%86%D8%AF-ug8s0518omyl</link>
                <description>ورژن کنترل چیست؟ابزاری است برای مدیریت تغییرات مجموعۀ اطلاعاتی مثل سورس کد، نوشتار و... . این ابزار در جایی که چندین نفر بخواهند روی منبعی مشترک کار کنند، اهمیت پیدا می‌کند.انواع ورژن کنترلCentralized Version Control System &#40;CVCS&#41;ارتباط به‌صورت کلاینت/سرور است. به این صورت که ریپوزیتوری در یک یا چندین سرور مستقر شده است و کلاینت‌ها به آن متصل می‌شوند و تغییرات خود را اعمال می‌کنند. SVN و CVS مثال‌های محبوبی از CVCS هستند.Distributed Version Control System &#40;DCVS&#41;علاوه بر سرور مرکزی هر کلاینت یک نسخه از ریپوزیتوری را به‌صورت لوکال دارد. تغییرات در ریپوی لوکال انجام می‌شود و در نهایت با ریپوی مرکزی همگام‌سازی می‌شود. Git و Mercurial مثال‌هایی از DCVS هستند.گوگل CVCS مختص خود را توسعه داده که Piper نام دارد.اطلاعاتی دربارۀ مقیاس ریپوی گوگلمجموع تعداد فایل‌ها:‌ یک میلیارد؛تعداد فایل‌های سورس کد: نُه میلیون؛تعداد خطوط کد: دو میلیارد؛تعداد کامیت: سی‌وپنج میلیون؛حجم محتوا : هشتادوشش ترابایت؛تعداد کامیت در روز : ‌چهل هزار.ده‌ها هزار توسعه‌دهنده روی این ریپوی مشترک کدنویسی می‌کنند.چرا گوگل از گیت استفاده نمی‌کند؟اولین قدم برای توسعۀ پروژه‌ای که با گیت نگهداری می‌شود، clone یا به‌عبارتی دریافت یک کپی از آن پروژه در workspace محلی است. آیا منطقی است ۸۶ ترابایت کد را clone کنیم؟در پروژه های گیت توصیه می شود که از ریپوهای کوچک استفاده کنید. بنابراین اگر گوگل می‌خواست ‌از گیت استفاده کند، مجبور بود ریپوی بزرگ خود را به هزاران ریپوی کوچک‌تر تبدیل کند که در ادامه دلایل انجام‌ندادن چنین کاری توضیح داده شده است. البته در حال حاضر، گوگل برای کدبیس اندروید از هشتصد ریپوی مستقل گیت استفاده می‌کند.علاوه بر این، گوگل تلاش‌هایی برای مقیاس‌پذیرترکردن برخی distributed version controlهای اوپن‌سورس مثل Mercurial کرده است. این همکاری با کمک جامعۀ اوپن‌سورس Mercurial و برخی شرکت‌هایی انجام شده است که به استفاده از مونو ریپو تمایل داشتند.گوگل چگونه چالش بزرگ ریپو را حل کرده است؟به‌جای اینکه کل ریپو کپی شود، فقط فایل‌هایی که به تغییر نیاز دارند، در workspace کپی می‌شوند. توسعه‌دهندگان قبل از تغییر ابتدا یک کپی از فایل مدنظر در workspace خود ایجاد می‌کنند. workspaceها برای کد ریویو با دیگر توسعه‌دهنده‌ها به‌اشتراک گذاشته می‌شوند و بعد از تأیید در ریپوی مرکزی کامیت می‌شوند. فرایند Piper در شکل نشان داده شده است.Piper Workflowمدل branchingدر گوگل کدنویسی روی branchها کاری غیرمعمول است و خیلی به‌ندرت چنین اتفاقی می‌افتد. تنها branch مجاز release است. حتی باگ فیکس هم در برنچ اصلی انجام می‌گیرد و روی برنچ ریلیز cherry pick می‌شود.مدل Branchingآیا دسترسی به همۀ کدها وجود دارد؟ورژن کنترل Piper امکان تعریف دسترسی در سطح فایل را دارد. بیش از ۹۹درصد فایل‌هایی را که در Piper ذخیره شده است، تمامی توسعه‌دهنده‌های تمام‌وقت مشاهده می‌کنند. بعضی کانفیگ‌های حیاتی و همچنین برخی الگوریتم‌های خاص دسترسی محدود دارند. همچنین خواندن و نوشتن در فایل‌ها لاگ می‌شود. اگر سهواً اطلاعات حساسی تغییر کند، امکان رول‌بک وجود دارد.فلوی گوگل روزانه هزاران توسعه‌دهنده روی این ریپو هزاران کامیت انجام می‌دهند. برای جلوگیری از بروز مشکل، گوگل ابزاری برای آزمایش خودکار پیاده‌سازی کرده است که وابستگی‌های هر تغییر را تشخیص می‌دهد و آن‌ها را rebuild می‌کند و اگر خطایی رخ دهد، تغییرات به‌صورت خودکار رول‌بک می‌شوند. ابزارهایی هم برای ارزیابی کیفیت کد پیاده‌سازی شده است. همچنین مالک‌های پروژه باید تمامی کدها را قبل از کامیت، ریویو کنند.مزایا و معایبهر تصمیم، نوعی trade-off است و نمی‌توان یک نسخه برای همۀ شرکت‌ها و فرهنگ‌ها ارائه کرد. در ادامه از نگاه گوگل مزیت‌ها و معایب monorepo ارائه می‌شود. در برخی موارد تجربه مختصری از چالش هایی که در «بله» با آن مواجه شده‌ایم نیز بیان شده است.مزیت‌هاUnified versioning, one source of truthنیازی به آرتیفکت‌کردن و ورژن‌زدن کتابخانه‌ها نیست و مستقیماً در کد به آن‌ها دسترسی داریم.Extensive code sharing and reuseاز تکرار و کپی کدهای مشترک جلوگیری می‌شود؛ برای مثال در «بله» برای فرار از پیچیدگی کتابخانه‌کردن کدهای مشترک برخی از توسعه‌دهندگان کدهای مشترک مورد نیاز را در پروژه‌ها کپی می‌کردند. در مدل مونو ریپو به‌علت سادگی استفاده از کدهای مشترک، احتمال بروز چنین مشکلاتی کمتر است. علاوه بر این به‌علت یکجابودن کدها، توسعۀ ابزاری برای جلوگیری از کپی‌کردن کدهای مشترک ساده‌تر خواهد بود.Simplified dependency managementمسئله diamond dependency در شرایطی پیش می‌آید که کتابخانۀ A به B و C وابستگی دارد و B و C هم به D وابستگی دارند؛ اما B به نسخۀ یک از D، و C هم به نسخۀ دو از D نیاز دارد. در این شرایط معمولاً در بیلدکردن A به‌مشکل می‌خوریم؛ زیرا هم‌زمان به دو نسخۀ متفاوت از این کتابخانه نیاز است و ممکن است یکی از نسخه‌ها دیگری را نقض کند. در این شرایط ممکن است بهترین اتفاق کامپایل‌ارور باشد و بدترین اتفاق دان‌شدن هنگام عملیاتی‌کردن نسخۀ جدید. :) در مونو ریپو مسئلۀ diamond dependency کمتر اتفاق می‌افتد.همچنین وجود کل سورس کد در یک ریپو این مزیت را دارد که توسعه‌دهندگان core libraryها خیلی راحت‌تر می‌توانند تست و بنچ‌مارک بنویسند‌. زیرا با تغییر هر کتابخانه، تمامی تست‌های کدهایی که به آن کتابخانه وابسته هستند، اجرا می‌شوند و مشکل در لحظه مشخص می‌شود؛ اما در حالتی که ریپوها جداست، باید نسخه داده شود و تمامی پروژه‌هایی که به این کتابخانه وابسته هستند، به‌روزرسانی شوند و تست‌های خودشان را ران کنند تا نقص و اشکالات آن مشخص شود که کاری زمان‌بر و پرهزینه است.Diamond DependencyAtomic changesچندین تغییر مرتبط باهم در یک کامیت یا یک پول‌ریکوئست انجام می‌شود؛ برای مثال، در «بله» برای تعریف api جدید، مجبور به تغییر سه پروژه مختلف بودیم و هم‌زمان سه تا پول‌ریکوئست باید می‌دادیم و همه هم باید باهم مرج می‌شد تا ناسازگاری پیش نیاید. در مدل monorepo همۀ این‌ها خیلی ساده‌تر و با یک پول‌ریکوئست به‌انجام می‌رسد؛ چون کنار هم و در یک ریپوی هستند.Large-scale refactoringاز آن‌جا که وابستگی‌ها در یک پروژه هستند، عملیات ریفکتور خیلی راحت‌تر می‌شود. در ریپوهای مستقل هنگام ریفکتور پروژه‌هایی که وابستگی‌های زیادی به آن وجود دارد، نیاز هست که پروژه‌های وابسته شناسایی شده و آن ها نیز به طور مستقل تغییر داده شوند. اما در ریپوی مشترک همه تغییرات به صورت یکجا و با ریسک کمتری انجام می‌شود.Collaboration across teamsدسترسی همۀ تیم‌ها به کدهای یکدیگر، منجر به فرهنگی می‌شود که به‌جای مطالعۀ مستندات، کدهای یکدیگر را مطالعه کنند و این اتفاق همکاری و تعامل بیشتر بین تیم‌ها را به‌همراه دارد.Code visibility and clear tree structureفهم ساختار کلی پروژه و ارتباط بین آن‌ها ساده‌تر است؛ زیرا مرزی بین repository وابستگی‌ها وجود ندارد.هزینه‌هاTooling investments for both development and executionباتوجه‌به بزرگ‌بودن مقیاس repository، ابزارهای متداول و اوپن‌سورس توانایی مدیریت و نگهداری این حجم از کد را ندارند و باید ابزارهای مختصِ چنین ابعادی را توسعه داد.Codebase complexityازآنجاکه ایجاد وابستگی در monorepo خیلی ساده است، اتفاق متداولی است که تیم‌ها دربارۀ گراف وابستگی فکر نکنند و ناخودآگاه وابستگی‌های غیرضروری ایجاد می‌شود.Effort invested in code healthابزارهایی مختص بررسی سلامت کد باید ایجاد شود. برای مثال گوگل ابزارهای بخصوصی برای تشخیص خودکار کدهای تکراری و کدهای بلااستفاده توسعه داده است.برگرفته از مقالۀ Why Google Stores Billions of Lines of Code in a Single Repository</description>
                <category>AmirHossein JavanAmoli</category>
                <author>AmirHossein JavanAmoli</author>
                <pubDate>Mon, 24 Feb 2020 13:13:03 +0330</pubDate>
            </item>
                    <item>
                <title>سرویس های stateful در برابر سرویس های stateless</title>
                <link>https://virgool.io/apieco/%D8%B3%D8%B1%D9%88%DB%8C%D8%B3-%D9%87%D8%A7%DB%8C-stateful-%D8%AF%D8%B1-%D8%A8%D8%B1%D8%A7%D8%A8%D8%B1-%D8%B3%D8%B1%D9%88%DB%8C%D8%B3-%D9%87%D8%A7%DB%8C-stateless-q8tkva2g8l1m</link>
                <description>مقدمهبرای مدت ها سرویس‌های stateful انتخاب اصلی توسعه‌دهندگان بود، اما امروزه استفاده از container ها و ابزار‌های مدیریت container به خصوص داکر و kubernetes به ابزاری همه‌گیر برای مدیریت و مقیاس کردن سیستم‌های توزیع شده، تبدیل شده است.kubernetes ابزار بسیار مناسبی برای مدیریت سرویس های stateless می‌‌باشد اما توسعه و مدیریت سرویس داده محور  و stateful همچنان چالش برانگیز است.در این مقاله مروری برای مزایا و معایب سرویس های stateful و stateless خواهیم داشت.سرویس stateful و stateless چیستسرویس stateful برای پاسخ‌گویی به درخواست‌ها از وضعیت داخلی خود استفاده می‌کند و به ازای هر درخواست به دیتابیس کوئری نمی‌زند. به عبارتی استیت مورد نیازش را در حافظه کَش می‌کند. در مقابل سرویس stateless از دیتابیس و یا سرویس های کش برای نگهداری وضعیت خود استفاده می کند.مشکل سرویس های stateful فرض کنید دو نمونه از یک اپلیکیشن stateful یکسان داریم. از یک لودبالانسر برای توزیع بار درخواست‌ها بین این دو سرویس استفاده می‌کنیم. اولین درخواست به سرویس شماره یک می رود و دومین درخواست به سرویس شماره دو، از آنجا که سروییکس  در استیت خودش وضعیت لاگین را true کرده است درخواست دوم متوجه لاگین بودن نمی شود. این مشکل از آنجا ناشی می شود که استیت دو تا سرویس یکسان و فعال با یکدیگر سینک نیستند.یک راه توزیع چنین سرویس هایی استفاده sharding است که ابزارهایی مثل akka برای چنین جنس سرویس هایی طراحی شده اند.اکتورهای akka ذاتا stateful هستند زیرا اکتور بدون  استیت یکی از مزیت های اصلی خود را از دست می دهد و در دنیای اکتور هم anti-pattern به حساب می آید. بنابراین اپلیکیشن هایی که با اکتور نوشته می شوند از این جنس هستند و باید به این صورت توزیع شوند.مزایای سرویس های statefulمدیریت consistency بدون نیاز به lock :‌ با استفاده از sharding می توان توزیع شدگی را بدون ایجاد lock پیاده سازی کرد.پاسخگویی سریع تر به درخواست ها : از آنجا که داده ها در حافظه خود سرویس نگهداری می شود، دسترسی به آن ها نیز سریع تر خواهد بود.سرویس های stateless برای پاسخگویی به هر درخواست به دیتابیس و یا کش سرور کوئری می‌زنند. این نوع سرویس ها استیت خود را در سرور ذخیره نمی کنند و همه داده‌های مورد نیاز این سرویس‌ها در دیتابیس و کش ذخیره سازی می شود.این جنس سرویس ها هیچ استیتی را در رم و یا دیسک خود ذخیره سازی نمی کنند و وابسته به سرویس های دیگری برای ذخیره سازی استیت هستند.مزایای سرویس های statelessایزولیشن بین استیت و رفتار :‌ توسعه معمولا بر روی رفتار هست و ناپایداری در سرویس رفتار تاثیری روی استیت نمی گذارد و همچنین هنگام نسخه دادن نیازی به ریستارت سرویس های استیت نیست.استقلال بین استیت و رفتار :‌ این استقلال امکانی را به ما می دهد که از ابزار مناسب مختص هر کار استفاده کنیم. برای مثال JVM و  Managed Memory ابزار مناسبی برای کش نیست زیرا مقدار حافظه محدودی دارد و همچنین مکانیزم Garbage Collector کارایی چنین سرویس هایی رو کاهش می دهد. در مقابل سرویس هایی مثل ردیس که با C نوشته شده اند برای چنین کاربردهایی بسیار مناسب‌تر  هستند.افزایش سرعت بروزرسانی سرویس‌ها :‌ با هر نسخه نیازی به بروز رسانی سرویس های استیت نداریم.ریپلیکیت سرویس ها : در لحظه چندین سرویس یکسان می تواند فعال باشد که در صورت نیاز به بروزرسانی، فقط با فوروارد کانکشن ها، درخواست ها و عملیات آن ها به  سرویس مورد نظر فوروارد خواهد شد.باکت تستینگ : پردازش درخواست ها در همان‌جایی که کانکشن متصل هست انجام می شود. بنابراین با جدا کردن کانکشن کاربرهای مورد نظر می توان به سادگی و بدون نوشتن کد اضافه باکت تست را پیاده سازی کرد.برون سپاری :‌پیدا کردن متخصص پستگرس و ردیس خیلی راحت تر از متخصص akka cluster هست! همچنین سرویس هایی مثل ردیس و پستگرس در سرویس‌های کلود  مثل آمازون و  گوگل ارائه می‌شوند که می توان نگهداری این سرویس ها را به شرکت هایی که تخصص این کار را دارند سپرد.مالتی دیتاسنتر : در مالتی دیتاسنتر باید استیت تمامی کاربران در دو دیتاسنتر وجود داشته باشد در نتیجه نیاز به سینک شدن دیتاسنترها به ازای تغییر استیت ها داریم که این در سیستم های statsful چالش برانگیز است.استفاده بهینه از رم : در مجموع کاهش کارایی در نتیجه ی خواندن استیت ها از DB در سیستم های statesless نسبت به کاهش تعداد سرورها موردنیاز برای این سیستم در مقایسه با statefulها بسیار بسیار ناچیز است هر چند همان کاهش کارایی را میتوان با استفاده از DBهای مقیاس پذیر مانند کاساندرا و استفاده از کش های میانی سرور و DB مانند redis، جبران کرد.کاهش تعداد نودها و در نتیجه کاهش هزینه نگهداری : نیازی نیست مدیریت کلاستر در سطح سرویس هایی که ما توسعه دادیم انجام بشود و به عهده سرویس های اوپن سورس و پایداری مثل کاساندرا و ردیس خواهد بود.کاهش پیچیدگی برنامه نویسی:‌ در واقع پیچیدگی از سطح سرویس ما به سرویس هایی که وظیفشون مدیریت چنین پیچیدگی هایی است انتقال پیدا می کند.معایب سرویس‌های stateless برای consistency باید از lock استفاده کنیم و یا راه حل های دیگر همزمانی مثل CSP و غیرهتاخیر رفت و برگشت شبکه برای دریافت دادهنظرات برخی از شرکت هاشرکت Netflixدر کنفرانس GoTo سال ۲۰۱۶ شرکت Netflix ارائه ای با عنوان Microservices at Netflix Scale برگزار می کند. در این ارائه ادعا می کند که سرویس ها باید stateless باشند. یکی از علت های چنین ادعایی نتیجه ای است که از Chaos Testing به دست آورده اند.Chaos Testing و به طور کلی تر Chaos Engineering به مجموعه تمهیداتی گفته می‌شود نرم‌افزار را در محیط واقعی یا اصطلاحاً Production Environment زیر بار فشارهای مختلفی قرار دهند تا در نهایت دریابند که سرویس مذکور تا چه حد تحمل شرایط غیرمنتظره را دارا است. برای اطلاعات بیشتر به لینک زیر مراجعه کنیدhttps://tinyurl.com/yxrbmhaqشرکت Lightbendشرکت lightbend توسعه دهنده فریم ورک آکا و یکی از مدعیان اصلی سرویس های stateful است. این شرکت در مقاله که در ادامه بخشی از آن نقل قول شده است توضیح می دهد که سرویس های stateful برای چه کاربردهایی مناسب تر هستند.چکیده ای از مقاله Design Techniques for Building Stateful از lightbendاینجا به دو تا از مزیت های stateless اشاره کرده:کاهش پیچیدگی برنامه نویسیکاهش پیچیدگی های مربوط به نگهداری استیتاینجا هم به نکته بسیار مهمی اشاره شده که سسیتم های stateful برای Realtime Streaming Data بسیار مناسب هستند و برای دیگر کاربردها stateless ها به اندازه کافی خوب هستند.نتیجه گیریاگرچه سرویس های stateless سربار کوئری زدن به دیتابیس را دارند اما به شدت مقیاس پذیر هستند.با توجه به توضیحات داده شده اکتورها در دنیای stateless کاربرد چندانی نخواهند داشت. همچنین  هزینه نگهداری سرویس های stateless بسیار پایین تر از سرویس های stateful هست.سسیتم های stateful برای Realtime Streaming Data بسیار مناسب‌تر هستند و برای دیگر کاربردها stateless ها به اندازه کافی خوب هستند.در انتها از دوستان خوبم سید مصطفی مشکاتی و امین پایدار تشکر می کنم که من را در نگارش این مقاله یاری کردند.مراجعمقاله ای عالی از lightbend که تفاوت و کاربرد stateful و stateless رو به خوبی نشان داده استhttps://www.lightbend.com/blog/design-techniques-stateful-cloud-native-applications-resilience-recoverability-scalabilityکنفرانس GoTo با موضوع Microservices at Netflix Scalehttps://www.dideo.ir/v/yt/57UK46qfBLYاسلایدهاhttps://drive.google.com/file/d/1AkIp9eabmyXhD7un4g-obh9eG-UtM52Z/view?usp=sharingمقاله برای تبیین تفاوت های سرویس های stateless و statefulhttps://www.xenonstack.com/insights/what-are-stateful-and-stateless-applications/مقاله ای از lightbend برای طرفداران stateful  :)https://drive.google.com/file/d/1WBachZCQSHfetvg9nZTUkcKISHnpiwvm/view?usp=sharing</description>
                <category>AmirHossein JavanAmoli</category>
                <author>AmirHossein JavanAmoli</author>
                <pubDate>Tue, 13 Aug 2019 16:59:15 +0430</pubDate>
            </item>
            </channel>
</rss>