পাঠ ০৪ · ৫৮-এর মধ্যে · মডিউল ১
Home / Courses / Full-Stack Web Frameworks / আর্কিটেকচার ম্যাপ

মনোলিথ বনাম মাইক্রোসার্ভিস বনাম SPA/SSR/SSG — একটি আর্কিটেকচার ম্যাপ

Monolith vs microservices vs SPA/SSR/SSG — an architecture map
৮ মিনিট পড়া শুরু · Beginner Python কোডসহ সম্পূর্ণ বাংলায়

এই পাঠে যা শিখবেন

  • মনোলিথ ও মাইক্রোসার্ভিস আর্কিটেকচারের মূল পার্থক্য -- ডিপ্লয়মেন্ট ইউনিট ও প্রসেস বিভাজনের দিক থেকে
  • SPA, SSR, SSG রেন্ডারিং স্ট্র্যাটেজির সংক্ষিপ্ত পরিচয় (বিস্তারিত M9-এ)
  • এই দুটো আর্কিটেকচারাল সিদ্ধান্ত কেন একে অপরের থেকে স্বাধীন
  • Python দিয়ে মনোলিথ-স্টাইল বনাম মাইক্রোসার্ভিস-স্টাইল রিকোয়েস্ট রাউটিং সিমুলেট করা

১ · মনোলিথ আর্কিটেকচার

L01-এ আমরা তিন-স্তর আর্কিটেকচারের একটি প্রিভিউ পেয়েছি। এখন সেই ছবিতে আরেকটি প্রশ্ন যোগ করা যাক -- মনোলিথMonolithএকটি একক, অখণ্ড কোডবেস ও প্রসেস হিসেবে বানানো ও ডিপ্লয় করা অ্যাপ্লিকেশন -- সব ফিচার একই প্রোগ্রামের ভেতর একসাথে চলে।-এ পুরো ব্যাক-এন্ড (ইউজার ম্যানেজমেন্ট, অর্ডার প্রসেসিং, পেমেন্ট -- সবকিছু) একটি একক প্রসেস ও একটি একক কোডবেসে চলে। ডিপ্লয় করার সময় পুরো অ্যাপ্লিকেশনটি একসাথে ডিপ্লয় হয়, একটি একক ইউনিট হিসেবে।

২ · মাইক্রোসার্ভিস আর্কিটেকচার

মাইক্রোসার্ভিস-এ একই ফিচারগুলো (ইউজার ম্যানেজমেন্ট, অর্ডার প্রসেসিং, পেমেন্ট) আলাদা স্বতন্ত্র সার্ভিসে ভাগ করা হয় -- প্রতিটির নিজস্ব প্রসেস, প্রায়ই নিজস্ব ডেটাবেস, এবং স্বাধীনভাবে ডিপ্লয় করার ক্ষমতা থাকে। একটি গেটওয়ে (M2-এর L08-এ বিস্তারিত) আগত রিকোয়েস্ট গ্রহণ করে সঠিক সার্ভিসে রাউট করে দেয়।

মনোলিথ এক প্রসেস, এক কোডবেস Users মডিউল Orders মডিউল Payments মডিউল মাইক্রোসার্ভিস গেটওয়ে Users সার্ভিস Orders সার্ভিস Payments সার্ভিস প্রতিটি সার্ভিস স্বাধীনভাবে ডিপ্লয়/স্কেল করা যায়
মনোলিথে একটি প্রসেস সব ফিচার একসাথে চালায়; মাইক্রোসার্ভিসে প্রতিটি ফিচার নিজস্ব স্বতন্ত্র সার্ভিসে চলে, গেটওয়ে অনুরোধ যথাযথ সার্ভিসে রাউট করে।
মনোলিথ শুরুতে সহজ (একটি কোডবেস, একটি ডিপ্লয়মেন্ট) কিন্তু বড় টিম/স্কেলে সমন্বয় কঠিন হয়ে যেতে পারে। মাইক্রোসার্ভিস স্বাধীন স্কেলিং ও ডিপ্লয়মেন্ট দেয় কিন্তু নেটওয়ার্ক কল, একাধিক ডেটাবেস, ও ডিস্ট্রিবিউটেড সিস্টেমের জটিলতা যোগ করে -- এই ট্রেড-অফের গভীর আলোচনা সহোদর ../system-design/ কোর্সে করা হয়েছে; এই কোর্স মূলত ফ্রেমওয়ার্ক-স্তরের প্রভাবে ফোকাস করে (M12-M13-এ ডিপ্লয়মেন্ট প্রসঙ্গে আরও আসবে)।

