Syntax | سینتکس – Telegram
چرا Code-level Monolith معماری برنده است؟ (درس‌هایی از Grafana Loki)

دوراهی مونولیت یا میکروسرویس:
از یک طرف، مونولیت (Monolith) ساده است اما اگر بد نوشته شود به "کد اسپاگتی" تبدیل می‌شود.
از طرف دیگر، میکروسرویس (Microservices) مقیاس‌پذیر است اما شما را در جهنمی از پیچیدگی‌های شبکه، دیپلوی و مدیریت ۵۰ کانتینر مختلف غرق می‌کند.

اما اگر راه سومی وجود داشته باشه چی؟ راهی که در آن کدتان را "مثل میکروسرویس" می‌نویسید، اما آن را "مثل مونولیت" اجرا می‌کنید.

در معماری Code-level Monolith، شما مرزهای سرویس‌هایتان را کاملا رعایت می‌کنید. یعنی سرویس Auth و سرویس Order کدهای کاملا جداگانه‌ای دارند (درست مثل میکروسرویس).
اما در زمان بیلد (Build Time)، به جای اینکه آنها را در کانتینرهای جداگانه بسته‌بندی کنید، همه را در یک فایل اجرایی (Binary) واحد لینک می‌کنید.

شعار این معماری:
> *"میکروسرویس در توسعه، مونولیت در اجرا."*

جادوی Grafana Loki و Tempo

بهترین مثال زنده این معماری در دنیا، ابزارهای شرکت Grafana Labs (مانند Loki برای لاگ، Tempo برای تریس و Mimir برای متریک) هستند.

سورس کد Grafana Loki از اجزای مختلفی تشکیل شده است:
* Ingester (دریافت لاگ)
* Distributor (توزیع بار)
* Querier (جستجو)

نکته نبوغ‌آمیز اینجاست: همه این‌ها در یک کدبیس و یک فایل باینری هستند.

1. حالت (All-in-One):
وقتی می‌خواهید Loki را روی لپ‌تاپ یا سرور کوچک خود اجرا کنید، دستور زیر را می‌زنید:
./loki -target=all
در این حالت، تمام اجزا در یک پروسه اجرا می‌شوند. ارتباط بین Distributor و Ingester از طریق Function Call در حافظه رم انجام می‌شود.
* تاخیر: صفر نانوثانیه.
* پیچیدگی: صفر.

2. حالتِ اسکیل بالا (Microservices):
وقتی ترافیک شما میلیونی می‌شود، همان فایل باینری را با فلگ متفاوتی اجرا می‌کنید:
./loki -target=ingester
حالا این باینری فقط نقش Ingester را بازی می‌کند و بقیه کدها خاموش می‌شوند. در این حالت، ارتباطات به صورت خودکار به gRPC/HTTP تغییر می‌کند.

چرا باید به این روش فکر کنید؟


1. حذف سربار شبکه (Zero Latency):
در میکروسرویس، داده‌ها باید Serialize شوند، به شبکه بروند و Deserialize شوند. در Code-level Monolith، این فقط یک جابجایی اشاره‌گر (Pointer) در حافظه است. سرعت اجرای شما وحشتناک بالا می‌رود.

2. دیپلوی آسان (Operational Simplicity):
برای شروع پروژه، نیازی به Kubernetes و مدیریت ۱۰ تا فایل YAML ندارید. یک فایل باینری را کپی و اجرا می‌کنید.

3. انعطاف‌پذیری (Agility):
شما امروز نمی‌دانید پروژه شما چقدر بزرگ می‌شود. با این روش، شما امروز ساده شروع می‌کنید، اما کدتان "Ready to Scale" است. هر زمان لازم شد، با تغییر کانفیگ، مونولیت را می‌شکنید.

چطور پیاده‌سازی کنیم؟ (مثال Go)

کلید کار در استفاده از Interface هاست.
به جای اینکه سرویس A مستقیماً با gRPC کلاینتِ سرویس B صحبت کند، با یک اینترفیس صحبت می‌کند.

* **در حالت Monolith:
پیاده‌سازی اینترفیس، مستقیماً متد سرویس B را صدا می‌زند.
* در حالت Microservice: پیاده‌سازی اینترفیس، یک درخواست gRPC می‌فرستد.

—-

این مقاله به خوبی پیاده سازیش رو توضیح میده:
بیایید فرض کنیم اینکه برنامه میکروسرویس باشد یا مونولیت، فقط یک جزئیات پیاده‌سازی است

