3 पॉइंट द्वारा GN⁺ 2023-09-13 | 1 टिप्पणियां | WhatsApp पर शेयर करें
  • microservices को default की तरह अपनाने वाली संस्कृति पर यह आलोचना है कि उसने वास्तविक scale problem नहीं, बल्कि मौजूद ही नहीं रहने वाली समस्याओं को हल करने के लिए लागत और जटिलता बढ़ाई है
  • JavaScript/Node.js ecosystem की बंद प्रकृति, FAANG-शैली की practices, और प्रचुर venture funding के मेल से startups में भी web-scale architecture की नकल करने का माहौल बना
  • Docker और Kubernetes होने पर भी development, debugging, deployment, testing, और resilience हासिल करने जैसी distributed systems की कठिनाइयाँ खत्म नहीं होतीं
  • Dropbox, Twitter, Netflix, Facebook, GitHub, Instagram, Shopify, StackOverflow, WhatsApp जैसी कंपनियाँ monolithic codebase से शुरू हुईं, या आज भी अपने core में monolith रखती हैं
  • ज़्यादातर कंपनियाँ उस scale तक पहुँचती ही नहीं जहाँ सचमुच distributed system की ज़रूरत हो, इसलिए केवल तभी किसी हिस्से को service के रूप में अलग करना व्यावहारिक है जब कोई load साफ़ तौर पर अलग करके scale करना ज़रूरी हो

जटिलता की पूजा करने वाली संस्कृति

  • सिर्फ़ किसी user का birthday पाने के लिए जटिल microservices भूलभुलैया समझाने में नाकाम रहने वाला व्यंग्य आज की tech culture में over-engineering पर निशाना साधता है
  • समस्या यह है कि तात्कालिक काम हल करने के बजाय लक्ष्य बदलकर मौजूद ही नहीं रहने वाली समस्या को हल करने में पैसा जलाने का हो गया है
  • JavaScript और Node.js की आलोचना सिर्फ़ किसी एक technology की समस्या नहीं, बल्कि ऐसे बंद software ecosystem के ख़तरे से जुड़ी है जो लोगों को पहले से सीखे गए सबक फिर से सीखने पर मजबूर करता है
  • industry पहले भी CORBA और SOAP जैसी जटिलता की दीवारों से टकराकर दिशा बदल चुकी है

microservices के चलन को बनाने वाली परिस्थितियाँ

  • browser के लिए JavaScript लिखने वाले developers खुद को “full-stack” कहकर server development और asynchronous code की दुनिया में आए; शुरुआती Node लगभग व्यक्तिगत learning project जैसा था, और शुरुआती JavaScript server development के लिए कई समस्याओं वाला विकल्प था
  • Node के बाहर की दुनिया मानो है ही नहीं, ऐसी सोच बन गई, और Node का तरीका ही एकमात्र तरीका है जैसी कट्टर सोच पैदा हुई
  • इसके बाद FAANG पृष्ठभूमि वाले लोग startups में आए और “Google में हम ऐसे करते थे” वाली पद्धतियों को context और scale की परवाह किए बिना सही जवाब की तरह फैलाया
    • अलग User Preferences Service न हो तो system scale नहीं करेगा, इस तरह का दबाव इसका प्रमुख उदाहरण है
  • venture funding प्रचुर होने के दौर में revenue से ज़्यादा investors को explosive growth दिखाना ज़रूरी हो गया, और कंपनियों ने महंगे software engineers को तेज़ी से hire करके उन्हें “कुछ न कुछ” करने में लगा दिया

distributed systems आज भी कठिन हैं

  • microservices को “scalable software लिखने का नया तरीका” बताकर पेश किया गया, लेकिन मूल रूप से यह बहुत पुराने distributed systems वाले सवालों से जुड़ा है
  • अतीत में distributed systems को कठिन और जोखिम भरे tools माना जाता था, और वे खास तौर पर मुश्किल समस्याओं के लिए अंतिम उपाय जैसे थे
  • distributed systems में नीचे दिए गए सभी काम ज़्यादा कठिन और ज़्यादा समय लेने वाले हो जाते हैं
    • development
    • debugging
    • deployment
    • testing
    • resilience हासिल करना
  • microservices-आधारित development के लिए कोई standard tools या common framework नहीं है, और 2020s में भी distributed systems का काम बस थोड़ा आसान हुआ है
  • Docker और Kubernetes distributed setup की मूलभूत जटिलता को जादू की तरह ख़त्म नहीं कर देते

जहाँ सादगी ने बेहतर नतीजे दिए

  • 5 साल के startup code audits से सीखी गई बातें के अनुसार, सफल startups ने लगभग बेशर्मी की हद तक Keep It Simple approach अपनाई
  • जल्दी microservices में जाना, distributed computing पर निर्भर architecture, और messaging-केंद्रित design कई कंपनियों के लिए बड़े pitfalls साबित हुए
  • कई startups सरल और high-performance systems बनाते हुए भी इस बात को लेकर झूठी हीनभावना महसूस करते हैं कि वे “पहले दिन से microservices” नहीं कर रहे
    • “अगर हमारे पास सिर्फ़ कुछ engineers द्वारा संभाला जा रहा Django monolith और MySQL instance है, तो इसमें ग़लत क्या है?” — इसका जवाब लगभग हमेशा होता है, “कुछ भी ग़लत नहीं”
  • अनुभवी engineers भी आज की tech culture में खुद को अनुपयुक्त महसूस कर सकते हैं, लेकिन असली समस्या अनुचित overconfidence, फिजूलखर्ची, और Dunning-Kruger के मिश्रण वाला माहौल हो सकती है