৩ · SPA, SSR, SSG সংক্ষেপে -- একটি ভিন্ন অক্ষ

মনোলিথ/মাইক্রোসার্ভিস ব্যাক-এন্ডের প্রশ্ন হলেও, SPA, SSR, SSG হলো ফ্রন্ট-এন্ড HTML কখন তৈরি হয় তার প্রশ্ন -- সম্পূর্ণ ভিন্ন, স্বাধীন একটি সিদ্ধান্ত (M9-এ প্রতিটি বিস্তারিত আসবে)।

SPA · Single-Page Application
প্রাথমিক HTML একবার লোড হয়, এরপর JavaScript ক্লায়েন্টেই নতুন কন্টেন্ট রেন্ডার করে -- দ্রুত নেভিগেশন, কিন্তু প্রথম লোড ভারী।
SSR · Server-Side Rendering
প্রতিটি রিকোয়েস্টে সার্ভার সম্পূর্ণ HTML তৈরি করে পাঠায় -- ভালো SEO ও দ্রুত প্রথম দৃশ্যমান কন্টেন্ট।
SSG · Static Site Generation
HTML বিল্ড-টাইমে একবার তৈরি হয়ে থাকে, প্রতিটি রিকোয়েস্টে শুধু সেই ক্যাশড ফাইল সার্ভ হয় -- সবচেয়ে দ্রুত, তবে আপডেটের জন্য রিবিল্ড লাগে।
দুটো স্বাধীন অক্ষ -- মনে রাখার সহজ উপায়

"ব্যাক-এন্ড কীভাবে সংগঠিত (মনোলিথ/মাইক্রোসার্ভিস)" আর "ফ্রন্ট-এন্ড HTML কখন তৈরি হয় (SPA/SSR/SSG)" -- এই দুটো সম্পূর্ণ ভিন্ন প্রশ্নের উত্তর। একটি মনোলিথ ব্যাক-এন্ড SSR ব্যবহার করতে পারে, একটি মাইক্রোসার্ভিস ব্যাক-এন্ডও SSR বা SPA যেকোনোটাই ব্যবহার করতে পারে -- একটি অক্ষের সিদ্ধান্ত অন্যটিকে বাধ্য করে না।

৪ · কোড সেল -- মনোলিথ বনাম মাইক্রোসার্ভিস রাউটিং সিমুলেশন

নিচের কোডে একই তিনটি পাথ দুইভাবে হ্যান্ডল করা হয়েছে -- প্রথমে monolith_handle নামের একটি একক ফাংশন দিয়ে (মনোলিথ-স্টাইল, সব লজিক এক জায়গায়), তারপর পাথ প্রিফিক্স অনুযায়ী আলাদা সার্ভিস ফাংশনে রাউট করা একটি microservice_gateway দিয়ে (মাইক্রোসার্ভিস-স্টাইল)।

Python
# --- মনোলিথ: একটি প্রসেসই সব হ্যান্ডল করে ---
def monolith_handle(path):
    if path.startswith("/users"):
        return "monolith-process", "ইউজার ডেটা (একই প্রসেস, একই কোডবেস)"
    elif path.startswith("/orders"):
        return "monolith-process", "অর্ডার ডেটা (একই প্রসেস, একই কোডবেস)"
    elif path.startswith("/payments"):
        return "monolith-process", "পেমেন্ট প্রসেসিং (একই প্রসেস, একই কোডবেস)"
    else:
        return "monolith-process", "404 Not Found"