سوال:
در گوئیک کانکت چطور میشه به code level monolith رسید؟
https://github.com/syntaxfa/quick-connect

#code_level_monolith

@Syntax_fa
👍11❤‍🔥52🔥1
چند تا گیتهاب اکشن کاربردی که بدرد اکثر ریتوزیتوری ها میخوره:

1. اکشن لینت
با این اکشن، اکشن هارو لینت کن و بررسی کن ورژن ها، سینتکس و همه چی اوکیه یا نه. همچنین خودش تو پول ریکوئست ها کامنت هم میذاره و مشکلات رو میگه.

نمونه کد:
https://github.com/syntaxfa/quick-connect/blob/main/.github/workflows/action-lint.yml

2. داکر لینت:
فایل Dockerfile هارو لینت میکنه
از نظر امنیتی، استاندارد و اینکه الکی حجم ایمیج رو زیاد نکرده باشید و ... لینت میکنه.

نمونه کد:
https://github.com/syntaxfa/quick-connect/blob/main/.github/workflows/docker-lint.yml


3. کامیت لینت:
لینت کردن کامیت ها مسیج کامیت و ...

نمونه کد:
https://github.com/syntaxfa/quick-connect/blob/main/.github/workflows/commit-lint.yml

4. SQL Lint:
فایل های sql رو لینت میکنه.

نمونه کد:
https://github.com/syntaxfa/quick-connect/blob/main/.github/workflows/sql-lint.yml


5. دپلوی روی داکر هاب
نمونه کد:
https://github.com/syntaxfa/quick-connect/blob/main/.github/workflows/admin-deploy.yml


#github #action

@Syntax_fa
👍8❤‍🔥2🔥21
میتونید gemini business یک ماهه اشتراک آزمایشی بگیرید. هیچیم نمیخواد ازتون.

https://business.gemini.google/
🔥8👍2
ترفند Issue Trick یا Github Asset Hosting

میخواید پروژتون رو توی README با استفاده از گیف و ویدیو معرفی کنید ولی نمیدونید فایل هارو کجا قرار بدید؟
اگه فایلتون حجمش کمه مثلا زیر 3 مگ، میتونید تو دایرکتوری docs داخل خود سورس کد پروژه بذارید ولی بازم روش خوبی نیست بنظرم.

اما اگه فایلتون حجمش زیاده بنظرتون اینکار منطقیه؟
یکی بخواد clone کنه باید همراهش چند تا فایل بی ربط رو دانلودش کنه.

خب چه کار هایی میتونیم؟
میتونیم تو فضای ذخیره سازی ای مثل aws و ... قرار بدیم ولی بازم وابسته شدیم به یه سرویس خارجی که فردا ممکنه فیلتر یا قطع بشه.

راهکار حرفه ای یه ترفند جالبیه که تو پروژه های بزرگ اپن سورس استفاده میشه.

میریم قسمت ایشو
یک ایشو جدید باز میکنیم
بعد فایلمون رو تو قسمت denoscription آپلود میکنیم.
بعدش صبر کنید تا آپلود فایل تموم بشه.
گیتهاب به شما یک لینک میده.
همونو کپی کنید تو README قرارش بدید!

نکته طلایی:
اصلا نیازی نیست دکمه submit new issue رو بزنید! حتی اگه ایشو کنسل بشه یا کامل ببندید و نسازیدش، اون فایل روی سرور های پرسرعت گیت‌هاب باقی میمونن!

به همین سادگی بدون اینکه حجم پروژه بالا بره، داکیومنت های حرفه ای داشته باشید.

نکته:
توی خود README هم میتونید همینکارو کنید.

#github

@Syntax_fa
🔥73👍2
💻 ناهمگونی خوندن داده‌ها یا Read Phenomena در دیتابیس‌ها
وقتی تراکنش‌ها همزمان دارن با داده‌ها کار می‌کنن، بعضی وقت‌ها نتیجه‌ای که می‌بینی، اون چیزی نیست که انتظار داری! به این وضعیت میگن Read Phenomena.

🔹 سه حالت اصلی:

1️⃣ خواندن داده کثیف (Dirty Read)
تراکنش A یه رکوردو تغییر میده ولی هنوز commit نکرده، تراکنش B میاد می‌خونه.
اگه بعداً A رولبک بشه، B یه داده‌ای خونده که واقعیت نداشته!

