পাঠ ৫৪ · ৫৮-এর মধ্যে · মডিউল ১২
Home / Courses / Full-Stack Web Frameworks / মনোলিথ বনাম মাইক্রোসার্ভিস

মনোলিথ বনাম মাইক্রোসার্ভিস ডিপ্লয়মেন্ট স্ট্র্যাটেজি

Monolith vs microservice deployment strategies
৯ মিনিট পড়া উচ্চ-মধ্যবর্তী · Advanced Python কোডসহ সম্পূর্ণ বাংলায়

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

  • মনোলিথ ডিপ্লয়মেন্টের atomic (all-or-nothing) বৈশিষ্ট্য কেন এবং কীভাবে গঠনগতভাবে (structurally) নিশ্চিত হয়
  • মাইক্রোসার্ভিস ডিপ্লয়মেন্টে কেন আংশিক-ব্যর্থতা (এক সার্ভিস ব্যর্থ, বাকিরা সফল) সম্ভব
  • একটি "মিশ্র-ভার্সন" অবস্থা বাস্তবে সিমুলেট করে দেখা, এবং সেটি মনোলিথে কেন কখনো ঘটতে পারে না তা যাচাই করা
  • এই দুই স্ট্র্যাটেজির মধ্যে সিদ্ধান্ত নেওয়ার সময় বিবেচ্য বিষয়

১ · মনোলিথ ডিপ্লয়মেন্ট — একক, atomic ইউনিট

একটি মনোলিথ অ্যাপ্লিকেশনের সব অংশ (ফ্রন্ট-এন্ড সার্ভিং, API, ব্যবসায়িক লজিক) একটি একক প্রসেস/আর্টিফ্যাক্ট হিসেবে প্যাক করা ও ডিপ্লয় করা হয়। ডিপ্লয়মেন্ট মানে একটাই কল — পুরো অ্যাপ্লিকেশনকে একসাথে নতুন ভার্সনে সুইচ করা। এর ফলে ডিপ্লয়মেন্ট স্বভাবতই atomic হয় — হয় পুরো অপারেশন সফল, নাহলে পুরোটাই ব্যর্থ হয়ে আগের অবস্থায় ফিরে যায় (rollback)। যেহেতু ডিপ্লয় করার মতো ইউনিট মাত্র একটি, "কিছু অংশ নতুন, কিছু অংশ পুরনো" — এমন মিশ্র অবস্থা তৈরি হওয়ার কোনো উপায় নেই।

২ · মাইক্রোসার্ভিস ডিপ্লয়মেন্ট — একাধিক স্বাধীন ইউনিট

মাইক্রোসার্ভিস আর্কিটেকচারে অ্যাপ্লিকেশন একাধিক ছোট, স্বাধীন সার্ভিসে ভাগ করা থাকে (যেমন auth-service, user-service, payment-service) — প্রতিটির নিজস্ব ডিপ্লয়মেন্ট চক্র আছে। এর মানে প্রতিটি সার্ভিস আলাদাভাবে ডিপ্লয় করা হয় — একটি সার্ভিসের ডিপ্লয়মেন্ট ব্যর্থ হলেও অন্য সার্ভিসগুলোর ডিপ্লয়মেন্ট প্রভাবিত হয় না। এটি নমনীয়তা দেয় (একটি সার্ভিস স্বাধীনভাবে আপডেট/স্কেল করা যায়), কিন্তু এর মূল্য হলো সিস্টেমটি সাময়িকভাবে মিশ্র-ভার্সন অবস্থায় থাকতে পারে — কিছু সার্ভিস নতুন ভার্সনে, কিছু এখনো পুরনো ভার্সনে।

মনোলিথ
১টি ডিপ্লয় কল → সব-অথবা-কিছুই। সরল, কিন্তু ছোট পরিবর্তনের জন্যও পুরো অ্যাপ পুনরায় ডিপ্লয় করতে হয়।
মাইক্রোসার্ভিস
N-টি স্বাধীন ডিপ্লয় কল → আংশিক-সাফল্য সম্ভব। নমনীয়, কিন্তু ভার্সন সামঞ্জস্যতা নিজে থেকে সামলাতে হয় (ব্যাকওয়ার্ড-কম্প্যাটিবল API ডিজাইন প্রয়োজন)।

৩ · সিমুলেশন — মনোলিথ কখনো মিশ্রিত হয় না, মাইক্রোসার্ভিস হতে পারে

