PHP Academy · पाठ

मोनोलिथ से माइक्रोसर्विसेज़ तक

तय करें कि क्या अलग करना है और सेवा-सीमाएँ कैसे निर्धारित करनी हैं।

पाठ 1, कुल 4 में से13 चरण

मोनोलिथ से माइक्रोसर्विसेज़ तक, CoddyKit पर PHP Academy का एक निःशुल्क पाठ है। यह 4 में से 1वाँ पाठ है। आप नीचे पूरा पाठ निःशुल्क पढ़ सकते हैं—फिर अंतर्निहित कोड संपादक और 24/7 एआई ट्यूटर के साथ ब्राउज़र में इसका व्यावहारिक अभ्यास कर सकते हैं। यह PHP Academy सीखने के मार्ग का हिस्सा है और आपकी प्रगति वेब तथा CoddyKit ऐप पर सिंक होती रहती है। PHP Academy पाठ्यक्रम में कुल 4 पाठ शामिल हैं।

मोनोलिथ से माइक्रोसर्विसेज़ तक

माइक्रोसर्विसेज़ कोई डिफ़ॉल्ट विकल्प नहीं, बल्कि संगठनात्मक और संचालन संबंधी निर्णय हैं। किसी PHP मोनोलिथ को विभाजित करने पर एक ही प्रक्रिया के भीतर की सरलता के बदले नेटवर्क कॉल, वितरित डेटा और परिनियोजन की जटिलता मिलती है। गलत कारणों से किया गया विभाजन सब कुछ धीमा कर देता है।

यह पाठ सबसे कठिन हिस्से पर केंद्रित है: सेवा-सीमाएँ निर्धारित करना। जोड़ सही हों तो बाकी काम केवल आधारभूत जोड़-तोड़ रह जाता है; जोड़ गलत हों तो आप एक वितरित मोनोलिथ बना लेते हैं—पूरी लागत, कोई लाभ नहीं।

विभाजन क्यों करें (और क्यों न करें)

विभाजन करने के अच्छे कारण:

  • स्वतंत्र परिनियोजन-क्षमता और टीम का स्वामित्व।
  • अधिक भार वाले उपतंत्रों को स्वतंत्र रूप से बढ़ाने की क्षमता।
  • तकनीक/रनटाइम का अलगाव और त्रुटियों का सीमांकन।

बुरे कारण हैं: "कोड अव्यवस्थित है" (पहले मोनोलिथ को पुनर्गठित करें), या किसी चलन के पीछे भागना। यदि दो सेवाओं को हमेशा साथ में परिनियोजित करना पड़े या वे एक ही डेटाबेस तालिका साझा करें, तो वे वास्तव में एक ही सेवा हैं जो दो भूमिकाएँ निभा रही है।

सीमाबद्ध संदर्भ

डोमेन-चालित डिज़ाइन सीमाएँ तय करने के लिए सबसे सटीक साधन देता है: सीमाबद्ध संदर्भ। किसी संदर्भ के भीतर शब्दों का एक ही सटीक अर्थ होता है। बिलिंग में "ग्राहक" (जिसके लिए चालान बनाया जाता है) और सहायता में "ग्राहक" (टिकट लिखने वाला) अलग-अलग होते हैं।

प्रत्येक सीमाबद्ध संदर्भ सेवा के लिए एक मजबूत उम्मीदवार है। सीमाएँ व्यावसायिक भाषा और संगठन में वास्तव में होने वाले संवाद के अनुरूप बनती हैं—यही कॉनवे का नियम व्यवहार में है।

उच्च सामंजस्य, कम युग्मन

सेवा की अच्छी सीमा उन चीज़ों को भीतर रखती है जो साथ-साथ बदलती हैं, और उन चीज़ों को बाहर करती है जो स्वतंत्र रूप से बदलती हैं। प्रस्तावित विभाजन का मूल्यांकन इन बातों से करें:

  • कितनी सुविधाओं के लिए एक ही समय में दो सेवाओं को छूना पड़ता है? (ऐसी सुविधाएँ कम होनी चाहिए।)
  • उनके बीच कॉल का तरीका कितना अधिक संवादात्मक है? (कॉल मोटे स्तर के होने चाहिए।)

यदि एक सुविधा लागू करते समय बार-बार किसी सीमा के दोनों ओर काम करना पड़े, तो सीमा गलत जगह पर है।

