MicroservicesMonolithModular MonolithSoftware ArchitectureBackend Engineering

Day 22 — Microservices vs Monolith — Hype বাদ দিয়ে সত্যিটা বলি 🏗️

July 5, 20266 min read30 Days Of Backend Engineering

আপনার application এখন ভালোভাবেই চলছে। আপনি এখন আর একা কাজ করেন না। আপনি কয়েকটি team build করেছেন। অনেকদিন ধরেই এই team building-টা চলছে। মোটামুটি ১০০-১২০ জনের team আপনারা operate করছেন।

এখন আপনার ইচ্ছা জাগল যে system-টা optimize করা দরকার। এর জন্য শুরু করলেন system monitoring। এভাবে ১ সপ্তাহ monitoring করলেন। ১ সপ্তাহ পর আপনার কাছে সব data চলে আসলো। আপনি কিছু জিনিস খেয়াল করলেন:

  • Feed এবং Chat related service-গুলো সবথেকে বেশি use হচ্ছে।
  • Post-এর write-এর থেকে read করা হচ্ছে বেশি।
  • Payment related service-গুলোর usage একেবারেই কম, মাসের শেষে বা প্রথমে এই service-টা use হয়।
এছাড়াও আরও কিছু জিনিস আপনি উপলব্ধি করলেন, team member-দের কাছ থেকে feedback নিলেন:
  • Feed related service-গুলো, post-এর সাথে সম্পৃক্ত থাকলেও, chat related service-এর কোনো connection নেই। এই কারণে অনেক performance drop হচ্ছে। Server capacity বেড়ে যাচ্ছে। বেশি user handle করা যাচ্ছে না। For example, সন্ধ্যার পরে chat service-এর usages বেড়ে যায়, এই কারণে user-রা নতুন post করতে problem face করে, অল্প একটু latency থাকে। Feed service-এ একটু problem হয়।
  • Development problem। Application-টা অনেক বড় হয়ে গেছে। এখন একই codebase-এ অনেক team কাজ করে। এই জন্য এটা maintain করা ঝামেলা হয়ে যাচ্ছে। Feature development-এর চেয়ে code maintain করতেই সময় চলে যাচ্ছে।
  • Deployment issue। Everyday নতুন নতুন feature, improvement হচ্ছে। এই অবস্থায় ছোট একটা bug fix করে deploy করলেও পুরো application build করা লাগছে।
  • Merge conflict নিয়মিত হচ্ছে।
এগুলো ছাড়াও আরও অনেক বিষয় আছে যেগুলো আপনি উপলব্ধি করলেন। এই কারণে system-এর performance down হচ্ছে। একটু optimize করলে profit-ও একটু বাড়ানো যাবে।

Monolith: যা দিয়ে সবাই শুরু করে

Monolith মানে সব কিছু একটা codebase-এ, একটা deployment। আপনার application-টাও কিন্তু monolith application। Server অনেকগুলো বাড়িয়েছেন কিন্তু codebase তো সেই একটাই।

Monolith application's folder structure

my-app/
  ├── auth/
  ├── orders/
  ├── payments/
  ├── notifications/
  └── main.ts

সুবিধা:

  • Development simple। একটা project খুললেই সব দেখা যায়।
  • Debugging easy।
  • End-to-end test সহজ।
  • Deploy একটাই।
**সমস্যা যখন বাড়ে:**
  • Codebase বিশাল হয়ে যায়।
  • একটা bug পুরো app down করে।
  • আলাদা আলাদা scale করা যায় না।
  • ৫০ জন developer একই codebase-এ conflict করে।

Microservices: Small and Independent

আপনার বর্তমান সমস্যার সমাধান হচ্ছে microservice। Application-কে domain এবং use case অনুযায়ী অনেক part-এ divide করা হবে। প্রত্যেকটা part-ই হলো একেকটা microservice। এখানে প্রত্যেকটা service standalone application হিসেবে কাজ করে। Logic আলাদা, implementation আলাদা হতে পারে, infact database-ও আলাদা হতে পারে।

feed-service     → port 3001
chat-service    → port 3002
payment-service  → port 3003

সুবিধা:

  • Independent deploy — Payment service update করলে feed বা chat service restart না।
  • Independent scale — Feed page-এ বেশি traffic? শুধু feed-service scale করলেই হবে।
  • আলাদা team আলাদা service own করে। এতে কোড maintain করা easy হয়। Merge conflict কমে যায়।