# --- মাইক্রোসার্ভিস: পাথ প্রিফিক্স অনুযায়ী স্বতন্ত্র সার্ভিসে রাউট ---
def users_service(path):
    return "ইউজার ডেটা (users-service, নিজস্ব প্রসেস)"

def orders_service(path):
    return "অর্ডার ডেটা (orders-service, নিজস্ব প্রসেস)"

def payments_service(path):
    return "পেমেন্ট প্রসেসিং (payments-service, নিজস্ব প্রসেস)"

microservice_registry = {
    "/users": users_service,
    "/orders": orders_service,
    "/payments": payments_service,
}

def microservice_gateway(path):
    for prefix, service_fn in microservice_registry.items():
        if path.startswith(prefix):
            return prefix, service_fn(path)
    return None, "404 Not Found"

test_paths = ["/users/42", "/orders/7", "/payments/checkout", "/unknown"]

print("--- মনোলিথ: এক প্রসেস সব হ্যান্ডল করছে ---")
for path in test_paths:
    process, result = monolith_handle(path)
    print(f"{path:20s} -> [{process}] {result}")

print("\n--- মাইক্রোসার্ভিস: পাথ প্রিফিক্স অনুযায়ী ভিন্ন সার্ভিসে রাউট ---")
for path in test_paths:
    service, result = microservice_gateway(path)
    service_label = service if service else "কোনো সার্ভিস পাওয়া যায়নি"
    print(f"{path:20s} -> [{service_label}] {result}")

monolith_processes = {monolith_handle(p)[0] for p in test_paths}
microservice_processes = {microservice_gateway(p)[0] for p in test_paths if microservice_gateway(p)[0]}

print(f"\nমনোলিথে জড়িত ভিন্ন প্রসেস সংখ্যা: {len(monolith_processes)}")
print(f"মাইক্রোসার্ভিসে জড়িত ভিন্ন প্রসেস/সার্ভিস সংখ্যা: {len(microservice_processes)}")

    
লক্ষ্য করুন /unknown পাথ দুই পদ্ধতিতেই "404 Not Found" দেয়, কিন্তু ভিন্নভাবে -- মনোলিথে monolith_handle-এর else শাখা থেকে, মাইক্রোসার্ভিসে microservice_gateway-এর লুপ কোনো প্রিফিক্স না মেলার পর return None, "404 Not Found" থেকে। শেষ দুই লাইনে দেখা যায় মনোলিথে সবসময় একটিই প্রসেস-নাম জড়িত থাকে ({"monolith-process"}), কিন্তু মাইক্রোসার্ভিসে তিনটি ভিন্ন সার্ভিস জড়িত হয় (/users, /orders, /payments) -- এটাই "একটি প্রসেস বনাম একাধিক স্বতন্ত্র প্রসেস" পার্থক্যের একটি গণনাযোগ্য প্রমাণ।
মূল কথা · Key takeaway

মনোলিথ বনাম মাইক্রোসার্ভিস ব্যাক-এন্ডের সংগঠন নিয়ে সিদ্ধান্ত, আর SPA বনাম SSR বনাম SSG ফ্রন্ট-এন্ড রেন্ডারিং নিয়ে সিদ্ধান্ত -- দুটোই স্বাধীন অক্ষ, একসাথে মিলিয়ে একটি প্রজেক্টের সম্পূর্ণ আর্কিটেকচার ম্যাপ তৈরি হয়। এই কোর্সের বাকি অংশ (M2-M13) এই ম্যাপের প্রতিটি অংশ গভীরভাবে কভার করবে -- MVC/REST দিয়ে শুরু করে, ফ্রন্ট-এন্ড/ব্যাক-এন্ড ফ্রেমওয়ার্ক ফান্ডামেন্টাল হয়ে, রেন্ডারিং স্ট্র্যাটেজি ও ডিপ্লয়মেন্ট পর্যন্ত।