<?php
// Chatty boundary smell: N network calls to render one view
foreach ($order->lineItems as $item) {
    $product = $catalogApi->get($item->productId); // one call PER item!
    $names[] = $product['name'];
}

// Coarse-grained: one batch call across the boundary
$ids   = array_map(fn($i) => $i->productId, $order->lineItems);
$names = $catalogApi->getMany($ids); // single round-trip
echo count($names) . " products in one call\n";

प्रति सेवा एक डेटाबेस

अटल नियम यह है: प्रत्येक सेवा अपने डेटा की स्वामी होती है और कोई दूसरी सेवा उसकी तालिकाओं को नहीं छूती। साझा डेटाबेस उस युग्मन को फिर से बना देते हैं जिससे बचने के लिए आपने विभाजन किया था—स्कीमा में बदलाव असंबंधित सेवाओं को तोड़ देता है।

इसका अर्थ है कि वे सेवाओं के बीच की पूछताछ, जो मोनोलिथ में SQL JOIN थी, अब एपीआई कॉल या प्रतिकृत पठन-मॉडल बन जाती है। यही इसकी कीमत है और यही इसका उद्देश्य भी।

<?php
// In the monolith: one JOIN across domains
$sql = 'SELECT o.id, c.email
        FROM orders o JOIN customers c ON c.id = o.customer_id';

// After split: Orders service holds only the foreign id;
// it asks the Customers service for the rest (or keeps a local read model).
$order = $orderRepo->find($id);          // local
$customer = $customersApi->get($order->customerId); // network call
echo $order->id . ' / ' . $customer->email . "\n";

स्ट्रैंगलर फ़िग प्रतिरूप

मोनोलिथ को एक ही बड़े बदलाव में कभी न लिखें। स्ट्रैंगलर फ़िग प्रतिरूप क्रमिक रूप से हिस्से निकालता है: किसी नए सेवा-मुखौटे/प्रॉक्सी के माध्यम से ट्रैफ़िक के एक हिस्से को नई सेवा तक भेजें, उसे विकसित करें, और पुराना कोड-पथ तभी हटाएँ जब नया पथ उसे पूरी तरह संभालने लगे।

एक रिवर्स प्रॉक्सी (या एपीआई गेटवे) सामने रहता है और प्रत्येक मार्ग के लिए तय करता है कि अनुरोध पुराने मोनोलिथ तक भेजना है या नई सेवा तक। प्रवासन एक समय में एक क्षमता के अनुसार आगे बढ़ता है और हर चरण में परिनियोजित किया जा सकता है।

<?php
// Facade routing: peel off one capability at a time
function route(string $path): string {
    $migrated = ['/invoices', '/invoices/pdf']; // moved to billing-svc
    foreach ($migrated as $prefix) {
        if (str_starts_with($path, $prefix)) {
            return 'http://billing-svc' . $path;
        }
    }
    return 'http://legacy-monolith' . $path; // everything else, for now
}
echo route('/invoices/pdf'), "\n";
echo route('/users/42'), "\n";

किसी मॉड्यूल को अलग करना

व्यावहारिक निष्कर्षण क्रम:

  1. ऐसा मॉड्यूल खोजें जिसकी आवक निर्भरताएँ कम हों और डेटा का स्वामित्व स्पष्ट हो।
  2. पहले मोनोलिथ में उसके प्रक्रिया-भीतर वाले कॉल को एक इंटरफ़ेस के पीछे रखें।
  3. उसके स्वामित्व वाले डेटा को अपने अलग स्कीमा/डेटाबेस में ले जाएँ।
  4. इंटरफ़ेस के कार्यान्वयन को नेटवर्क क्लाइंट से बदल दें।
  5. मुखौटे के माध्यम से ट्रैफ़िक बदलें; पुराना कोड हटा दें।

पहले मोनोलिथ के भीतर इंटरफ़ेस-आवरण करने से नेटवर्क वाले चरण का जोखिम कम हो जाता है।

<?php
// Step 2: hide the implementation behind a port the monolith calls
interface InvoiceService {
    public function generate(string $orderId): string; // returns invoice id
}

// Today: local class. Tomorrow: HTTP client to billing-svc.
// The monolith's calling code never changes.
final class LocalInvoiceService implements InvoiceService {
    public function generate(string $orderId): string { return 'inv-1'; }
}

वितरित डेटा संगति