**সমস্যা:**
  • Network latency — একটা request ৫টা service ঘুরে আসে।
  • Distributed transactions কঠিন।
  • Debugging nightmare — কোন service-এ error?
  • Infrastructure complexity বাড়ে অনেক।
এখানে একটা problem আছে। আগের multiple server-এর মতো। আগে তো Load Balancer use করে সেটা solve করেছিলাম। সেখানে একটা application-এর clone ছিল, problem নাই। কিন্তু এখানে Load Balancer দিয়ে কাজ হবে না।

আর এই service-গুলোর IP address সব জায়গায় দেওয়া তো possible না। তাহলে solution-টা কী? Solution-টা হচ্ছে API Gateway। API Gateway-তে এই service-গুলো connect হবে এবং একটা simple application-এর মতো behave করবে। User কিছুই বুঝতে পারবে না।


যেখানে সবচেয়ে বেশি ক্যাচাল লাগে!

Microservices মানে distributed system। আর আমি আগে বলেছি, "Distributed system is a nightmare"। কখন কোন সময় কী হবে আপনি predict-ই করতে পারবেন না। 3 body problem-এর মতো। আপনার ঘুম হারাম হয়ে যেতে পারে যেকোনো সময়।

Problems:

  • Partial failures — Service A চলছে, Service B down। এখন আপনি সার্ভিস B use করতে পারবেন না। এখানে scalling করা লাগতে পারে। তার জন্য আলাদা ঝামেলা।
  • Network timeouts — কোনর কারণে নেটওয়ার্ক slow হয়ে গেছে, এক টা পর্যায়ে timeout ও হয়ে যাচ্ছে। এখন inter-service communication করতে সমস্যা হবে ইনফ্যাক্ট হবেই না। এটা একটা সমস্যা।
  • Data consistency — দুই service-এ data কীভাবে consistent রাখব? এর জন্য CAP theoram আছে। এই নিয়ে সামনে আলোচনা হবে ইনশাআল্লাহ।
এই problem গুলা resolve করতে Circuit Breaker, Saga pattern, Distributed tracing — সব দরকার। এই overhead ছোট team সামলাতে পারে না। এই জন্য ছোট টিমের জন্য microservice না।
N:B: এতক্ষণে হয়তো কিছু idea করতে পেরেছেন যে microservice-এ event driven architecture কেন use করা হয়।

কখন কোনটা?

Monolith দিয়ে শুরু করুন যখন:

  • Startup, নতুন product, MVP।
  • Team size ছোট (< ১৫ জন)।
  • Business domain এখনো পরিষ্কার না।
  • Fast iteration দরকার।
**Microservices যান যখন:**
  • Product proven, scale দরকার।
  • Team বড় (৫০+ developer)।
  • স্পষ্ট bounded context আছে।
  • Independent deploy-এর সুবিধা cost justify করে।

Modular Monolith: Middle Ground

Monolith-এ সবকিছু তো এক জায়গাতেই থাকে। Modular monolith-এ সব code একসাথেই থাকে তবে সেগুলো module আকারে divide করা থাকে। অনেকটা microservice-এর concept-এর মতো, standalone module। এইসব module-গুলো main application-এর সাথে loosely coupled থাকে। খুব easily এই application থেকে module remove করা যায় বা অন্য কোথাও সরিয়ে নিয়ে যাওয়া যায়।

আমি personally modular monolith architecture-টা পছন্দ করি।

Folder structure of Modular Monolth:

my-app/
  ├── modules/
  │   ├── auth/      ← নিজস্ব DB schema
  │   ├── orders/    ← নিজস্ব DB schema
  │   └── payments/  ← নিজস্ব DB schema
  └── main.ts

Modular monolith-এর সবথেকে বড় সুবিধা হচ্ছে, এই module-গুলোকে gradually microservices-এ convert করা যায়। For example, order-কে আমি একটা আলাদা service-এ নিয়ে যেতে পারবো। একটা standalone application বানাবো এবং feature সবকিছু same থাকবে। At last, API Gateway-এর সাথে main application + order service connect করে দেবো। এভাবে gradually একটা modular monolith-কে microservice-এ transfer করা যায়।


বটম লাইন

Microservices Netflix, Uber-এর জন্য সঠিক — কারণ তারা সেই scale-এ। startup-এর জন্য না। Monolith দিয়ে শুরু করুন, domain বুঝুন, তারপর দরকার হলে আলাদা করুন।

আপনার current project কোনটা? পরিবর্তন করেছেন কখনো? কমেন্টে শেয়ার করুন! 👇