ভাবনার প্রশ্ন

প্রতিটি প্রশ্ন নিজে কিছুক্ষণ ভাবুন -- তারপর "→ উত্তর" চাপুন।

প্র ০১ একটি ছোট স্টার্টআপ, যাদের টিমে মাত্র ২ জন ডেভেলপার, তাদের কি মাইক্রোসার্ভিস দিয়ে শুরু করা উচিত?

সাধারণত না। মাইক্রোসার্ভিসের সুবিধা (স্বাধীন স্কেলিং, স্বাধীন ডিপ্লয়মেন্ট) তখনই সবচেয়ে বেশি কাজে লাগে যখন টিম বড় হয় ও বিভিন্ন অংশের স্কেলিং চাহিদা আলাদা হয়ে যায়। ছোট টিমের জন্য একটি মনোলিথ প্রায়ই দ্রুত শুরু করা, ডিবাগ করা, ও ডিপ্লয় করা সহজ -- ডিস্ট্রিবিউটেড সিস্টেমের বাড়তি জটিলতা (নেটওয়ার্ক কল, একাধিক ডেটাবেস) ছাড়াই। অনেক সফল প্রোডাক্ট মনোলিথ দিয়ে শুরু করে পরে প্রয়োজনমতো মাইক্রোসার্ভিসে ভাগ হয়েছে (M13-এ "সঠিক স্ট্যাক বাছাই করা" পাঠে আরও)।

প্র ০২ একটি খবরের ওয়েবসাইট (কন্টেন্ট প্রায়ই বদলায় না) কি SPA, SSR নাকি SSG দিয়ে সবচেয়ে ভালো কাজ করবে বলে আপনার মনে হয়?

অনেক খবরের সাইটের জন্য SSG (বা ISR, যা L41-এ আসবে) ভালো ফিট -- কন্টেন্ট প্রায়ই বদলায় না, তাই বিল্ড-টাইমে একবার HTML তৈরি করে ক্যাশ করে রাখলে প্রতিটি রিকোয়েস্ট অত্যন্ত দ্রুত সার্ভ করা যায়, এবং SEO-ও ভালো থাকে (সম্পূর্ণ HTML সার্চ ইঞ্জিন সরাসরি পড়তে পারে)। তবে "ব্রেকিং নিউজ" বা লাইভ আপডেট প্রয়োজন হলে SSR বা হাইব্রিড পদ্ধতি বেশি উপযুক্ত হতে পারে -- এই ট্রেড-অফগুলো M9-এ বিস্তারিত আলোচনা করা হবে।

প্র ০৩ উপরের কোডে microservice_processes গণনা করার সময় if microservice_gateway(p)[0] শর্তটি কেন প্রয়োজন?

কারণ /unknown পাথের জন্য microservice_gateway (None, "404 Not Found") রিটার্ন করে -- অর্থাৎ প্রথম মান None। যদি এই শর্ত না থাকত, তাহলে সেট-এ None-ও একটি "প্রসেস" হিসেবে গণনা হয়ে যেত, যা ভুল -- কারণ /unknown আসলে কোনো সার্ভিসেই পৌঁছায়নি। if শর্তটি নিশ্চিত করে শুধু সত্যিকারের সার্ভিসে পৌঁছানো রিকোয়েস্টগুলোই গণনা হয়।