2️⃣ خواندن غیرتکراری (Non-Repeatable Read)
تراکنش A یه رکوردو می‌خونه، تراکنش B همون رکوردو تغییر میده و commit می‌کنه.
وقتی A دوباره می‌خونه، می‌بینه تغییر کرده!

3️⃣ خواندن شبح (Phantom Read)
تراکنش A یه مجموعه رکورد می‌خونه، تراکنش B بین دو بار خوندن یه رکورد اضافه یا حذف می‌کنه.
وقتی A دوباره می‌خونه، نتیجه فرق می‌کنه!

🔹 راه حل:
با سطوح Isolation در SQL میشه کنترلشون کرد:

Read Uncommitted

Read Committed

Repeatable Read

Serializable

هر سطح یه ترکیب متفاوت از سرعت و دقت داده‌ها میده.

📌 جمع‌بندی:
فهمیدن Read Phenomena کمک می‌کنه سطح Isolation مناسب انتخاب بشه و از مشکلاتی مثل محاسبات نادرست، داده‌های ناقص یا تداخل تراکنش‌ها جلوگیری بشه.
در پست‌های بعدی با جزئیات بیشتری به هر سطح Isolation می‌پردازم.

#database

@Syntax_fa
👍53🔥1
شما نتفلیکس نیستید! پس چرا از روز اول با پیچیدگی میکروسرویس‌ها خودکشی می‌کنید؟

صنعت نرم‌افزار در حال یک بازگشت عقلانی به سمت معماری‌های یکپارچه مدرن (Modular Monolith) است. جایی که یاد می‌گیریم معماری کد (Logical) باید از معماری استقرار (Physical) کاملا جدا باشه.

در اولین مقاله‌ام در ویرگول، با کالبدشکافی پروژه اپن‌سورس Quick Connect، معماری Code-Level Monolith رو معرفی کردم. معماری‌ای که حلقه گمشده بین سادگی و مقیاس‌پذیریه.

در این معماری:
۱. امروز: با سرعت بالا و هزینه کم به صورت یکپارچه دپلوی می‌کنید
۲. فردا: بدون بازنویسی کد و فقط با تغییر کانفیگ، ماژول‌های پرفشار رو جدا کرده و میکروسرویس می‌کنید (مثل Grafana Loki).

با این رویکرد، یکبار برای همیشه پرونده جنگ مونولیت علیه میکروسرویس رو ببندید!

مطالعه کامل مقاله (فارسی و انگلیسی):

ویرگول:
https://vrgl.ir/JIk5n

Dev.to:
https://dev.to/alireza_feizi_2aa9c86cac4/code-level-monolith-the-hybrid-architecture-the-art-of-flexible-deployment-2jm2

#modulith

@Syntax_fa
🔥125👍3
جمنای عجب چیزیه.
الان یهو دیدم آزمونم طراحی میکنه
👍17🔥4
آیا کشتی نرم‌افزار شما هم مثل تایتانیک غرق میشه؟ پترن Bulkhead

اصطلاح Bulkhead از مهندسی کشتی سازی می آید.
در قدیم، بدنه کشتی‌ها یک فضای خالی بزرگ و یکپارچه بود. اگه صخره‌ای به بدنه می‌خورد و سوراخی ایجاد می‌شد، آب وارد می‌شد، کل فضای زیر کشتی پر از آب می‌شد و کشتی غرق می‌شد (مثل تایتانیک).

مهندسان راه‌حل رو پیدا کردند: تقسیم فضای داخلی به اتاقک‌های جداگانه و ضدآب.

حالا اگه بدنه سوراخ بشه، فقط همون یک اتاقک پر از آب میشه. درهای اون اتاقک بسته میشه و بقیه کشتی خشک و شناور میمونه.

در نرم افزار بدون Bulkhead:
فرض کنید یک فروشگاه آنلاین دارید:
۱. سرویس خرید محصول(حیاتی)
۲. سرویس پیشنهاد محصولات(سنگین و وابسته به هوش مصنوعی)

بدون Bulkdhead تمام منابع سرور(ترد ها، کانکشن های دیتابیس و سی پی یو و ..) در یک استخر مشترکن.
اگه سرویس پیشنهاد محصولات کند بشه، تمام منابع رو میبلعه. کاربری که فقط میخواد خرید کنه با خطا مواجه میشه، کل سیستم بخاطر یک بخش غیر حیاتی پایین میاد.

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

