Syntax | سینتکس
2.98K subscribers
423 photos
111 videos
35 files
392 links
Download 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