डेटा विभाजित होने के बाद आप सेवाओं के बीच ACID लेन-देन खो देते हैं। अंततः संगति को स्वीकार करें: सेवाएँ अपने डेटा के बारे में घटनाएँ प्रकाशित करती हैं और अन्य सेवाएँ उन घटनाओं से स्थानीय पठन-मॉडल बनाती हैं।

ऑर्डर्स सेवा हर अनुरोध पर कस्टमर्स से पूछताछ नहीं करती—वह एक छोटा प्रक्षेपण रखती है (केवल आवश्यक फ़ील्ड), जिसे CustomerUpdated घटनाएँ अद्यतन करती हैं। इससे रनटाइम निर्भरता और विलंबता का एक अतिरिक्त पड़ाव हट जाता है।

<?php
// Orders service keeps a tiny local projection of customer data
function onCustomerUpdated(PDO $db, array $evt): void {
    $db->prepare(
        'INSERT INTO customer_read_model (id, email)
         VALUES (:id, :email)
         ON CONFLICT (id) DO UPDATE SET email = EXCLUDED.email'
    )->execute(['id' => $evt['id'], 'email' => $evt['email']]);
}

संचालन की वास्तविकता

माइक्रोसर्विसेज़ जटिलता कोड से हटाकर संचालन में ले जाती हैं। विभाजन करने से पहले आपके पास ये सुविधाएँ होनी चाहिए:

  • केंद्रीकृत लॉग लेखन और वितरित अनुरेखण (हर पड़ाव पर सहसंबंध पहचानकर्ता)।
  • प्रति सेवा सतत एकीकरण/सतत परिनियोजन और स्वतंत्र संस्करणयुक्त परिनियोजन।
  • हर कॉल पर स्वास्थ्य-जाँच, समय-सीमा, पुनःप्रयास और सर्किट-ब्रेकर।
  • अनुबंध परीक्षण, ताकि प्रदाता चुपचाप उपभोक्ता को तोड़ न सके।

यदि आपकी टीम एक सेवा को अच्छी तरह नहीं चला सकती, तो दस सेवाएँ दस गुना अधिक खराब स्थिति पैदा करेंगी।

सेवाओं का उचित आकार निर्धारण

"माइक्रो" भ्रामक है—सेवाओं का आकार व्यावसायिक क्षमता और टीम के स्वामित्व के अनुसार तय करें, कोड की पंक्तियों के अनुसार नहीं। बहुत सूक्ष्म (नैनोसर्विसेज़) होने पर एक सुविधा नेटवर्क कॉलों के तूफ़ान में फैल जाती है; बहुत मोटे स्तर की होने पर आप फिर मोनोलिथ में लौट जाते हैं।

एक उपयोगी नियम है: किसी सेवा का स्वामित्व एक टीम ले सके, उसे स्वतंत्र रूप से परिनियोजित किया जा सके और वह कई सहकर्मी सेवाओं से होकर गुजरने वाली समकालिक श्रृंखला के बिना अपने मुख्य उपयोग-मामले पूरे कर सके।

मॉड्यूलर मोनोलिथ का विकल्प

वितरित प्रणाली पर जाने से पहले मॉड्यूलर मोनोलिथ पर विचार करें: एक ही परिनियोजनीय इकाई, लेकिन भीतर से स्पष्ट सीमाओं और अपने-अपने स्कीमा वाले मॉड्यूलों में विभाजित, जो केवल प्रकाशित इंटरफ़ेस के माध्यम से संवाद करते हैं—मॉड्यूलों के बीच तालिकाओं तक कोई पहुँच नहीं।

आपको वितरित प्रणालियों की अतिरिक्त लागत के बिना स्वच्छ सीमाएँ और आसान पुनर्गठन मिलता है। जब किसी मॉड्यूल को सचमुच स्वतंत्र विस्तार या स्वामित्व की आवश्यकता हो, तब वह स्ट्रैंगलर प्रतिरूप के माध्यम से बाहर निकाले जाने के लिए पहले से तैयार होता है। अधिकांश टीमों के लिए यह सही पहला पड़ाव है।

<?php
// Modules talk only through interfaces, never each other's tables.
namespace App\Billing;          // owns billing_* tables
interface BillingFacade {
    public function invoiceForOrder(string $orderId): string;
}

namespace App\Sales;            // owns sales_* tables
final class Checkout {
    public function __construct(private \App\Billing\BillingFacade $billing) {}
    // Sales never SELECTs from billing_* directly - only via the facade.
}