monolith के साथ बढ़ी कंपनियाँ

  • यह सोचना कि monolith के बिना growth नहीं हो सकती, लगभग एक मिथक है
  • Dropbox, Twitter, Netflix, Facebook, GitHub, Instagram, Shopify, StackOverflow जैसी कंपनियाँ monolithic codebase से शुरू हुईं, और कुछ आज भी अपने core में monolith बनाए हुए हैं
  • StackOverflow performance page पर यह गर्व से बताता है कि वह कम hardware पर बहुत बड़ी site चलाता है
  • Shopify अब भी Rails monolith इस्तेमाल करता है, और आज़माए हुए Resque से अरबों jobs संभालता है
  • WhatsApp ने Erlang monolith और लगभग 50 engineers के साथ भारी scale हासिल किया
    • engineering organization को लगभग 50 लोगों तक छोटा रखा
    • अलग-अलग teams 1–3 लोगों की थीं और उनमें उच्च स्वायत्तता थी
    • servers की संख्या कम रखना पसंद किया गया और हर server को जहाँ तक संभव हो vertically scale किया गया
  • Instagram को 12 लोगों की team के साथ अरबों डॉलर में acquire किया गया, और Threads भी Instagram मॉडल का अनुसरण करता है

मौजूद न होने वाली समस्याएँ हल नहीं करनी चाहिए

  • मूल सवाल है: “हम किस समस्या को हल कर रहे हैं?”
  • अगर scale समस्या है, तो यह दिखाने वाला data चाहिए कि क्या और क्यों अलग service में बाँटना है
  • distributed systems scale और resilience के लिए बनाए जाते हैं, लेकिन यह भी सोचना पड़ता है कि जब कोई service धीमी हो जाए या बंद हो जाए तो traffic दूसरी services पर कैसे टूट पड़ेगा
  • किन बातों पर विचार करना है, यह system के usage pattern और load characteristics पर निर्भर करता है
    • backpressure
    • circuit breaker
    • queue
    • jitter
    • सभी endpoints के लिए उचित timeout
    • safeguards ताकि छोटा बदलाव पूरे system failure में न बदल जाए
  • ज़्यादातर कंपनियाँ उस विशाल scale तक नहीं पहुँचतीं जहाँ सचमुच distributed systems की ज़रूरत हो
  • Amazon और Google के scale, expertise, और resources के बिना उनकी नकल करना समय और पैसे की बर्बादी बन सकता है
  • चेतावनी यही है कि खराब distributed system, distributed system न होने से भी ज़्यादा कठिन हो सकता है

team-आधारित services और API का आदर्श बनाम वास्तविकता

  • company structure के अनुसार distributed topology बनाने की कोशिश इस सोच से शुरू होती है कि समस्या को छोटे टुकड़ों में बाँट देने से काम आसान हो जाएगा
  • आदर्श microservice वह है जिसे एक dedicated team सख्ती से maintain करे, जो सुंदर और backward-compatible versioned API के पीछे छिपी हो, और जिसे चलाने के लिए दूसरी teams से लगभग कोई बातचीत न करनी पड़े
  • वास्तविकता में Slack channels release, bugs, config changes, breaking changes, और announcements से भरे रहते हैं
  • हर किसी को हर समय पूरे हालात समझने पड़ते हैं, और पहले से व्यस्त teams का कई microservices को ढीले-ढाले तरीके से संभालना आम बात है
  • लोगों के आने-जाने के साथ service ownership भी बदलती रहती है, और नतीजा एक अच्छी race car की जगह कई बेकार golf carts जैसा हो जाता है

microservices आपसे क्या छीन लेते हैं

  • DRY का कमज़ोर होना

    • microservices मूल रूप से DRY नहीं होते, और हर service में duplicate boilerplate घुस जाता है
    • छोटे microservices में plumbing code का हिस्सा इतना बड़ा हो सकता है कि औसत service instance product code से ज़्यादा “service” code बन जाए
    • common code अलग निकालने की कोशिश करें तो हर विकल्प दर्द देता है
      • common library बनाएँ तो versioning और update strategy तय करनी पड़ती है
      • सभी repositories में नियमित pull requests बनाकर forced update कराया जा सकता है
      • monorepo में बाँधें तो उसकी अपनी समस्याएँ आती हैं
      • कुछ code duplication स्वीकार करें, या हर team को बार-बार पहिया फिर से बनाना पड़े
  • developer experience का बिगड़ना

    • developer experience का मतलब है नई feature development या bug fix के लिए लगने वाला friction और effort
    • microservices environment में किसी खास काम के लिए कौन-कौन सी services चलानी हैं, किस team से और किस व्यक्ति से क्या पूछना है, यह समझने के लिए पूरे system का mental map चाहिए
    • Spotify ने ढेर सारे systems और services को सूचीबद्ध करने के लिए Backstage बनाया, और यह इस खेल की ऊँची लागत का संकेत है
    • जो कंपनियाँ Spotify नहीं हैं, वे अपने temporary solutions बनाती हैं, जिनसे robustness और portability की उम्मीद करना मुश्किल है
    • नई service शुरू करने के लिए बहुत सी चीज़ें automate करनी पड़ती हैं
      • GitHub/GitLab developer permissions
      • base environment variables और configuration
      • CI/CD
      • code quality checks
      • code review settings
      • branch rules और protection
      • monitoring और observability
      • test harness
      • infrastructure as code
    • अगर कई programming languages इस्तेमाल हों, तो यह सूची languages की संख्या के साथ बढ़ती जाती है
    • इस automation को ठीक-ठाक बनाने में महीनों लग सकते हैं, और फिर सवाल होता है: product बनाएँ या tools?
  • integration testing की कठिनाई

    • single-service tests और unit tests pass हो जाने पर भी यह अलग सवाल है कि हर commit के बाद core paths अब भी सही चल रहे हैं या नहीं
    • distributed setup की integration testing लगभग असंभव जैसी समस्या बन जाती है, और उसकी जगह observability ने ले ली है
    • observability एक नया industry segment बन चुका है, जो सिर्फ़ पैसा ही नहीं बल्कि developer time भी माँगता है
    • observability plugin की तरह तुरंत काम नहीं करती; canary releases और feature flags जैसी चीज़ों को समझना और implement करना पड़ता है
    • समस्या को टुकड़ों में बाँटने से समाधान आसान नहीं होता, बल्कि और कठिन समस्याओं का एक bundle मिल जाता है