নিচের কোড সেলে দুটো অংশ আছে। প্রথমে deploy_monolith() — একটি একক ফাংশন কল যা "কম্পোনেন্ট"-দের একটি ডিকশনারি নিয়ে হয় সবগুলোকে একসাথে নতুন ভার্সনে পাঠায়, নাহলে ব্যর্থ হলে সবগুলোকে অপরিবর্তিত (রোলব্যাক) রাখে — একটি সফল ও একটি ব্যর্থ রান, দুটোতেই ফলাফলের ভার্সন-সেটের আকার (len(set(...))) হিসাব করে দেখানো হয়েছে এটি সবসময় 1 — অর্থাৎ মিশ্র অবস্থা কখনো ঘটে না। এরপর deploy_service() — প্রতিটি সার্ভিসের জন্য আলাদাভাবে কল হয়; ৪টি সার্ভিসের মধ্যে ৩টি সফল হয় ও একটি (payment-service) ইচ্ছাকৃতভাবে ব্যর্থ হয় — চূড়ান্ত অবস্থায় সত্যিই মিশ্র ভার্সন (কিছু নতুন, কিছু পুরনো) দেখা যায়।

Python
# ---------- মনোলিথ: একক, atomic ডিপ্লয়মেন্ট ----------

def deploy_monolith(components, new_version, fail=False):
    """components: {কম্পোনেন্ট_নাম: বর্তমান_ভার্সন} -- পুরো অ্যাপ একটি একক
    ডিপ্লয় কলে ডিপ্লয় হয়। সফল হলে সব কম্পোনেন্ট একসাথে new_version-এ যায়;
    ব্যর্থ হলে সবগুলো অপরিবর্তিত (রোলব্যাক) থাকে -- কখনো কিছু কম্পোনেন্ট নতুন,
    কিছু পুরনো থাকতে পারে না, কারণ এখানে প্রতিটি কম্পোনেন্টের জন্য আলাদা
    ডিপ্লয় কল নেই -- একটিমাত্র কল সবকিছু ঠিক করে।"""
    if fail:
        return dict(components), "ROLLED_BACK"          # সব কম্পোনেন্ট অপরিবর্তিত
    return {name: new_version for name in components}, "DEPLOYED"

components = {"web": "v1.0.0", "api": "v1.0.0", "worker": "v1.0.0"}

print("=== মনোলিথ -- সফল ডিপ্লয়মেন্ট ===")
state_ok, status_ok = deploy_monolith(components, "v1.1.0", fail=False)
print(f"  {state_ok}  |  status={status_ok}")
print(f"  আলাদা ভার্সনের সংখ্যা: {len(set(state_ok.values()))}")

print("\n=== মনোলিথ -- ব্যর্থ ডিপ্লয়মেন্ট ===")
state_fail, status_fail = deploy_monolith(components, "v1.1.0", fail=True)
print(f"  {state_fail}  |  status={status_fail}")
print(f"  আলাদা ভার্সনের সংখ্যা: {len(set(state_fail.values()))}")
print("  (দুটো রানেই আলাদা ভার্সনের সংখ্যা 1 -- মিশ্র অবস্থা structurally অসম্ভব)")

# ---------- মাইক্রোসার্ভিস: একাধিক স্বাধীন ডিপ্লয়মেন্ট ----------

def deploy_service(name, current_version, new_version, fail=False):
    """একটি একক সার্ভিসকে স্বাধীনভাবে ডিপ্লয় করে -- অন্য কোনো সার্ভিসের
    সাফল্য/ব্যর্থতার সাথে এর কোনো সম্পর্ক নেই।"""
    if fail:
        return current_version, "FAILED"
    return new_version, "DEPLOYED"

services = {
    "auth-service":    {"current": "v2.3.0", "new": "v2.4.0", "fail": False},
    "user-service":    {"current": "v1.8.0", "new": "v1.9.0", "fail": False},
    "payment-service": {"current": "v3.1.0", "new": "v3.2.0", "fail": True},   # ইচ্ছাকৃতভাবে ব্যর্থ
    "notify-service":  {"current": "v1.0.4", "new": "v1.0.5", "fail": False},
}

print("\n=== মাইক্রোসার্ভিস -- আংশিক-ব্যর্থতা পরিস্থিতি ===")
final_state = {}
for name, info in services.items():
    version, status = deploy_service(name, info["current"], info["new"], fail=info["fail"])
    final_state[name] = version
    print(f"  {name:18s} -> {version:8s} | {status}")

new_versions = {info["new"] for info in services.values()}
old_versions = {info["current"] for info in services.values()}
any_on_new = any(v in new_versions for v in final_state.values())
any_on_old = any(v in old_versions for v in final_state.values())
mixed = any_on_new and any_on_old

