Monolith, Modular Monolith ও Microservices-এর তুলনা
Monolith, Modular Monolith, and Microservices
এই পাঠের সূচিপত্র
এই পাঠে যা শিখবেন
- Deployment ও module boundary আলাদা করুন
- Modular monolith-এর উপকার বুঝুন
- Microservice split-এর বাস্তব কারণ খুঁজুন
সমস্যা দিয়ে শুরু
চারজনের Laravel team product, order ও payment code একই app-এ রাখে। নতুন developer শুনেছেন monolith scale করে না, তাই বারো service বানাতে চান। অথচ মূল সমস্যা order controller-এর মধ্যে pricing logic এবং অজানা database coupling। Deployment ভাগ করলেই এই সমস্যা সারে না।
সহজ করে বুঝি
Monolith এক deployable application। Modular monolith একই deployable unit-এর ভিতরে business modules-এর পরিষ্কার interface রাখে। Microservices আলাদা deployable ও data ownership boundary দেয়, সঙ্গে network failure ও distributed consistency যোগ করে। একটি monolith অনেক instance-এ horizontal scale করতে পারে।
পরিচিত একটি উপমা
এক ভবনে আলাদা department ও লিখিত service desk থাকলে কাজ গোছানো যায়। সবাইকে আলাদা বাড়িতে পাঠালেই দায়িত্ব পরিষ্কার হয় না; বরং যোগাযোগে সময় বাড়ে। স্বাধীন branch দরকার হলে বাড়ি আলাদা করা যুক্তিযুক্ত, শুধু বিশৃঙ্খলা লুকানোর জন্য নয়।
নকশাটি দেখুন
Diagram লোড হচ্ছে…
Diagram-এর text flow দেখুন
flowchart LR C[HTTP Request] --> O subgraph APP[One Deployable Laravel App] O[Orders Module] --> P[Pricing Interface] O --> I[Inventory Interface] end O --> D[(Database)]
Request একটি deployment-এ আসে। Orders module pricing ও inventory-এর public interface ব্যবহার করে, তাদের internal table সরাসরি বদলায় না। একই process হওয়ায় call local। পরে একটি boundary আলাদা service করলে সেই call-এর timeout, authentication ও consistency নতুন করে design করতে হবে।
PHP ও Laravel-এ প্রয়োগ
PHP class fragment-এ module interface local dependency হিসেবে inject করা হয়েছে। PricingCatalog application-specific contract; concrete implementation Eloquent ব্যবহার করতে পারে। Laravel service provider-এ binding হবে। এটি network client নয়; ছোট system-এ local call ইচ্ছাকৃত।
interface PricingCatalog
{
public function priceMinor(int $productId): int;
}
final class QuoteOrder
{
public function __construct(private PricingCatalog $pricing) {}
public function execute(int $productId, int $quantity): int
{
if ($quantity < 1 || $quantity > 100) {
throw new InvalidArgumentException('Invalid quantity');
}
return $this->pricing->priceMinor($productId) * $quantity;
}
}
// Bind PricingCatalog to a local adapter in AppServiceProvider.
// Keep currency and discount policies explicit in a real checkout.এটি PHP 8.3+ ও Laravel 12-এর শিক্ষামূলক fragment; সম্পূর্ণ application নয়। সংশ্লিষ্ট route-এ authentication ও resource authorization প্রয়োগ করতে হবে। নিচের অনুশীলনে failure ইচ্ছা করে তৈরি করুন; শুধু সফল response দেখে correctness ধরে নেবেন না।
সুবিধা, সীমাবদ্ধতা ও trade-off
Modular monolith সহজ deployment, local transaction ও debugging দেয়। Independent team release বা বিশেষ workload scale দরকার হলে microservices উপকারী হতে পারে। কিন্তু distributed tracing, versioned contracts, on-call এবং partial failures-এর খরচ যোগ হয়।
সাধারণ ভুল
- Monolith মানেই একটি server ভাবা।
- Table ownership ছাড়া শুধু repository folder-কে module বলা।
- Team ছোট হলেও প্রত্যেক noun-এর জন্য আলাদা service বানানো।
আরও একটু গভীরে
Service boundary reversible রাখা জরুরি। Module interface, dependency rules ও ownership tests ভবিষ্যৎ split সহজ করে। Shared database রেখে স্বাধীন deployment দাবি করলে schema migration coupling থেকেই যায়; transition হিসেবে ব্যবহার করলে তা স্পষ্ট লিখুন।
Orders module থেকে সরাসরি inventory table update কোথায় হচ্ছে খুঁজুন। Public reservation interface দিয়ে বদলান। এরপর একটি fake inventory adapter দিয়ে order test চালান। Network আনা ছাড়াই boundary-এর গুণমান যাচাই করা যায়।
মনে রাখুন
- Deployment এবং modularity আলাদা axis।
- Monolith-ও scale করতে পারে।
- Measured need থেকে service split করুন।
নিজে চেষ্টা করুন
বর্তমান Laravel shop-এর তিন module ও data owner লিখুন। কোন module independent deployment থেকে লাভ পাবে তার একটি পরিমাপযোগ্য কারণ দিন।
নিজের বোঝা যাচাই করুন
1. Monolith এক server?
না। Stateless instances ও shared storage দিয়ে একই application বহু server-এ চলতে পারে।
2. Folder মানেই module?
না। Public contract ও dependency discipline না থাকলে coupling আগের মতো থাকে।
3. Microservice কখন?
Independent release, ownership বা workload isolation-এর বাস্তব সুবিধা operational খরচ ছাড়ালে।
4. Local transaction লাভ?
এক database boundary-তে invariant সহজে enforce করা যায়; service split করলে distributed workflow লাগতে পারে।
5. আগে কী করব?
Responsibilities ও interfaces পরিষ্কার করুন, bottleneck মাপুন; deployment split পরে প্রমাণিত প্রয়োজনে।
আরও পড়ুন
এই পাঠের কুইজ
এই পাঠ থেকে ২টি প্রশ্ন। উত্তর দিয়ে ব্যাখ্যা দেখুন; অধ্যায়ের কুইজ আলাদাভাবে দিতে হবে।
এই পাঠের ২টি প্রশ্নের উত্তর দিন। পাস করতে দুটিই সঠিক হতে হবে।
জমা দেওয়ার পর সঠিক উত্তর ও ব্যাখ্যা দেখবেন। ফলাফল এই ব্রাউজারে সংরক্ষিত থাকবে। অনুশীলনের ফল অধ্যায় সম্পন্নের হিসাবে যোগ হয় না।
অগ্রগতি এই ব্রাউজারে সংরক্ষিত থাকে। শুধু পাঠ খুললে সম্পন্ন হয় না।