monolith अपने-आप अच्छा code नहीं बन जाता

  • monolith के समर्थन का मतलब यह नहीं कि “monolith अच्छा code है और microservices बुरा code हैं”
  • वास्तविक दुनिया में जल्दबाज़ या औसत teams द्वारा बनाए गए कई औसत monoliths मौजूद हैं
  • लेकिन distributed systems अधूरे छोड़े गए हिस्सों, खराब निर्णयों, और छूटे हुए failure modes के प्रति कहीं ज़्यादा निर्दयी होते हैं
  • अगर आप हमेशा उच्च स्तर की operational discipline नहीं रखेंगे, तो distributed systems में उसकी क़ीमत चुकानी पड़ेगी

micro नहीं, सिर्फ़ service भी काफ़ी हो सकती है

  • service का “micro” होना ज़रूरी नहीं; कई बार सिर्फ़ service ही काफ़ी होती है
  • कुछ startups हर function के लिए service बनाने तक पहुँच गए, जो दिखाता है कि अप्रमाणित cargo cult कितनी दूर जा सकता है
  • monolith से शुरुआत करना एक साफ़-सुथरा विकल्प है
  • “trunk & branches” pattern भी कई मामलों में फिट बैठता है
    • core functionality एक “meat and potatoes” जैसे मुख्य monolith के ज़िम्मे होती है
    • साफ़ तौर पर पहचाने जा सकने वाले और अलग scale की ज़रूरत वाले loads branch services संभालते हैं
  • CPU-intensive Image-Resizing Service, User Registration Service की तुलना में अलग service के रूप में कहीं ज़्यादा समझ में आती है
  • असली कसौटी यह पूछना है कि क्या registrations प्रति सेकंड इतने ज़्यादा हैं कि उन्हें independent horizontal scaling की ज़रूरत पड़े

trend का पीछे हटना और व्यावहारिक चुनाव

  • microservices का अति-उत्साह अब ठंडा पड़ता दिख रहा है, और venture funding का प्रवाह सख्त होने के साथ market कंपनियों को ज़्यादा समझदारी भरे फैसले लेने पर मजबूर कर रहा है
  • जब आपके पास web-scale problem ही नहीं है, तब web-scale architecture पर पैसा खर्च करना टिकाऊ नहीं है
  • अगर आपको New York से Philadelphia जाना है, तो जटिल spaceship बनाने के बजाय 90 मिनट का Amtrak ticket खरीदना ही समस्या के अनुरूप समाधान है