त्वरित जाँच

गलत विभाजन को पहचानना।

पुनरावलोकन

सेवा-सीमाएँ सही ढंग से निर्धारित करना:

  • परिनियोजन-क्षमता, विस्तार और स्वामित्व के लिए विभाजन करें—कोड के अव्यवस्थित होने के कारण नहीं।
  • सीमाओं को सीमाबद्ध संदर्भों के अनुरूप रखें; उच्च सामंजस्य और कम युग्मन का लक्ष्य रखें।
  • प्रति सेवा एक डेटाबेस—कोई साझा तालिका नहीं; JOIN को एपीआई या पठन-मॉडल से बदलें।
  • स्ट्रैंगलर फ़िग प्रतिरूप से क्रमिक रूप से प्रवासन करें।
  • अंततः संगति स्वीकार करें और विस्तार करने से पहले संचालन में निवेश करें।

अगला विषय: ये सेवाएँ वास्तव में एक-दूसरे से कैसे संवाद करती हैं—REST और gRPC।

शुरुआत निःशुल्क

एआई शिक्षक के साथ PHP सीखें — निःशुल्क

अपने ब्राउज़र में वास्तविक कोड लिखें और चलाएँ, चौबीसों घंटे एआई शिक्षक से तुरंत सहायता पाएँ, और वेब या ऐप पर वहीं से शुरू करें जहाँ आपने छोड़ा था।

पाठ्यक्रम
49
पाठ
195

अक्सर पूछे जाने वाले प्रश्न

क्या “मोनोलिथ से माइक्रोसर्विसेज़ तक” पाठ निःशुल्क है?

हाँ—“मोनोलिथ से माइक्रोसर्विसेज़ तक” का पूरा पाठ यहाँ वेब पर निःशुल्क पढ़ा जा सकता है। इंटरैक्टिव अभ्यास (अंतर्निहित कोड संपादक और 24/7 एआई ट्यूटर) करने और PHP Academy पाठ्यक्रम का बाकी हिस्सा अनलॉक करने के लिए CoddyKit PRO लें। PHP Academy पाठ्यक्रम में कुल 4 पाठ शामिल हैं।

“मोनोलिथ से माइक्रोसर्विसेज़ तक” में मैं क्या सीखूँगा?

तय करें कि क्या अलग करना है और सेवा-सीमाएँ कैसे निर्धारित करनी हैं। आप ब्राउज़र में सीधे चलाए जाने वाले व्यावहारिक कोड के साथ PHP Academy का अभ्यास करते हैं, और पाठ पूरा करते समय 24/7 एआई ट्यूटर आपके प्रश्नों के उत्तर देता है।

क्या PHP Academy शुरू करने के लिए मुझे किसी अनुभव की आवश्यकता है?

पहले के अनुभव की आवश्यकता नहीं है। CoddyKit पर PHP Academy शुरुआती से लेकर उन्नत शिक्षार्थियों तक सभी के लिए व्यवस्थित किया गया है, इसलिए आप यहीं से या शुरुआत से सीखना शुरू कर सकते हैं और अपनी गति से आगे बढ़ सकते हैं। यह 4 में से 1वाँ पाठ है।

“मोनोलिथ से माइक्रोसर्विसेज़ तक” पाठ पूरा करने में कितना समय लगता है?

CoddyKit का अधिकांश पाठ लगभग 5–10 मिनट में पूरा हो जाता है। हर पाठ छोटा और संवादात्मक है, इसलिए आप लगातार प्रगति करते हैं और वेब या ऐप पर वहीं से सीखना जारी रख सकते हैं जहाँ आपने छोड़ा था।

क्या मैं इस PHP Academy पाठ में कोड लिख और चला सकता हूँ?

हाँ। हर PHP Academy पाठ में एक अंतर्निर्मित कोड संपादक शामिल है, जिससे आप सीधे अपने ब्राउज़र में वास्तविक कोड लिख और चला सकते हैं और तुरंत एआई प्रतिक्रिया पा सकते हैं—स्थानीय सेटअप की आवश्यकता नहीं है।

इस पाठ्यक्रम के सभी पाठ

  1. मोनोलिथ से माइक्रोसर्विसेज़ तक
  2. सेवा संचार: REST और gRPC
  3. API गेटवे और सेवा खोज
  4. लचीलापन: सर्किट ब्रेकर और पुनःप्रयास
← PHP Academy पर वापस जाएँ