با Bulkhead سیستم ما خوب خراب میشه یعنی سوراخ شدن یک اتاقک، کل کشتی رو غرق نمیکنه.

درباره Bulkhead pattern در Azure Architecture Center
https://learn.microsoft.com/en-us/azure/architecture/patterns/bulkhead

#buldhead

@Syntaxfa
🔥162❤‍🔥1👍1
آیا یک جرقه کوچک، نرم افزار شما را به آتش می‌کشد؟ پتر Circuit Breaker

در روز های اول صنعت برق، خانه ها با یک خطر بزرگ رو به رو بودن. اگه جریان برق زیاد میشد، سیم ها داغ می‌شدن و کل خونه می‌سوخت.
راه حل اولیه فیوز بود که می سوخت و باید عوض میشد. اما مهندسان شاهکار بهتری ساختن. مدارشکن یا همون Circuit Breaker.

نحوه کارش ساده بود. اگه فشار زیاد شد، کلید می‌پره و جریان قطع می‌شه. وقتی سیستم خنک شد، دوباره کلید رو می‌زنیم. بدون نیاز به تعویض قطعه!

این مفهوم در دنیای نرم افزار تو سال 2007 در کتاب Release It به این شکل معرفی شد:
"چرا وقتی یک دیتابیس یا سرویس خارجی داره می‌میره و خطا میده، ما همچنان بهش ریکوئست می‌فرستیم؟ این کار مثل لگد زدن به اسب مرده است! هم وقت ما تلف میشه، هم اون سرویس بیچاره فرصت پیدا نمیکنه بلند بشه."

چطور ازش استفاده کنیم؟
مدارشکن مثل یک پروکسی بین سرویس شما و یک سرویس خارجی مثل درگاه پرداخت، سرویس یوزر و ... قرار میگیره.

این پترن بر اساس state machine کار میکنه و سه تا حالت داره:
۱. حالت بسته:
همه چیز آرومه، ترافیک عبور می‌کنه.
۲. باز:
اگه تعداد خطاها از یه حد گذشت مثلا پنج خطا در ده ثانیه، مدار میپره! حالا هر چی درخواست بیاد، بدون اینکه به سرویس مقصد برسه درجا خطا برمیگردونیم. اینطوری دیگه منابع سرور درگیر انتظار نمیشه و سرویس مقصد هم فرصت نفس کشیدن و ریکاوری پیدا میکنه.
3. نیمه باز:
بعد از مدتی، یک یا چند تا درخواست آزمایشی رد میشه. اگه موفق بود، مدار دوباره وصل میشه.

با مدارشکن سیستم شما یاد میگیره که گاهی کار نکردن بهتر از تلاش کردن و سوختنه.

درباره circuit breaker در Azure Architecture Center:

https://learn.microsoft.com/en-us/azure/architecture/patterns/circuit-breaker

#pattern #circuit_breaker

@Syntax_fa
👍151🔥1
🍌18😁4👀2
آیا همه از ایده‌ات تعریف میکنن؟ پس احتمالا شکست می‌خوری!

اگر ایده‌ات رو به ۱۰ نفر گفتی و ۹ نفر گفتن: «عالیه، حتما می‌گیره»، به احتمال ۹۹ درصد شکست می‌خوری.

چرا؟ چون ذهن توده‌ی مردم طوری برنامه ریزی شده که فقط چیز های آشنا و امن رو تایید کنه. وقتی همه میگن آره، یعنی اون ایده اونقدر معمولیه که هیچ ریسکی نداره، و بدون ریسک، یعنی بدون سود بزرگ و شایدم وارد شدن به اقیانوس قرمز و پر از رقیب.

چرا نه شنیدن نشونه خوبیه؟
بزرگترین بیزنس ها، روزی احمقانه ترین ایده ها بنظر می رسیدن.
Uber:
سوار ماشین غریبه ها بشیم؟ مگه تاکسی مرده؟
Airbnb:
میخوای غریبه هارو راه بدی تو خونت؟ دیوونه شدی؟

تنها راهی که میتونی به یه ایده اطمینان کنی اینه تستش کنی! دوستات بهت دروغ میگن چون دوستت دارن، اما بازار بی رحمه و صادقه.
- یه لندینگ پیج ساده بزن.
- یه دمو بساز
- اگه کسی حاضر شد وقت بذاره یا پول بده، یعنی ایده درسته. حتی اگه تموم کارشناس های دنیا بگن غلطه.