print(f"\nচূড়ান্ত অবস্থায় কেউ নতুন ভার্সনে আছে?: {any_on_new}")
print(f"চূড়ান্ত অবস্থায় কেউ পুরনো ভার্সনে আছে?: {any_on_old}")
print(f"মিশ্র-ভার্সন অবস্থা ঘটেছে?: {mixed}")
print("(payment-service পুরনো ভার্সনে রয়ে গেছে, বাকি তিনটি নতুন ভার্সনে চলে গেছে --")
print(" এই মিশ্র অবস্থা মাইক্রোসার্ভিসে সম্ভব, কিন্তু উপরের মনোলিথ সিমুলেশনে কখনোই ঘটেনি)")

    
মনোলিথ সিমুলেশনে components ডিকশনারির সব কম্পোনেন্ট শুরুতে একই ভার্সন ("v1.0.0") থেকে শুরু করে বলে len(set(...)) হিসাব সরাসরি বোঝায় — সফল রানে সবাই "v1.1.0"-এ যায় (সেট সাইজ ১), ব্যর্থ রানে সবাই "v1.0.0"-এ থেকে যায় (সেট সাইজ ১) — কোনো রানেই সেট সাইজ ১-এর বেশি হয় না। মাইক্রোসার্ভিস সিমুলেশনে payment-service-এর fail=True থাকায় সে তার current_version ("v3.1.0") ধরে রাখে, যেখানে বাকি তিনটি সার্ভিস তাদের নিজ নিজ new ভার্সনে চলে যায় — তাই mixed True হয়, যা মনোলিথে কখনো সম্ভব নয়।
মূল কথা · Key takeaway

মনোলিথ ডিপ্লয়মেন্ট একটি একক ডিপ্লয় কলের মধ্য দিয়ে যায় বলে গঠনগতভাবেই atomic — সব-অথবা-কিছুই, মিশ্র অবস্থা অসম্ভব। মাইক্রোসার্ভিস ডিপ্লয়মেন্ট একাধিক স্বাধীন কলের মধ্য দিয়ে যায় বলে নমনীয় (একটি সার্ভিস বাকিদের প্রভাবিত না করেই ব্যর্থ/সফল হতে পারে) কিন্তু এর দাম হলো সাময়িক মিশ্র-ভার্সন অবস্থা সামলানোর দায়িত্ব — যেমন ব্যাকওয়ার্ড-কম্প্যাটিবল API ডিজাইন। ব্যাপক distributed-systems স্কেল আলোচনা ../system-design/ কোর্সে রয়েছে।

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

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

প্র ০১ উপরের কোডে deploy_monolith()-এ যদি প্রতিটি কম্পোনেন্টের জন্য আলাদা if/for লুপে আলাদা সাফল্য/ব্যর্থতা নির্ধারণ করা হতো, তাহলে এটি কি এখনো "মনোলিথ" ডিপ্লয়মেন্ট বলা যেত?

না — যদি প্রতিটি কম্পোনেন্টের নিজস্ব স্বাধীন সাফল্য/ব্যর্থতা থাকতে পারত, তাহলে সেটি আসলে মাইক্রোসার্ভিস প্যাটার্নের অনুকরণ হয়ে যেত, নাম যাই হোক না কেন। মনোলিথের সংজ্ঞাগত বৈশিষ্ট্যই হলো একটি একক ডিপ্লয় সিদ্ধান্ত সব কম্পোনেন্টের জন্য প্রযোজ্য — উপরের কোডে fail একটি একক প্যারামিটার যা পুরো কলকে নিয়ন্ত্রণ করে, প্রতিটি কম্পোনেন্টকে আলাদাভাবে নয় — এটাই এর atomicity নিশ্চিত করে।

প্র ০২ মাইক্রোসার্ভিস সিমুলেশনে payment-service ব্যর্থ হলেও auth-service, user-service, notify-service কেন প্রভাবিত হয়নি?

কারণ প্রতিটি সার্ভিসের জন্য deploy_service() স্বতন্ত্রভাবে, নিজস্ব প্যারামিটার (current_version, new_version, fail) নিয়ে কল হয়েছে — একটি কলের রিটার্ন মান অন্য কলকে কোনোভাবেই প্রভাবিত করে না। লুপে প্রতিটি সার্ভিস তার নিজের info["fail"] মান অনুযায়ী স্বাধীনভাবে সফল বা ব্যর্থ হয়েছে — এটাই মাইক্রোসার্ভিসের মূল বৈশিষ্ট্য যা মনোলিথে সম্ভব নয়।