1 टिप्पणियां

 
GN⁺ 2023-09-13
Hacker News की राय
  • मैं उन लोगों में से हूँ जिन्होंने microservices की ज़ोरदार वकालत की है, Netflix platform बनाने में मदद की है और दुनिया भर में घूमकर इनके फायदे बताए हैं, लेकिन जब startups को सलाह देता हूँ तो लगभग हमेशा कहता हूँ कि monolith से शुरुआत करो
    codebase और database को एक साथ रखना कहीं ज़्यादा आसान है, और यह काफी लंबे समय तक scale कर सकता है। DynamoDB जैसे key/value store का इस्तेमाल करने पर relational features में से कुछ खोते हैं, लेकिन आप और ज़्यादा समय तक टिक सकते हैं
    monolith को भी Lambda पर deploy किया जा सकता है, और services को तोड़े बिना भी Lambda के फायदे मिल सकते हैं
    बढ़ने के बाद ही उन हिस्सों को, जिन्हें स्वतंत्र रूप से scale करना हो या अलग deployment चाहिए हो, अपने data store वाले microservices के रूप में अलग करना चाहिए
    microservices सिर्फ platform बनाए रखने में engineering time का कम-से-कम 25% खा जाते हैं, इसलिए अगर आप उतनी efficiency वापस नहीं पा सकते तो उनका कोई मूल्य नहीं है

    • “काफी लंबे समय” कहना भी कम करके कहना है। अगर कोई SQL को कुछ हद तक संभालना जानता है, तो सिर्फ Postgres को बड़े DB server पर चलाकर ही आप किसी असली DBA को hire करने के बारे में सोचने से पहले 5 करोड़ rows वाली table तक पहुँच सकते हैं
    • उस मोड़ पर microservices में तोड़ने के बजाय monolith को components में refactor करना चाहिए, और tracing के जरिए असली performance metrics देखने चाहिए
      जब आप बढ़ रहे हों, या ज़्यादातर मामलों में, microservices बिल्कुल न करना ही बेहतर है
      और कृपया data को मत तोड़िए। data को manage करना code से कहीं ज़्यादा जटिल है
    • बात एक बहुत सरल सत्य पर आकर टिकती है। जितना संभव हो उतना सरल, और जितना जरूरी हो उतना ही जटिल बनाइए
      अभी से ज़्यादा जटिल बनाना आप कभी भी कर सकते हैं। monolith से कुछ हिस्से निकालकर service बना सकते हैं, और हाँ यह मुश्किल है, लेकिन system में पहले से घुस चुकी complexity को निकालने की तुलना में कुछ भी नहीं
      जिसने कई microservices को वापस monolith में बदला है वह जानता है कि आम तौर पर यह शुरू से फिर बनाने जितना काम हो जाता है
    • कई businesses को शुरुआत से ही scale करने की जरूरत नहीं होती। Netflix उस तरह का है जहाँ customers बहुत हैं और प्रति customer revenue कम है, लेकिन ऐसे businesses भी बहुत हैं—शायद ज़्यादा—जहाँ customers कम हैं और प्रति customer revenue अधिक है
      ऐसे products चाहें तो सचमुच laptop पर production environment चला सकते हैं
      पिछली नौकरी में 300 customers के लिए हमने microservices का मेला लगा रखा था। जबकि वह ऐसा business था जहाँ कुछ हजार customers होना ही success और दसियों हजार होना बड़ी success होता
      आम तौर पर platform maintenance पर engineering time का 25% खर्च नहीं किया जाता, इसलिए हालत यह हो जाती है कि local पर run भी नहीं हो पाता और production environment बस duct tape से किसी तरह जुड़ा रहता है
      हाल ही में एक interview में मुझसे “50 करोड़ concurrent users” वाला system design करने को कहा गया, जबकि वह company मोटे तौर पर कम customers और high revenue per customer वाले type की थी
      मुझे अभी भी नहीं पता कि यह जाँच थी कि मैं बता पाता हूँ या नहीं कि 50 करोड़ दुनिया की internet-connected आबादी का करीब 10% है और बिल्कुल बेतुका number है, या वे सच में मानते थे कि startup ऐसा हो सकता है
      मैंने जवाब दिया कि मैं सबसे सरल चीज़ पर focus करूँगा: monolith बनाऊँगा और यह validate करूँगा कि features और product लोगों को चाहिए या नहीं। मुझे hire नहीं किया गया
    • Netflix, Amazon, Reddit के scale तक पहुँचने से पहले मैं व्यक्तिगत रूप से microservices recommend नहीं करूँगा। उस scale पर भी अंदर वैसी expertise होनी चाहिए, नहीं तो यह nightmare बन जाता है
  • मैं लगभग 800 contributors वाले एक विशाल monolith में काम कर रहा हूँ, और user birthday जैसे साधारण field जोड़ना भी उतना ही complex है। हालांकि सारी complexity technical नहीं है; क्योंकि सबके code को छूना पड़ता है, “organizational alignment” चाहिए होता है
    design और review अंतहीन चलते रहते हैं, कम-से-कम 2 architects की approval चाहिए होती है, और यह कई planning cycles में जोड़ा जाता है। असली code में आधे दिन से भी कम लगता है
    code review में 90% test coverage चाहिए, लेकिन tests इतने ज्यादा हैं कि एक PR बहुत बड़ा हो जाता है, इसलिए उसे कई PRs में तोड़ना पड़ता है और कई weekly releases में डालना पड़ता है
    इसलिए इसे feature flag के पीछे छिपाया जाता है, और अभी feature flags 13,000 हैं
    production में जाने और dashboards व monitoring जुड़ने के बाद इसे बार-बार on/off किया जाता है। birthday feature ने billing service को क्यों बिगाड़ दिया, यह पक्का नहीं, लेकिन वजह वही लगता है, इसलिए कई हफ्ते analysis करना पड़ेगा
    आखिरकार 1 साल बाद, उस काम को संभालने वाला engineer अच्छा review पाता है और शायद promotion candidate बन जाता है। और फिर तुरंत उसे एक और broken project पर लगा दिया जाता है जो 3 साल से development में है: users को timezone set करने देने का काम

    • असली मुद्दा microservices बनाम monolith नहीं, बल्कि लेख में बताए गए complexity cult के apostles जैसा है
      microservices और monolith, दोनों ही universal hammer या silver bullet नहीं हैं, और उलटकर कहें तो अपने-आप में बुराई भी नहीं। दोनों trade-offs वाले tools हैं, और हर organization में अलग context के trade-offs से जुड़ते हैं
      समस्या यह है कि engineers complexity से मोहित हो जाते हैं और “simplicity” को “quick fix” समझ लेते हैं, और organizations tools व architecture patterns की अंधी नकल करती हैं
      सिर्फ architecture या design pattern इस्तेमाल करने से benefits मिलेंगे—ऐसा मानकर भोलेपन से apply करें तो वैसा नहीं होता
    • विशाल monorepo का समर्थन करने वाले लोग अक्सर भूल जाते हैं कि Google के पास उस single codebase को refactor और test करने के लिए tools ही बनाने वाली अलग teams हैं
    • सुनने में यह ऐसी company लगती है जो कोई भी tech stack paradigm इस्तेमाल करे, उसे बिगाड़ ही देगी
    • इस company पर code changes जल्दी release करने का कोई competitive pressure नहीं दिखता। लेकिन अगर कोई challenger आ गया या moat गायब हो गया तो यह problem बनेगा
      मैंने यह बात याद रखने की कोशिश की है कि software engineering complexity से लगातार लड़ने का काम है, और कभी सफलता मिली है तो कभी असफलता
      यह लड़ाई हमेशा लड़नी होती है और यही top priority होनी चाहिए। वरना ऐसे ही होता है
      इस युद्ध को खत्म कर देने वाला कोई architecture या ideology नहीं है; यही इस पेशे की प्रकृति है
    • 13,000 feature flags पागलपन है। पिछली नौकरी में यह अच्छा हुआ कि हमने उन नए features के लिए “release” flag इस्तेमाल करने पर जोर दिया जिन्हें explicitly कुछ customers के लिए on/off करने की जरूरत नहीं थी
      production environment में ऐसे release flags को enable नहीं किया जा सकता था, और developers को final testing और release से पहले flag code हटाना पड़ता था
      जिस feature को flag चाहिए, उसमें थोड़ा extra काम बढ़ता है, लेकिन कुछ महीनों बाद codebase complexity घटने का असर बहुत बड़ा होकर लौटता है
  • माइक्रोसर्विसेज़ किसी तकनीकी समस्या का नहीं, बल्कि एक सामाजिक समस्या का समाधान हैं
    N इंजीनियरों वाली टीम को N² स्तर के coordination की ज़रूरत होती है। बड़ी टीमें अंतहीन meetings, emails और design reviews में फँस जाती हैं, जबकि छोटी टीमें ज़्यादा प्रभावी होती हैं लेकिन बड़े सिस्टम को maintain करने में मुश्किल महसूस करती हैं
    सिस्टम को subsystems में बाँटने से हर टीम अपने puzzle के हिस्से पर focus कर सकती है और लोगों के बीच coordination घट सकता है
    यह सही है कि माइक्रोसर्विसेज़ complexity और overhead जोड़ती हैं, लेकिन यह approach बड़े organizations को बड़े systems तेज़ी से बनाने और iterate करके बेहतर करने में मदद करती है

    • असल में ऐसा नहीं होता। सिस्टम को subsystems में बाँटने से मौजूदा connections बस subsystems के बीच नए connections में map हो जाते हैं; मूल समस्या हल करने के लिए connections फिर भी चाहिए होते हैं
      अब direct connection के बजाय teams के बीच “cross-functional” meetings और एक complex communication layer की ज़रूरत पड़ती है
      अगर आपने ऐसा decomposition ढूँढ लिया है जिसमें subsystems के बीच connections की लगभग ज़रूरत ही नहीं, तो original system में भी वे connections मौजूद नहीं रहे होंगे और N² problem भी नहीं रही होगी
    • सिद्धांत में मैं सहमत हूँ, लेकिन व्यवहार में मैंने कभी teams को सचमुच माइक्रोसर्विसेज़-केंद्रित तरीके से organize होते नहीं देखा
      बार-बार जो देखा है वह “हर कोई हर माइक्रोसर्विस के लिए जिम्मेदार है” वाली एक विशाल team है, और अंत में कोई भी किसी चीज़ के लिए जिम्मेदार नहीं रहता
    • लगता है लोग भूल जाते हैं कि codebase में अलग directories बनाई जा सकती हैं
      “people problem” हल करने के नाम पर एक मामूली technical problem को complex distributed systems problem में बदल देते हैं
      अब सच में समस्या पैदा हो जाती है
    • सच कहूँ तो मुझे यह बात भी पक्की नहीं लगती कि छोटी teams को बड़े systems maintain करने में दिक्कत होती है। मैंने 7 अच्छे engineers के साथ 35 लाख lines वाले project को maintain किया है, जिसमें web UI और thick client दोनों थे
      वह दो तरह के databases support करता था, और उसमें horizontally scalable job runner भी था
      एक समय team में 35 लोग थे, लेकिन layoffs के बाद यह घटकर 7 रह गई, और उस समय हमने उल्टा कहीं ज़्यादा काम करना शुरू कर दिया। क्योंकि सबको align करने में लगने वाला समय बहुत घट गया था
      meetings, approvals, reviews, planning, retrospectives और management meetings बहुत कम हो गईं, developers को ज़्यादा discretion मिला और उन्होंने बस काम पूरा कर दिया
      features आधे समय में आसानी से निपट जाते थे, और बाकी 50% समय technical debt चुकाने में लगाते थे। complexity को बेरहमी से घटाने की वजह से नए features जोड़ने की speed भी बढ़ गई
      कुछ projects को शायद ज़्यादा लोगों की ज़रूरत हो, लेकिन मुझे लगता है कि तय समय में किसी system में जोड़ी जा सकने वाली complexity की एक ऊपरी सीमा होती है
      threshold पार करके developers बढ़ाने पर प्रति सप्ताह features की संख्या वही रहती है, बस सब थोड़ा कम काम करते हैं और communication में ज़्यादा समय लगाते हैं
      इस process को हज़ारों लोगों तक दोहराएँ तो एक field जोड़ने में महीनों लग जाते हैं
    • service में ही क्यों तोड़ना ज़रूरी है?
      सोचता हूँ, क्या अलग-अलग folders में ले जाने का तरीका कभी सोचा था?
      modularize करने के लिए नया repository और नया Docker setup बनाना ज़रूरी नहीं। बस folders इस्तेमाल कर लो
  • अक्सर दिखने वाला pattern यह है। मौजूदा CTO या VPs ने original monolith बनाया था या बनाने में शामिल थे
    कोई भी CTO से यह नहीं कहना चाहता कि वह code खराब है। या फिर बस समय बदल गया है और code को पूरी तरह overhaul की ज़रूरत है, जिसका monolith होने से कोई लेना-देना नहीं
    CTO marketing या fundraising में व्यस्त रहता है, इसलिए microservices या monolith का फैसला नहीं कर पाता, और नया hire किया गया architect फैसला लेता है
    हर कोई microservices पर खुश होता है। क्योंकि यह तेज़ी से बढ़ रही serious tech company की narrative में अच्छी तरह fit बैठता है, और कोई अकेले विरोध करना या CTO की आलोचना करना नहीं चाहता
    बहुत कम मामलों में कोई सचमुच इसलिए microservices recommend करता है कि वह सबसे अच्छा trade-off है। बल्कि इसलिए कि उन्हें अपना काम पसंद है, और लोगों को hire करना पसंद है, और यह company की narrative से अच्छी तरह मेल खाता है
    बड़े overhaul के दौरान बहुत सारा code फिर से लिखा और सुधारा जा सकता है, और उसे बस microservices migration कह दिया जाता है
    अंत में यह CTO की भावनाएँ आहत किए बिना, भीड़ के साथ चलते हुए, और लगभग सभी के समर्थन वाले कारण के नाम पर पुराने खराब code को बड़े पैमाने पर फिर से लिखने का तरीका बन जाता है

    • CTO का code खराब है यह कहना न चाहना कोई pattern नहीं, बल्कि लगभग अपरिहार्य बात है
      चाहे individual lead engineer हो या CTO/founder, आखिर पीछे मुड़कर देखने पर यही निष्कर्ष निकलता है कि चीज़ें बेहतर की जा सकती थीं, और team जिन patterns और processes को ईमानदारी से follow करती रही, उनके फायदे और नुकसान खुशी और डर दोनों के साथ दिखते हैं
    • अभी जो वर्णन किया गया, वह StumbleUpon के पिछले 5 सालों को हूबहू समझाता है
  • यह लेख मेरे bias को confirm करता है, इसलिए और अच्छा लगा
    मैं कई सालों से कहता आ रहा हूं, लेकिन मेरी राय में microservices का craze औसत engineers के लिए अपनी demand बनाए रखने का एक बहाना ही है। औसतपन इसे बढ़ावा देता है, और साथ ही कई tech companies को चलते रहने देता है
    ऐसे सक्षम engineers पर्याप्त नहीं हैं जो UNIX को सच में ठीक से संभाल सकें और StackOverflow जैसे खूबसूरत minimalist systems बना सकें
    इसलिए औसतपन को छिपाने के smoke screen के रूप में microservices बने रहेंगे। खासकर इसलिए भी, क्योंकि AWS जैसे cloud providers हर संभव channel से खुद को promote करते हैं और decision-makers को वही रास्ता चुनने के लिए प्रेरित करते हैं

    • समझ नहीं आता कि सुरक्षित monolithic system बनाए रखने की सलाह देने वाले architect को कोई hire क्यों नहीं करता या उसकी बात क्यों नहीं सुनता
      अगर आप cloud, microservices और बिना prove हुए नए frameworks की बात नहीं करते, तो आपको समय से पीछे छूटा हुआ बूढ़ा समझा जाता है
      जबकि ऐसे systems बहुत कम ही सबसे efficient, powerful या safe होते हैं
      मेरी मौजूदा कंपनी दूसरी companies के अंदर इस्तेमाल होने वाला software बनाती है, जिसमें concurrent users ज्यादा से ज्यादा 200 होते हैं और usage spikes भी नहीं आते
      यह एक साधारण web server के लिए perfect environment है, और unexpected scaling problems भी नहीं होने चाहिए, फिर भी हर कोई cloud पर जाना चाहता है
      मेरी राय में वजह यह है कि management, programmers, यहां तक कि customers भी cloud marketing से convince हो गए हैं और मानते हैं कि cloud cool है
    • गलत वजहों से, जैसे resume में अच्छा लगेगा, microservices को लेकर उत्साहित developers निश्चित रूप से हैं, लेकिन बड़ी समस्या यह है कि companies complexity को कैसे handle करती हैं
      company सिर्फ अपना org chart ही ship नहीं करती, बल्कि अपनी सारी dysfunctions और historical baggage भी product में भरकर भेजती है
      5 साल पहले वह एक खूबसूरत platform रहा होगा, जिसमें efficient और well-designed data model और API, अच्छी तरह लिखा और tested code था; लेकिन CEO के लगातार direction changes, sales team द्वारा धकेली गई last-minute customer requests, product managers द्वारा ऐसी features जोड़ना जिनकी न जरूरत थी न मांग, और कम staff व कम समय के कारण 5 साल बाद वह पूरी तरह mess बन सकता है
      एक दिन आप technical debt के विशाल ढेर के सामने खड़े मिलते हैं, जहां bug fixes और feature additions जरूरत से कहीं ज्यादा समय लेने लगते हैं, और microservices siren song की तरह कान में फुसफुसाते हैं कि सब कुछ जलाकर फिर से शुरू किए बिना भी काम चल सकता है
    • StackOverflow UNIX पर नहीं, बल्कि Windows पर बनाया गया था
      यह nitpicking जैसा लग सकता है, लेकिन इसमें बड़ा point है। technology choice बहुत कम मामलों में bottleneck होती है
    • मेरे अनुभव में औसत engineers भी Ruby on Rails जैसे opinionated framework का इस्तेमाल करके ठीक-ठाक monolith बना सकते हैं
      इसके उलट microservices में moving parts और failure modes ज्यादा होते हैं, इसलिए वे कहीं ज्यादा complex हैं; ऐसे में औसत engineers ही नहीं, कई non-average engineers भी problems पैदा करने की संभावना बहुत ज्यादा रखते हैं
    • औसत engineer से ज्यादा यह शायद कम अनुभव वाले engineers हो सकते हैं जो अपना resume भरना चाहते हैं
      लगता है हम इस काम में क्या जरूरी है, यह मौजूदा generation को ठीक से सिखाने में असफल रहे हैं
  • मैं एक छोटी team में microservices की ओर shift कर रहा हूं, इसलिए बात समझ आती है। सबसे बड़ी समस्या observability है
    operations में समस्या आने पर ठीक-ठीक क्या गलत हुआ, यह पता लगाना बहुत बड़ा tedious काम बन जाता है
    एक distributed application के logs follow करना काफी नहीं है; कई distributed applications के logs एक साथ देखने पड़ते हैं, जिनमें messages आपस में मिले-जुले होते हैं
    tracing को visualize करने वाला tool हो तो ठीक रहेगा, लेकिन छोटी team होने से लोगों की bandwidth limited है और अभी ऐसा tool नहीं है
    इसके उलट monolith में कई साल पहले से NewRelic integrated था। performance issues थे, लेकिन ज्यादातर indexes और कुछ materialized views से solve हो गए
    क्या गलत हुआ, यह समझना आसान है, और code पुराना तथा race conditions से भरा होने पर भी problem-solving खुद मुश्किल नहीं है
    हर microservice के लिए अलग database instance रखने और बाद में उन्हें upgrade करने की नौबत आने से डर लगता है। मैं चाहता था कि एक database instance में कई databases हों, लेकिन वह architecture option में नहीं है

    • OTEL(OpenTelemetry) tools और libraries, या Prometheus, Tempo, Loki वाले Grafana stack को देखना worthwhile होगा
      centralized logging और service calls/code execution की tracing कोई नई चीज नहीं है। बस अक्सर इसे बाद के लिए टाल दिया जाता है और फिर ऐसी unpleasant situation में फंस जाते हैं
      शुरुआत से सही tools न लगाने के कारण team और छोटी व ज्यादा constrained हो जाती है, क्योंकि services क्या कर रही हैं इसकी जानकारी बहुत कम या बिल्कुल नहीं होती
      database instances को एक-एक करके upgrade किया जा सकता है। अगर security जैसी कोई गंभीर bug न हो, तो सिर्फ इसलिए जल्दी करने की जरूरत नहीं कि upgrade possible है
    • सोच रहा हूं कि क्या आप cloud इस्तेमाल नहीं कर रहे। cloud providers centralized logging देते हैं, इसलिए अगर services के बीच request ID pass करें और log entries में वही ID डालें, तो services के बीच requests को trace किया जा सकता है
  • ऐसे लेख पढ़ने पर अजीब तरह से therapy जैसी feeling आती है। क्योंकि 10 साल पहले भी मैंने यही बात जोर से कही थी, लेकिन मुझे अविश्वासी समझकर चुप रहने को कहा गया था
    “microservices” paradigm ने मेरे मुंह में कड़वाहट छोड़ दी है, यह समझिए। मैंने खुद देखा है कि जब latest trendy technology के trade-offs को पूरी तरह समझे बिना उसे पूरी तरह अपना लिया जाता है, तो क्या नतीजे होते हैं
    बहुत पहले जब मुझे StumbleUpon में hire किया गया, उस समय एक leading computer science PhD, एक ठीक-ठाक चल रहे और revenue generate कर रहे PHP monolith को Scala/Java microservices architecture में बदलने की कोशिश कर रहा था
    onboarding process में उस पागल computer scientist के साथ एक अजीब 1:1 भी था, जिसमें उसने microservices के benefits पर लंबा भाषण दिया और “सिर्फ numbers की list जोड़ने के लिए distributed service क्यों बनाएं?” जैसे सवालों को “तुम समझ नहीं पाओगे कि यह कितना बेहतर है” वाली hand-waving से बड़ी सफाई से टाल दिया
    30 से ज्यादा नई hires और 4 साल से ज्यादा intense development के बाद, अब revenue न कमा रही company के पास बस एक धीमा, buggy और debug न हो सकने वाला distributed hellscape बचा था
    पूरे design का मालिक और architect उसी समय को “sabbatical” पर जाने के लिए सही मौका मान बैठा, और ज्यादा समय नहीं बीता कि पता नहीं कौन-सा funding round भी खत्म हो गया और सभी को नौकरियां ढूंढनी पड़ीं

  • Amtrak वाली उपमा उधार लें तो यह लेख पूरी तरह पटरी से उतर गया है
    लेखक यह मानकर चल रहा है कि अगर आपने घटिया microservices बनाए हैं, तो बस monolith बना लेने से सब जादुई ढंग से ठीक हो जाता
    यानी उसी स्तर के design और engineering से कचरा जैसे microservices बने हों, फिर भी अगर लक्ष्य monolith होता तो नतीजा सुनहरा निकलता
    लेख में जगह-जगह आत्मसंतुष्टि भी काफी है; full-stack JS developers पर की गई टिप्पणी इसका उदाहरण है
    लेकिन असली engineering नजरिए से सामग्री लगभग नहीं है। आप metrics या data की उम्मीद करें, तो बदले में बस लंबी-चौड़ी बात मिलती है
    system changes की cost कम रखने के लिए complexity manage करना अच्छा लक्ष्य है, लेकिन यह लेख जो सुझाता है वह यह नहीं है
    अगर इस बात को माना गया होता, या कोई data, या कम से कम एक anecdote भी दिया गया होता, तो लेख बेहतर होता
    हमारी team हो तो हम उस व्यक्ति के बजाय जो मानता है कि वह पहले से सब जानता है और आगे बढ़ने को कुछ नहीं बचा, ऐसे तेज और उत्साही frontend developer को चुनेंगे जो अपना दायरा बढ़ाकर full-stack developer बनना चाहता हो

    • पेश की गई dichotomy इतनी ज्यादा simplified है कि लेखक की विश्वसनीयता पर शक होने लगता है। कोई भी architecture हो, अगर उसे ठीक से maintain न किया जाए तो समय के साथ वह दबाव डालने वाला बोझ बन जाता है
    • सिक्के का दूसरा पहलू भी वैसा ही है। अगर आपने घटिया monolith बनाया है, तो यह दावा भी उतना ही गलत है कि बस microservices बना लेने से सब जादुई ढंग से ठीक हो जाता
  • मौजूदा workplace में मैं इस trend से लड़ रहा हूं, और कुछ teams में कुछ हद तक सफल रहा हूं, लेकिन दूसरी teams में बहुत कम। वे teams अब अपने बनाए हुए distributed monolith से जूझ रही हैं
    विडंबना यह है कि FAANMG के पूर्व कर्मचारी सभी monolith के पक्ष में हैं
    लगता है कई लोग यह बात चूक जाते हैं कि microservices एक iterative process का नतीजा हैं। आखिरकार monolith से वही हिस्से अलग किए जाते हैं जिन्हें scale करना होता है
    microservices को बहुत सारी ऐसी basic infrastructure चाहिए होती है जिसे जरूरत न हो तो कोई maintain नहीं करना चाहता
    ज्यादातर companies के पास उस pattern को support करने के लिए सही platform भी नहीं होता

  • सहमत हूं। हमारी company में tools ठीक से काम नहीं करते, इसलिए हमने debugging ही छोड़ दी है
    local machine पर एक service चलानी हो तो बाकी 9 को इस service से जुड़ने लायक configure करना पड़ता है
    customers के लिए कोई “feature” बनाना हो तो स्वाभाविक रूप से कम से कम 2 services को साथ में छूना पड़ता है और ज्यादा data move करना पड़ता है
    एक तरफ breakpoint लगाएं तो दूसरी तरफ timeout हो जाता है
    इसलिए सभी developers local VM में release build deploy करते हैं, hot reload के बिना console.log, System.PrintLines(), _logger डालते हैं और इधर-उधर बिखरी log files पढ़ते हैं
    जाहिर है, मैं यह जहाज छोड़ने वाला हूं

    • तीसरा paragraph कम से कम सब कुछ structured logs में बदलकर local aggregator को भेजने लायक बना दें तो कुछ हद तक सुधर सकता है
      सबको distributed tracing पर ले जाना और भी अच्छा होगा, लेकिन requests को ठीक से trace करने के लिए tracing metadata को पूरी तरह standardize करना पड़ता है, इसलिए investment ज्यादा है
      यह development से ज्यादा operations में मददगार होने की संभावना रखता है, लेकिन फिर भी मदद करेगा। सिर्फ सही span information भी इस अफरातफरी को समझने में काफी insight देती है
      अगर एक तरफ breakpoint दूसरी तरफ timeout करा देता है, तो सोचता हूं कि development mode में timeout बढ़ाने या बंद करने का कोई तरीका नहीं है क्या
    • हम mirrord और staging environment साथ में इस्तेमाल करते हैं, ताकि पूरा stack local पर उठाए बिना सिर्फ specific service चलाएं। services करीब 5 ही हैं, इसलिए वैसे भी यह बड़ी समस्या नहीं थी
    • Telepresence है