माइक्रोसर्विसेज़ की लागत (2020)
(robertovitillo.com)- बैकएंड आम तौर पर मोनोलिथ के रूप में शुरू होता है, लेकिन जब कई feature teams उसी codebase को छूने लगती हैं, तो coupling बढ़ सकती है और बदलाव की गति धीमी हो सकती है
- माइक्रोसर्विसेज़ business function के हिसाब से सेवाओं को बाँटकर independent deployment और छोटी टीमों की autonomy पाने का तरीका हैं
- अगर सेवाएँ जरूरत से ज्यादा छोटी हों, तो फायदे से अधिक operational burden बढ़ जाता है, और “micro” नाम उल्टा निर्णय को धुंधला कर सकता है
- पूरी तरह अपनाने पर standardization, resource provisioning, remote calls से बचाव, CI/CD, operations, और eventual consistency तक व्यापक लागतें आती हैं
- आम तौर पर मोनोलिथ में boundaries को पर्याप्त समझ लेने के बाद, जब growing pains बड़े हो जाएँ तब एक-एक करके अलग करना सुरक्षित होता है; microservices-first approach तब उपयुक्त है जब अनुभव और platform readiness मौजूद हो
जब मोनोलिथ बड़ा होता है तो दिखने वाली सीमाएँ
- आधुनिक single-page JavaScript application का बैकएंड आम तौर पर RESTful HTTP API देने वाली और relational database इस्तेमाल करने वाली एक single stateless web service के रूप में शुरू होता है
- यह service अलग-अलग business functions लागू करने वाले components या libraries से बनी होती है
- जैसे-जैसे एक ही codebase में काम करने वाली feature teams बढ़ती हैं, components के बीच coupling बढ़ती है और teams के काम के क्षेत्र overlap होने लगते हैं
- productivity घटती है, और बदलाव का असर कहाँ तक जाएगा इसका अनुमान लगाना मुश्किल हो जाता है
- codebase पर्याप्त जटिल हो जाए तो कोई भी उसे पूरी तरह नहीं समझ पाता, जिससे नए features लागू करने और bugs ठीक करने में ज्यादा समय लगता है
- भले ही बैकएंड team-wise libraries में बँटा हो, library में बदलाव अंततः service redeployment तक पहुँचता है
- memory leak जैसा bug आ जाए तो पूरी service प्रभावित हो सकती है
- गलत build को rollback करने पर सिर्फ bug बनाने वाली team नहीं, बल्कि सभी teams की गति प्रभावित होती है
service boundaries से मिलने वाली autonomy
- monolithic backend की growing pains कम करने का एक तरीका बैकएंड को independently deployable services के समूह में बाँटना है
- services API के जरिए communicate करती हैं, और API उसी process के अंदर component boundaries की तुलना में ऐसी boundaries बनाती है जिन्हें पार करना कठिन होता है
- इस architecture को microservices architecture कहा जाता है, लेकिन
microशब्द गलतफहमी पैदा कर सकता है- services का छोटा होना अनिवार्य नहीं है
- बहुत कम functionality वाली service फायदे से अधिक operational burden पैदा कर सकती है
- अधिक उपयुक्त नाम service-oriented architecture हो सकता है, लेकिन इस नाम के साथ भी पुराना baggage जुड़ा है
छोटी teams और independent services से बनने वाली speed
- बैकएंड को business function के अनुसार services में बाँटने पर हर service को एक छोटी single team develop और operate कर सकती है
- छोटी teams अधिक प्रभावी होती हैं, क्योंकि communication cost team size के साथ वर्ग के अनुपात में बढ़ती है
- जब हर team अपना release schedule तय करती है और codebase को control करती है, तो teams के बीच coordination कम होता है और decisions तेज होते हैं
- service codebase छोटा हो तो developers के लिए समझना आसान होता है और नए hires का onboarding time भी घटता है
- छोटा codebase IDE slowdown कम करके developer productivity में भी मदद करता है
- मजबूत service boundaries की वजह से developers को बैकएंड का कोई हिस्सा बदलते समय पूरे system के बजाय केवल एक छोटे हिस्से को समझना पर्याप्त होता है
- हर service स्वतंत्र रूप से scale कर सकती है और अपनी जरूरतों के अनुसार technology stack चुन सकती है
- API consumers को इस बात की चिंता नहीं होती कि functionality अंदर कैसे implement की गई है
- system के दूसरे क्षेत्रों को प्रभावित किए बिना नई technologies को experiment और evaluate करना आसान होता है
- हर microservice का अपना data model और data store हो सकता है
- developers दूसरे services को प्रभावित किए बिना schema बदल सकते हैं
माइक्रोसर्विसेज़ जोड़ने वाली वास्तविक लागत
- माइक्रोसर्विसेज़ पूरे system में अधिक moving parts जोड़ती हैं, और यह लागत मुफ्त नहीं है
- माइक्रोसर्विसेज़ को पूरी तरह अपनाने की लागत तभी चुकाने लायक है जब उसे दर्जनों development teams में distributed amortization के जरिए फैलाया जा सके
-
development experience
- हर service में अलग-अलग languages, libraries और data stores इस्तेमाल करना संभव है, लेकिन इससे application maintenance कठिन हो सकता है
- software stacks पूरी तरह अलग हों तो developers के लिए एक team से दूसरी team में जाना मुश्किल होता है
- logging जैसी सभी services को चाहिए common functionality देने के लिए अपनाई गई हर language के लिए libraries support करनी पड़ती हैं
- कुछ स्तर की standardization जरूरी है
- recommended languages और technology portfolio अपनाने वाली teams को अच्छा development experience देकर कुछ technologies के उपयोग को ढीले ढंग से प्रोत्साहित किया जा सकता है
-
resource provisioning
- कई independent services को support करने के लिए servers, data stores और अन्य general-purpose resources आसानी से create किए जा सकने चाहिए
- हर team को resource creation का अपना अलग तरीका बनाने नहीं देना चाहिए
- provisioned resources को फिर configure करना पड़ता है, और इसे संभालने के लिए काफी automation चाहिए
-
communication
- remote calls महंगी होती हैं और system के टूटने के नए तरीके पेश करती हैं
- failures के लिए तैयार रहने हेतु timeouts, retries और circuit breakers जैसे defensive mechanisms चाहिए
- network communication की performance loss कम करने के लिए asynchronous processing और batching भी इस्तेमाल करनी चाहिए
- ये elements system complexity बढ़ाते हैं
- remote client access और third-party APIs के उपयोग की वजह से monoliths भी समान समस्याओं से गुजर सकते हैं, लेकिन पैमाना छोटा होता है
-
continuous integration, delivery, deployment
- continuous integration यह सुनिश्चित करता है कि automated build और tests चलने के बाद code changes main branch में merge हों
- code changes merge होने पर उन्हें production-जैसे environment में automatically publish और deploy होना चाहिए
- उस environment में integration tests और end-to-end tests चलाकर यह confirm किया जाता है कि microservice उन दूसरी services को तोड़ नहीं रही जिन पर वह निर्भर है
- individual microservice tests monolith tests से अधिक कठिन नहीं होते, लेकिन सभी microservices की integration testing कहीं अधिक कठिन होती है
- individual services के interact करने पर बेहद subtle और unexpected behavior सामने आ सकता है
-
operations
- monolith के विपरीत, हर service-owner team के लिए अलग operations team रखना कहीं अधिक महंगा है
- service develop करने वाली team आम तौर पर उसी service की on-call responsibility भी लेती है
- team को हर sprint में तय करना पड़ता है कि development work और operational burden में किसे prioritize किया जाए, और इनके बीच friction पैदा होता है
- system failures debug करना भी कठिन हो जाता है
- पूरी application को local machine पर चलाकर debugger से step through नहीं किया जा सकता
- moving parts ज्यादा होने से failure modes भी ज्यादा होते हैं
- हर level पर अच्छी logging और monitoring महत्वपूर्ण हो जाती है
-
eventual consistency
- application को कई services में बाँटने पर data model अब सिर्फ एक data store में मौजूद नहीं रहता
- अलग-अलग data stores में records को atomically update करना और strong consistency guarantee करना धीमा, महंगा और implement करना कठिन है
- ऐसी architecture को आम तौर पर eventual consistency स्वीकार करनी पड़ती है
कब अलग करना चाहिए
- application को services में बाँटने से पूरे system की complexity काफी बढ़ जाती है
- सामान्य तौर पर monolith से शुरू करना और केवल पर्याप्त कारण होने पर ही उसे तोड़ना बेहतर है
- services के बीच boundaries सही तरीके से तय करना कठिन है, इसलिए monolith के अंदर boundaries को इधर-उधर करके उपयुक्त जगह ढूँढना ज्यादा आसान है
- जब monolith पर्याप्त mature हो जाए और growing pains बढ़ने लगें, तब microservices को एक-एक करके अलग किया जा सकता है
- microservices-first approach तभी शुरू करना उचित है जब पहले से अनुभव हो, इसके लिए platform बनाया गया हो, या platform बनाने में लगने वाला समय ध्यान में रखा गया हो
1 टिप्पणियां
Hacker News की रायें
लेख से मोटे तौर पर सहमत हूं, लेकिन उलट कर देखें तो कुछ मामलों में लागत उठाना वाजिब भी हो सकता है: पुराने third-party dependency compatibility issues को अलग service में निकालकर दर्दनाक refactoring या खुद से reimplementation से बचा जा सकता है, high-availability core system की deployment constraints को दूसरे systems की deployment रोकने से रोका जा सकता है, और बड़े customers जिन design constraints को बदल नहीं सकते उन्हें isolate किया जा सकता है
इसका मतलब यह नहीं कि यह मुफ्त है; मतलब यह है कि एक simple monolith को कचरे के ढेर में बदलने से, risky deployments से उसे हिलाने से, या खराब tech stack वाले business partner से बंधने से बचने के लिए यह चुकाने लायक लागत हो सकती है
Microservices क्या वह approach नहीं है जिसमें internal components को मूल रूप से libraries या classes के बजाय services बनाया जाता है?
Machine learning inference service Python में, server-side rendering UI Rails में, और I/O व concurrency-heavy service Go में लिखने जैसा हो, तो इन तीनों को अलग services में बांटने का अतिरिक्त बोझ justified हो सकता है
मुझे microservices पसंद हैं, लेकिन premature optimization और premature scaling उतने ही खराब हो सकते हैं जितना वह technical debt जो बाद में बिल्कुल अलग दिशा में optimize करने की जरूरत पड़ने पर पैदा होता है
किसी चीज को अलग service में निकालने का समय तब होता है, जब ऐसा न करने पर कोई problem manageable तरीके से हल नहीं हो सकती
boundaries enforce करने के लिए architectural complexity बढ़ाना organizational discipline की कमी का समाधान नहीं हो सकता, लेकिन mid-sized tech companies लगातार इसे ऐसे ही treat करती हैं। अगर domain boundaries कमजोर होने से problem आ रही है, तो service extract करने पर भी उसके अच्छी तरह हल होने की संभावना कम है
उद्धरण: https://www.oreilly.com/library/view/software-architects-han...
Tests pass होने तक PR रोकने वाला CI/CD भी organizational discipline problem को हल करने के लिए एक महंगा technical solution है
Domain name resolution किसी external service से कराना ठीक है, यह सब मानते हैं, और recursive DNS resolver व cache को monolith में integrate करने वाले लोग बहुत कम हैं। फिर भी जिम्मेदारियों का यह पुराना विभाजन example के तौर पर ठीक से स्वीकार नहीं किया जाता
समस्या शायद यह है कि जितना “अच्छा” employee होता है, वह value दिखाने के लिए उतना ही ज्यादा उत्साहित होता है, जिससे over-engineering होती है और आखिर में नरक बन जाता है
Microservices
grug को समझ नहीं आता कि big brain लोग system को सही तरह decompose करने की सबसे कठिन problem उठाकर उसमें network calls भी क्यों जोड़ देते हैं
grug को यह बहुत confusing लगता है
https://grugbrain.dev/#grug-on-microservices
“SCALE_REASONS की वजह से FOO_TABLE access approach को modernize करने के लिए MySQL से DynamoDB पर जाना चाहता हूं, लेकिन 59 teams में से 32 teams FOO_TABLE को direct access कर रही हैं या हमारी class के private methods direct call कर रही हैं। Priorities अलग हैं, इसलिए वे teams FOO_SERVICE इस्तेमाल करने पर migrate नहीं कर सकतीं या sharded tables इस्तेमाल करने के लिए अपनी query approach नहीं बदल सकतीं। अब FOO_TABLE को scale करना कई quarters का काम बन जाता है, और teams को धीरे-धीरे update करने देना पड़ेगा। 1–2 साल बाद शायद अभी जल रही पुरानी approach retire की जा सके। तब तक on-call का मजा लीजिए”
Microservices में team को पता चलेगा कि table scale नहीं हो रही, लेकिन data API के जरिए दिया जाता है। अगले sprint में migration plan और execute कर देंगे, और API users को लगेगा कि यह बहुत तेज हो गया है
Modern Ruby का REPL खोलें तो autocomplete और syntax checking के लिहाज से static typed language IDE से जो उम्मीद होती है, उसका काफी हिस्सा मिल जाता है
Isolation को हल्के में नहीं लेना चाहिए; यह software में जोड़े जा सकने वाले सबसे powerful features में से एक है। यह performance बढ़ा सकता है, failure boundaries बना सकता है, और security boundaries दे सकता है
यह actor model की core concept जैसा है। दो components एक-दूसरे की memory share और modify करने के बजाय, actor या microservice जैसे दो isolated systems सिर्फ defined protocol से communicate करते हैं
मुझे लगता है कि लोग modularity को गलत समझते हैं। modularity ज़रूरी है, लेकिन मुझे यह भी लगने लगा है कि एक और अहम architecture principle है: single vortex principle
software system में vortex, data flow का loop होता है। अगर आप data को कहीं भेजते हैं और processed result वापस लेते हैं, या किसी भी तरह उस data से प्रभावित होते हैं, तो वहाँ vortex है। mutable variable बहुत छोटे vortex का उदाहरण है
single vortex principle का मतलब है कि आदर्श रूप से software system में सिर्फ एक vortex होना चाहिए, या यूँ कहें कि हर component को पता होना चाहिए कि उसका vortex किस दिशा में घूम रहा है
जब दो vortex बनाने वाले modules को एक में मिलाते हैं, तो अगर vortex की direction मेल खाती है तो composition आसान होती है; अगर opposite direction हो तो यह तय करना पड़ता है कि नए vortex की direction क्या होगी, इसलिए मामला पेचीदा हो जाता है। इसलिए सबसे अच्छा यह है कि सभी modules के vortex एक ही direction में हों और मिलकर एक vortex बनाएं
यह principle Flux pattern, CQRS, event sourcing, immutability जैसे ideas का generalization है
या A में कुछ अप्रत्याशित हो जाए तो C block हो सकता है। आदर्श रूप से parent को सिर्फ child को call करना चाहिए और parent पर निर्भर नहीं होना चाहिए; अगर यह fail होता है तो architecture भी fail हो गई
architecture diagram देखते समय आधी लड़ाई यह समझने की होती है कि क्या asynchronous/synchronous है, push/pull क्या है, और flow की direction और order क्या है
enterprise service bus और message queue ऐसी जगहों पर vortex बनाने का solution लगते हैं जहाँ दोनों directions मेल नहीं खातीं
एक जगह यह बात है कि समस्या है “adopt की गई हर language के लिए एक-एक करके, सभी services को चाहिए होने वाली logging जैसी common functionality देने के लिए support करनी पड़ने वाली libraries की संख्या”
यही हमारे microservices छोड़ने का सबसे बड़ा कारण था। 2023 के tools, खासकर pure cloud-native या infinitely scalable FaaS environment में, ऐसी चिंता पर mental bandwidth खर्च करना पूरी तरह waste है। bank और financial institution जैसे customer segments के लिए तो और भी, क्योंकि वे हर third-party dependency की बहुत कड़ी जाँच करते हैं
अभी हम gzip में करीब 250MB के single monolithic .NET binary distribution के साथ चल रहे हैं, और दरार के कोई संकेत नहीं हैं। अगर आप 10–100MB के SaaS distribution को लेकर “मेरा exe अब L2 में fit नहीं होता” जैसी बारीक चिंताएँ कर रहे हैं, तो निश्चिंत रहें। monolithic software journey तो अभी शुरू भी नहीं हुई है
अगर कभी ऐसी garbage heaps में से किसी एक को फिर से लिखना पड़े, तो क्या यह कहीं आसान नहीं होगा कि हर commit globally consistent एक ही जगह पर हो?
microservices का मतलब यह नहीं कि वह lawless zone है और हर team पूरे organization को ध्यान में रखे बिना काम कर सकती है। teams के बीच कुछ हद तक consistency बनाए रखने के लिए rules हो सकते हैं और होने भी चाहिए
सबसे अच्छा code वह है जिसे फेंककर फिर से लिखना आसान हो। practical तौर पर पुराना code ज्यादा हाथों से गुजरता है, और खराब होता जाता है; सबसे बढ़कर, कोई उसे maintain करना नहीं चाहता
microservices पसंद करने वाले कहते हैं कि service को कैसे behave करना चाहिए इसका clear contract होता है और उस service का codebase काफी छोटा होता है, इसलिए change या rewrite करना आसान है
monolith पक्ष कहता है कि सब कुछ एक बड़े धागे के गुच्छे जैसा है, इसलिए एक धागा बदलने के लिए बस यह जानना होता है कि वह दूसरे धागों से कहाँ जुड़ता है, इसलिए change या rewrite करना आसान है
कौन सही है, पता नहीं। कई सालों से codebase को microscope से देखने वाले long-tenured लोगों के लिए monolith बेहतर हो सकता है, और बाकी लोगों के लिए microservices
release management के नज़रिए से देखें तो monolith से microservices की ओर जाना अक्सर गलत वजहों से होता है
वास्तविक बदलाव की एकमात्र वाजिब वजह performance bottleneck से जुड़ी scalability problem लगती है। बाकी सब software development की complexity को system maintenance में shift करने जैसा ही है
बेशक developers को यह पसंद आएगा, क्योंकि दूसरी teams के साथ तालमेल बैठाने का बड़ा बोझ कम हो जाएगा। लेकिन features कब और कैसे implement होते हैं, microservices में सही तरह test होते हैं, production में activate और centrally manage होते हैं—यह साफ़ करना तब बहुत कठिन हो जाता है जब development teams के बीच communication पर्याप्त mature न हो। और वही immaturity अक्सर monolith तोड़ने की असली वजह होती है
इसके उलट, developers कम हों और context अच्छी तरह defined हो, तो कई microservices संभालना तकलीफदेह है
“बाकी सब software development की complexity को system maintenance में shift करना है” — अगर software active development में है तो यह बात plausible लगती है। development महंगा है। distributed system का maintenance cost, एक बड़ी monolith develop करने की cost से कम भी हो सकता है; आखिरकार यह situation पर निर्भर करता है
“मोनोलिथ की लागत” वाला लेख कहाँ है? यहाँ तो वह दिख नहीं रहा। असल में सभी लोग बिना समझे माइक्रोसर्विसेज़ लागू कर रहे हैं, इसलिए सिर्फ वही समस्या दिखती है
अगर सभी लोग बिना समझे मोनोलिथ बना रहे होते, तो “मोनोलिथ खराब है” वाले लेख बहुत बड़ी संख्या में दिखते
लोग यह नहीं समझते कि दोनों सिस्टम आखिरकार समान मात्रा की समस्याएँ पैदा करते हैं। यह एक हाथी से काम करवाने और 1000 चूहों से काम करवाने के फर्क जैसा है। दोनों में समस्याएँ आती हैं, बस समस्याएँ अलग होती हैं
दोनों में से किसी एक को चुन लेने से समस्याएँ गायब नहीं होतीं। किसी भी तरफ समस्या आएगी, और एक को चुनकर उसका समाधान देना होगा। अगर किसी कंपनी में “कौन-सा architecture है” ही सबसे बड़ी बाधा है, तो मैं वहाँ काम करना चाहूँगा
अगर मोनोलिथ अच्छी तरह decomposed है, तो उसी जगह deploy की गई माइक्रोसर्विसेज़ से वह कैसे अलग है? शायद सिर्फ interface में। function call RPC बन जाता है, और components को अलग-अलग संभालने के फायदे मिलते हैं, जैसे patching के लिए थोड़ा overhead स्वीकार करना
distributed माइक्रोसर्विसेज़ और एक ही location में मौजूद माइक्रोसर्विसेज़ में क्या फर्क है? deployment ज्यादा जटिल होता है, लेकिन processes को अधिक उपयुक्त hardware पर समझदारी से रखा जा सकता है। failure modes बढ़ते हैं, लेकिन ज्यादा fault tolerance मिलती है
इसका कोई universal answer नहीं है। अगर फायदे चाहिए, तो लागत चुकानी पड़ेगी। मेरे हिसाब से ऐसी माइक्रोसर्विसेज़ बनाम मोनोलिथ बहसें या तो किसी pattern को गलत लागू करने से, या जीवन आसान बनाने वाले tools की कमी से, या अक्सर 10 साल पुराने software को लगातार refactor और redesign न करने से पैदा होती हैं, जिससे initial architecture चाहे जो भी हो, उस पर काम करना पीड़ादायक हो जाता है
“function call RPC बन जाता है” कहना सरल लगता है, लेकिन उस पल से client app को DNS server unavailable, hostname resolution failure, host unreachable, connection refused, authentication denied, untrusted TLS certificate, rate limit exceeded, 301 permanent redirect, result preparation delay, timeout जैसे सभी execution paths handle करने पड़ते हैं
अच्छी तरह decomposed app को भी इन्हें robust तरीके से handle करने के लिए async queue, request rate limiting, result cache, logged backoff retry, configurable client credentials/trust store/resource URL, और failure logging सक्षम करने के लिए redesign करना पड़ सकता है
local function call में जो data context में था, उसे उपलब्ध कराने के लिए RPC functions और parameters भी अलग से चाहिए होंगे। साथ ही monolith UI को अब users तक network latency और failures पहुँचाने पड़ सकते हैं, जो पहले संभव ही नहीं थे
सबसे अच्छी तरह बनाया गया monolith भी माइक्रोसर्विसेज़ में refactor करने के लिए काफी मेहनत माँगता है
क्या इस RPC call को safe तरीके से retry किया जा सकता है? exponential backoff? API load balancer सही चल रहा है या नहीं—तो monitoring भी चाहिए। माइक्रोसर्विसेज़ के बीच tracing कैसे करेंगे? अब OpenTelemetry जैसी चीज़ चाहिए हो जाती है
माइक्रोसर्विसेज़ architecture में breakpoint लगाकर debugging कितनी ज्यादा कठिन हो जाती है? दो माइक्रोसर्विसेज़ के बीच database transaction को rollback कैसे करेंगे? एक साधारण function call अचानक बहुत ज्यादा जटिल हो जाती है
इस concept का बचाव करते समय हर बार यह calculation से छूट जाता है कि services को बहुत छोटा रखने की requirement कितनी fragmentation पैदा करती है। और साफ कहें तो अगर एक monolith और एक microservice है, तो वह microservices नहीं हैं। microservices शब्द का मतलब यह imply करता है कि सब कुछ छोटी-छोटी services में टूटा है और कोई monolith नहीं है
माइक्रोसर्विसेज़ के पक्ष में दिए जाने वाले ज्यादातर तर्क उसी क्षण ढह जाते हैं जब समझ आता है कि उन्हें अनिवार्य रूप से “micro” होना है। और अगर वह requirement छोड़ दें, तो कोई नया या गहरा प्रस्ताव बचता ही नहीं
operations के नजरिए से “deployment ज्यादा जटिल है” कहना बहुत बड़ा understatement है। हर package अपनी अलग विशेषताओं और समस्याओं वाला, अलग से manage करने योग्य object होता है
जैसे frontend developers सोचते हैं कि React/Vue/Svelte जैसे frontend framework या library के बिना “modern web app” नहीं बनाया जा सकता, वैसे ही आजकल लगता है कि “monolith” का मतलब किसी डरावने विशाल tar ball को single instance के रूप में चलाना है, इसलिए वह “scale नहीं करता”—यह धारणा घूम रही है, लेकिन यह बेतुकी है
एक और बात दिखती है कि कुल code मात्रा बहुत बढ़ जाती है, और ज्यादातर services 20% business/domain code और 80% network message send/receive handling से बनी होती हैं। आप इसे कितना भी छिपाएँ, आखिरकार वह वहीं है, और किसी न किसी तरह network से निपटना ही पड़ेगा
frontend madness की तरह यह microservices cult भी तब खत्म होगा जब economy खराब होगी और ऐसी विनाशकारी Babel towers को सहारा देने के लिए पैसा नहीं बचेगा
साथ ही, माइक्रोसर्विसेज़ की अपनी जगह भी है। कुछ companies के भीतर, जहाँ लागत से ज्यादा value मिलती है, वहाँ यह सही है
per-service independent scaling जैसे technical benefits भी हैं, लेकिन सबसे बड़ा फायदा clear ownership boundaries और unnecessary tight coupling को रोकना है
अगर एक छोटी team single product बना रही है, तो संभव है कि वह organizational problem अभी मौजूद ही न हो जिसे माइक्रोसर्विसेज़ हल करती हैं, इसलिए इसकी जरूरत न हो। उस case में माइक्रोसर्विसेज़ premature optimization हैं, यानी ऐसी समस्या हल करने की कीमत चुकाना जो अभी है ही नहीं
आगे कहूँ तो frontend complexity पूरी तरह दिमाग में है: https://bower.sh/front-end-complexity
लेख मानो यह मानकर चलता है कि development organization पूरी तरह बिगड़ी हुई है और control से बाहर है। sprint के दौरान क्या करना है यह तय नहीं कर पाते, चुपके से third-party libraries और अनजान languages ले आते हैं, और incompatible changes को चुपचाप production में deploy कर देते हैं
अगर developers बेवकूफ नहीं हैं, तो microservices भी ज़्यादा आसान लगेंगी
अगर आप smart और सक्षम developers वाली team में काम करते हैं, तो मुझे यकीन है कि microservices ज़्यादा आसान होंगी। हालांकि तब तो सब कुछ ही ज़्यादा आसान हो जाएगा