অনুশীলন

  1. চিন্তা করুন: মাইক্রোসার্ভিস আর্কিটেকচারে যদি payments_service ক্র্যাশ করে, users_service ও orders_service-এর কী হবে বলে আপনার ধারণা? মনোলিথে একই পরিস্থিতি হলে কী হতো?

    মাইক্রোসার্ভিসে যেহেতু প্রতিটি সার্ভিস আলাদা স্বতন্ত্র প্রসেস, payments_service ক্র্যাশ করলেও users_service ও orders_service স্বাভাবিকভাবে চলতে থাকতে পারে -- শুধু পেমেন্ট-সংক্রান্ত ফিচার অকার্যকর হবে। মনোলিথে যেহেতু সবকিছু একই প্রসেসে চলে, একটি অংশের গুরুতর ক্র্যাশ (যেমন একটি আনহ্যান্ডলড এক্সসেপশন যা পুরো প্রসেস বন্ধ করে দেয়) সম্ভাব্যভাবে ইউজার ও অর্ডার ফিচারকেও অকার্যকর করে দিতে পারে -- এটাই মাইক্রোসার্ভিসের একটি সুবিধা (ফল্ট আইসোলেশন), যদিও এর বিনিময়ে বাড়তি জটিলতা আসে (L54-এ আরও বিস্তারিত)।

  2. পরীক্ষা করুন: উপরের কোড সেলে microservice_registry-তে একটি নতুন এন্ট্রি "/reviews": lambda path: "রিভিউ ডেটা (reviews-service, নিজস্ব প্রসেস)" যোগ করুন, তারপর test_paths-এ "/reviews/5" যোগ করে Run চেপে দেখুন microservice_processes-এর সংখ্যা কত হয়।

    নতুন এন্ট্রি যোগ করার পর /reviews/5 পাথটি microservice_gateway-এ "/reviews" প্রিফিক্সের সাথে মিলে যাবে এবং সেই lambda ফাংশন কল হবে, যা রিভিউ ডেটা রিটার্ন করবে। microservice_processes সেটে এখন চারটি ভিন্ন প্রিফিক্স থাকবে (/users, /orders, /payments, /reviews), তাই সংখ্যাটি ৩ থেকে ৪-এ বেড়ে যাবে -- অথচ monolith_processes এখনও ১-ই থাকবে, কারণ monolith_handle ফাংশনে কোনো পরিবর্তন করা হয়নি (নতুন পাথের জন্য এটি এখনও "404 Not Found" দেবে, তবে একই একক প্রসেস-নাম দিয়েই)।

আরও পড়ুন · ABCL TECH-এ আপনার পরবর্তী পদক্ষেপ

  • কোর্সের সম্পূর্ণ সিলেবাস দেখুন ৫৮টি পাঠ আর্কিটেকচার প্যাটার্ন, ফ্রন্ট-এন্ড/ব্যাক-এন্ড ফ্রেমওয়ার্ক ফান্ডামেন্টাল, স্টেট ম্যানেজমেন্ট, REST API, ORM, অথেন্টিকেশন, রেন্ডারিং স্ট্র্যাটেজি ও ডিপ্লয়মেন্ট -- বাকি পাঠগুলো শীঘ্রই যুক্ত হবে।
  • System Design কোর্স সহোদর কোর্স মনোলিথ থেকে মাইক্রোসার্ভিসে স্কেল করার বিস্তৃত ডিস্ট্রিবিউটেড-সিস্টেম আলোচনা সেই কোর্সে করা হয়েছে; এই কোর্স ফ্রেমওয়ার্ক-স্তরের আর্কিটেকচারে ফোকাস করে।
  • সব Courses দেখুন ABCL TECH C, C++, Python, Java, JavaScript, DSA, DBMS, Discrete Mathematics, System Design, Cybersecurity, Cloud Computing & DevOps, Computer Networks, Operating Systems, Computer Architecture, Programming Languages & Compiler Design, Software Engineering & Git, Theory of Computation, Engineering Economics ও Full-Stack Web Frameworks -- সব এক জায়গায়।
আগের পাঠ
ফ্রন্ট-এন্ড বনাম ব্যাক-এন্ড বনাম ডেটাবেস — তিনটি স্তর