প্র ০৩ mixed = any_on_new and any_on_old — এই বুলিয়ান এক্সপ্রেশনটি "মিশ্র অবস্থা" সঠিকভাবে শনাক্ত করে কেন? যদি সবগুলো সার্ভিস ব্যর্থ হতো, তাহলে mixed-এর মান কী হতো?

mixed তখনই True হয় যখন চূড়ান্ত অবস্থায় অন্তত একটি সার্ভিস নতুন ভার্সনে এবং অন্তত একটি সার্ভিস পুরনো ভার্সনে থাকে — ঠিক যেটাকে আমরা "মিশ্র" বলি। যদি সবগুলো সার্ভিস ব্যর্থ হতো, তাহলে any_on_new হতো False (কেউই নতুন ভার্সনে যায়নি), তাই mixed হতো False — এটি সঠিক, কারণ "সবাই পুরনো ভার্সনে" একটি সুসংগত (uniform, যদিও ব্যর্থ) অবস্থা, মিশ্র অবস্থা নয়।

অনুশীলন

  1. চিন্তা করুন: একটি ছোট টিমের, কম ট্রাফিকের একটি প্রজেক্টের জন্য মনোলিথ ভালো নাকি মাইক্রোসার্ভিস — কোন বিষয়গুলো এই সিদ্ধান্তে প্রভাব ফেলে?

    ছোট টিম, কম ট্রাফিকের প্রজেক্টের জন্য সাধারণত মনোলিথ ভালো পছন্দ — কারণ একাধিক সার্ভিস পরিচালনা করার অপারেশনাল জটিলতা (প্রতিটির আলাদা ডিপ্লয়মেন্ট, নেটওয়ার্ক কল, ভার্সন সামঞ্জস্যতা) ছোট টিমের জন্য অতিরিক্ত বোঝা হয়ে দাঁড়ায়, অথচ এত কম ট্রাফিকে মাইক্রোসার্ভিসের স্বাধীন-স্কেলিং সুবিধা কার্যত অব্যবহৃত থেকে যায়। মাইক্রোসার্ভিসের সুবিধা তখনই স্পষ্টভাবে প্রকাশ পায় যখন টিমের আকার ও ট্রাফিকের স্কেল বড় হয় এবং বিভিন্ন অংশ ভিন্ন হারে পরিবর্তন/স্কেল করার প্রয়োজন হয়।

  2. পরীক্ষা করুন: উপরের কোড সেলে services ডিকশনারিতে "user-service"-এর "fail" মানও True করে দিন (এখন দুটো সার্ভিস ব্যর্থ), Run চেপে দেখুন final_state-এ কতগুলো সার্ভিস পুরনো ভার্সনে থাকে এবং mixed-এর মান কী হয়।

    এখন payment-service ও user-service — দুটোই তাদের current_version-এ থেকে যাবে, আর auth-service, notify-service নতুন ভার্সনে যাবে। mixed এখনও True থাকবে, কারণ এখনও অন্তত একটি সার্ভিস নতুন ভার্সনে এবং অন্তত একটি পুরনো ভার্সনে আছে — শুধু "কতগুলো" সার্ভিস মিশ্রণের কোন পাশে আছে তা বদলেছে, মিশ্র-অবস্থা থাকা/না-থাকার সিদ্ধান্ত বদলায়নি। এটি দেখায় মাইক্রোসার্ভিসে একাধিক স্বাধীন ব্যর্থতা একসাথে ঘটতে পারে, প্রতিটি অন্যগুলো থেকে সম্পূর্ণ স্বাধীনভাবে।

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

  • কোর্সের সম্পূর্ণ সিলেবাস দেখুন ৫৮টি পাঠ আর্কিটেকচার প্যাটার্ন, ফ্রন্ট-এন্ড/ব্যাক-এন্ড ফ্রেমওয়ার্ক ফান্ডামেন্টাল, স্টেট ম্যানেজমেন্ট, REST API, ORM, অথেন্টিকেশন, রেন্ডারিং স্ট্র্যাটেজি ও ডিপ্লয়মেন্ট — বাকি পাঠগুলো শীঘ্রই যুক্ত হবে।
  • System Design কোর্স সহোদর কোর্স মাইক্রোসার্ভিস স্কেল করা, সার্ভিস ডিসকভারি ও ব্যাপক distributed-systems আর্কিটেকচারের বিস্তারিত সেই কোর্সে কভার করা হয়েছে।
  • সব 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 — সব এক জায়গায়।
আগের পাঠ
ফুল-স্ট্যাক প্রজেক্টের জন্য CI/CD পাইপলাইন