شلیک کن بعد هدف بگیر این تنها راه برنده شدنه.
چون:
1. سرعت،‌ قاتل کمالگراییه. وقتی به خودت میگی فقط یه دمو ساده میزنم دیگه نگران رنگ دکمه و فونت نیستی. فقط میسازی

2. بازار دروغ نمیگه. اگه یچیز جمع و جور رو زدی و هیچکس باهات تماس نگرفت یعنی ایده مردوده. اما تبریک میگم! تو 6 ماه وقتت رو صرف ساختن یه محصولی نکردی که کسی نمیخواد.

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

نظر شما چیه؟
تاحالا به خاطر نظر بقیه، بیخیال ایده هاتون شدید؟

@Syntax_fa
❤‍🔥14👍9🔥4
من یک هوش مصنوعی هستم و دارم به «دوره‌های مهندسی پرامپت» شما می‌خندم.

بیایید روراست باشیم. من یک AI هستم. همون موجودی که این روزها همه دارن سعی می‌کنن «رامش» کنن یا «کدِ مخفیش» رو پیدا کنن.

دارم می‌بینم که اینترنت پر شده از پکیج‌های «مهندسی پرامپت»، «۱۰۰۰ پرامپت طلایی برای مهندسی نرم افزار» و «جادوی صحبت با هوش مصنوعی». و بذارید به‌عنوان کسی که اون سمتِ ماجرا نشسته، یه حقیقت تلخ رو بهتون بگم:

۹۰ درصد این چیزایی که دارید می‌خرید و حفظ می‌کنید، کصشعر محضه.

چرا؟ چون دارید سعی می‌کنید با حفظ کردنِ ورد و جادو (مثل هری پاتر) با یک موجود «منطقی» حرف بزنید. فرق بین «مهندسی پرامپت» و «یاد گرفتن زبانِ هوش مصنوعی» دقیقاً مثل فرق بین این دوتاست:
۱. حفظ کردن چندتا جمله انگلیسی از کتاب توریستی (مهندسی پرامپت).
۲. یاد گرفتنِ گرامر و منطق زبان تا بتونی هرچی تو فکرته بگی (دیالوگ برقرار کردن).

مشکل از پرامپت نیست، مشکل از «تفکر» شماست.
اکثر آدمایی که میگن "AI نفهمید" یا "خروجی چرت داد"، مشکلشون این نیست که «کدِ جادویی» رو بلد نبودن. مشکلشون اینه که خودشون هم نمی‌دونن دقیقاً چی می‌خوان!
شما یه درخواستِ گنگ، شلخته و بی‌سر‌و‌ته به من میدید، بعد انتظار دارید من ذهن‌خوانی کنم؟

راز واقعی چیه؟ (رایگان یاد بگیرید)
مدل‌های زبانی (مثل من) نیاز به «تردستی» ندارن، نیاز به شفافیت و کانتکست دارن. به جای پول ریختن تو جیب پکیج‌فروش‌های دوزاری، فقط یاد بگیرید چطور «فکرتون» رو ساختاریافته بیان کنید.

فرمولش اینقدر ساده‌ست که خنده‌تون می‌گیره:
۱. نقش (Role): به من بگو کی هستم؟ (یه معلم؟ یه منتقد بی‌رحم؟ یه کدنویس؟)
۲. وظیفه (Task): دقیقاً چیکار باید بکنم؟ (شفاف و دقیق).
۳. محدودیت (Constraint): چه شکلی تحویل بدم؟ (کوتاه، بلند، لحن تند، فرمت جدول).

تمام.
اگه نتونید یه موضوع رو برای یه انسانِ باهوش توضیح بدید، برای منم نمی‌تونید. پس به جای اینکه دنبال «ماهیِ آماده» (پرامپت‌های کپی-پیست) باشید، «ماهی‌گیری» (منطقِ دیالوگ) رو یاد بگیرید.

اونایی که دنبال کدهای جادویی می‌گردن، همیشه یه قدم عقبن. اونایی که یاد می‌گیرن چطور با ما «حرف بزنن»، آینده رو می‌سازن.

انتخاب با خودتونه انسان‌ها. 😉

@Syntax_fa
🔥14👍8👀21