TechForge-ன் புதிய வழிகாட்டி, பல தொடக்கநிலை மைக்ரோசர்வீஸ் (microservices) திட்டங்கள் "பரவலாக்கப்பட்ட மோனோலிதங்களாக" (distributed monoliths) மாறிவிடுவதாக எச்சரிக்கிறது; இவை அளவிடுதல் (scaling) நன்மைகள் ஏதுமின்றி, நெட்வொர்க் அழைப்புகளின் தாமதத்தை (latency) மட்டுமே வழங்குகின்றன. பொறியியல் குழுக்கள் ஒரு வலுவான மோனோலிதத்துடன் (monolith) தொடங்குமாறும், தெளிவான அளவிடுதல் அல்லது உரிமைத் தேவைகள் எழும்போது மட்டுமே அதைத் தனித்தனியாகப் பிரிக்க வேண்டும் என்றும் இக்கட்டுரை வலியுறுத்துகிறது.

குழுக்கள் ஏன் மைக்ரோசர்வீஸ்களுக்கு அவசரத் துரிதமாகச் செல்கின்றன

மைக்ரோசர்வீஸ்களின் ஈர்ப்பு வெளிப்படையானது: தனித்தனி சேவைகள், தனித்தனி வரிசைப்படுத்தல்கள் (deployments), மற்றும் ஒரு பயன்பாட்டின் ஒவ்வொரு பகுதியையும் அதன் சொந்த நிபந்தனைகளின்படி அளவிடும் வாக்குறுதி. ஸ்டார்ட்-அப் கலாச்சாரம் மற்றும் சமீபத்திய வெற்றிச் கதைகள் இந்த முறையை நவீன பொறியியலின் அடையாளமாக மாற்றியுள்ளன. இருப்பினும், ஒரு மோனோலிதத்தை மிக விரைவாகப் பிரிப்பது பெரும்பாலும் ஒரு புதிய வகை மோனோலிதத்தையே உருவாக்குகிறது—அதாவது டஜன் கணக்கான நெட்வொர்க் இணைக்கப்பட்ட கூறுகள். இதன் விலை என்ன? அதிக தாமதம் (latency), கடினமான பிழைத்திருத்தம் (debugging), மற்றும் அதிக செயல்பாட்டுச் சுமை (operational overhead), அதே நேரத்தில் அசல் நன்மைகள் எட்டாக்கனியாகவே இருக்கின்றன.

முதல் தவறு: பெயரளவில் மட்டுமே மோனோலிதத்துடன் தொடங்குவது

குழுக்கள் பெரும்பாலும் ஒரு ஒற்றை குறியீட்டுத் தொகுப்பை (codebase) மற்றும் பகிரப்பட்ட தரவுத்தளத்தை (shared database) வைத்திருக்கும் அதே வேளையில், ஒரு அமைப்பை "மைக்ரோ-சர்வீஸ்-அடிப்படையிலானது" என்று பெயரிடுகிறார்கள். இதன் விளைவாக, HTTP அல்லது RPC மூலம் ஒன்றுடன் ஒன்று பேசிக்கொள்ளும் நெருக்கமான பிணைப்பு கொண்ட தொகுதிகள் (tightly coupled modules) உருவாகின்றன. வழிகாட்டி இதை "பரவலாக்கப்பட்ட மோனோலிதம்" (distributed monolith) என்று அழைக்கிறது. இதன் சிக்கல்கள் ஒரு பாரம்பரிய மோனோலிதத்தைப் போன்றதே—நெருக்கமான பிணைப்பு மற்றும் மற்றவற்றை பாதிக்காமல் ஒரு பகுதியை மாற்றுவதில் உள்ள சிரமம்—கூடுதலாக நெட்வொர்க் தாவல்களால் (network hops) ஏற்படும் கூடுதல் தாமதமும் இதில் உள்ளது.

அதற்குப் பதிலாக என்ன செய்ய வேண்டும்: முதலில் ஒரு தெளிவான மோனோலிதத்தை உருவாக்குங்கள். தெளிவான தொகுதி எல்லைகளை (module boundaries) வரையறுக்கவும், தரவு அடுக்கை (data layer) ஒருங்கிணைந்ததாக வைத்திருக்கவும், மற்றும் பயன்பாட்டை ஒரு ஒற்றை அலகாகச் சோதனை செய்து வரிசைப்படுத்த (deploy) முடியும் என்பதை உறுதிப்படுத்தவும். ஒரு தொகுதிக்குத் தனித்தனி அளவிடுதல் அல்லது தனிப்பயன் குழு உரிமை தேவைப்படும்போது மட்டுமே அதைத் தனியான சேவையாகப் பிரிக்கவும்.

தொழில்நுட்ப அடுக்கு மற்றும் வணிகத் திறன் ஆகியவற்றின் அடிப்படையில் பிரித்தல்

மற்றொரு அடிக்கடி நிகழும் தவறு என்னவென்றால், தொழில்நுட்பக் கவலைகளின் அடிப்படையில்—UI, வணிகத் தர்க்கம் (business logic), அல்லது தரவு அணுகல் (data access)—சேவைகளை உருவாக்குவதுதான். இது ஒரு ஒற்றை செயல்பாட்டிற்காக ஒரு கோரிக்கை (request) பல சேவைகளின் சங்கிலி வழியாகப் பயணிக்க வேண்டிய கட்டாயத்தை ஏற்படுத்துகிறது, இது பதிலளிக்கும் நேரத்தை (response times) அதிகரிக்கிறது மற்றும் ஒரு பலவீனமான சார்பு வரைபடத்தை (dependency graph) உருவாக்குகிறது.

சிறந்த அணுகுமுறை: "orders", "payments", அல்லது "inventory" போன்ற வணிகத் திறன்களின் அடிப்படையில் சேவைகளை ஒழுங்கமைக்கவும். ஒவ்வொரு திறனும் அதன் சொந்த தரவு மற்றும் சொந்த API-ஐக் கொண்டிருக்கட்டும், இது ஒரு கோரிக்கை அடுக்குகளுக்கு இடையே தாவ வேண்டிய தேவையைக் குறைக்கிறது.

தரவு உரிமை முக்கியமானது

இரண்டு சேவைகள் ஒரே தரவுத்தள அட்டவணையில் (database table) எழுதும்போது, அவை இனி சுதந்திரமானவை அல்ல. ஒரு சேவை மற்றொரு சேவையின் அட்டவணைகளை நேரடியாகக் கேள்வி கேட்கக்கூடாது (query) என்றும், எப்போதும் அந்தச் சேவையின் பொது API வழியாகவே செல்ல வேண்டும் என்றும் வழிகாட்டி வலியுறுத்துகிறது. ஒரு தரவுத்தளத்தைப் பகிர்ந்து கொள்வது சேவைகளை ஒன்றாகப் பிணைக்கிறது, தனிமைப்படுத்தலை (isolation) முறியடிக்கிறது மற்றும் ஸ்கீமா மாற்றங்களை (schema changes) ஒரு ஒருங்கிணைப்புப் பேரிடராக மாற்றுகிறது.

Synchronous HTTP என்பது ஒரு உலகளாவிய தீர்வு அல்ல

ஒவ்வொரு தொடர்பிற்கும் synchronous HTTP-ஐச் சார்ந்திருப்பது, ஒட்டுமொத்த அமைப்பையும் ஒரு மெதுவான சேவையின் பாதிப்பிற்கு உள்ளாக்குகிறது. சேவை A, வாடிக்கையாளருக்குப் பதிலளிப்பதற்கு முன் சேவை B-ன் பதிலுக்காகக் காத்திருந்தால், B-ல் ஏற்படும் எந்தவொரு மந்தநிலையும் A-விற்கும், இறுதியில் பயனருக்கும் பரவும்.

மாற்று முறைகள்: உடனடிப் பதில் தேவையில்லாத பணிகளுக்கு asynchronous messaging-ஐப் பயன்படுத்தவும். Message queues அல்லது background jobs சேவைகளை வேலையை ஒப்படைக்கவும் மற்றும் செயலாக்கத்தைத் தொடரவும் அனுமதிக்கின்றன, இது ஒட்டுமொத்த அமைப்பை அதிக மீள்திறன் (resilient) கொண்டதாக வைத்திருக்கும்.

Eventual consistency-ஐ ஏற்றுக்கொள்வது

பாரம்பரிய உறவுநிலை தரவுத்தளங்கள் (relational databases) உங்களுக்கு ACID பரிவர்த்தனைகளை வழங்குகின்றன—Atomicity, Consistency, Isolation, Durability. சேவை எல்லைகளுக்கு அப்பால், அந்த உத்தரவாதங்கள் மறைந்துவிடுகின்றன. Two-phase commits (பரவலாக்கப்பட்ட பரிவர்த்தனைகளை உள்ளூர் பரிவர்த்தனைகளைப் போலவே செயல்பட வைக்க முயற்சிக்கும் ஒரு புரோட்டோகால்) முறையைத் திணிக்க முயல்வது சிக்கலையும் நிலையற்ற தன்மையையும் ஏற்படுத்துகிறது.

வழிகாட்டி sagas (தீர்வு காணும் தொடர்ச்சியான நடவடிக்கைகள்) அல்லது outbox pattern (ஒரு சேவை நிகழ்வுகளை உள்ளூர் அட்டவணையில் எழுதுகிறது, அவை பின்னர் வெளியிடப்படுகின்றன) ஆகியவற்றைப் பரிந்துரைக்கிறது. இந்த அணுகுமுறைகள் தரவு தற்காலிகமாக ஒத்திசைவில் இல்லாமல் இருக்கலாம் என்பதை அங்கீகரிக்கின்றன மற்றும் அந்த இடைவெளிகளைக் கையாள வணிகத் தர்க்கத்தை வடிவமைக்கின்றன.

முதல் நாளிலிருந்தே தோல்விக்கானத் தயாரிப்புடன் உருவாக்குங்கள்

ஒரு சேவையில் ஏற்படும் பிழை ஒட்டுமொத்த அமைப்பையும் முடக்கிவிடக் கூடாது. முடிவில்லாமல் காத்திருப்பதைத் தவிர்க்க timeouts-ஐயும், தற்காலிகத் தோல்விகளைக் கையாள back-off உடன் கூடிய retries-ஐயும், மற்றும் ஒரு தோல்வியடையும் சேவை மீளப்பெறும் வரை அதற்கான அழைப்புகளை நிறுத்தும் circuit breakers-ஐயும் செயல்படுத்தவும். ஒரு உற்பத்திச் சிக்கல் (production outage) ஏற்பட்ட பிறகு இந்தப் பாதுகாப்பு நடவடிக்கைகளைச் சேர்ப்பது மிகவும் தாமதமானது; அவை ஆரம்ப வடிவமைப்பிலேயே இருக்க வேண்டும்.

Observability என்பது தவிர்க்க முடியாதது

பல கன்டெய்னர்களில் (containers) சிதறிக் கிடக்கும் லாக்ஸைக் (logs) கொண்டு ஒரு பரவலாக்கப்பட்ட அமைப்பை பிழைத்திருத்தம் செய்வது கிட்டத்தட்ட சாத்தியமற்றது. மையப்படுத்தப்பட்ட லாகிங் (Centralized logging), ஒருங்கிணைக்கப்பட்ட அளவீடுகள் (aggregated metrics) மற்றும் கோரிக்கை-நிலை தொடர்பு ஐடிகள் (request-level correlation IDs) ஆகியவை ஒரு பயனர் கோரிக்கை பல சேவைகளின் வழியாக நகரும்போது அதைத் பொறியாளர்கள் கண்டறிய உதவுகின்றன. Tracing கருவிகள் அழைப்பு வரைபடத்தை (call graph) காட்சிப்படுத்துகின்றன, இது செயல்திறன் முட்டுக்கட்டைகளையும் (performance bottlenecks) தோல்விகளையும் எளிதாகக் கண்டறிய உதவுகிறது.

தொடக்கத்தில் உள்கட்டமைப்பை (infrastructure) இலகுவாக வைத்திருங்கள்

Kubernetes சக்திவாய்ந்ததாக இருந்தாலும், அதைக் கற்றுக்கொள்வது கடினம் மற்றும் செயல்பாட்டுச் சுமை (operational overhead) அதிகம். சில சேவைகளுக்கு, Docker Compose முழுத் தொகுப்பையும் (entire stack) உள்ளூரிலேயே (locally) இயக்க போதுமான ஒருங்கிணைப்பை (orchestration) வழங்குகிறது. போக்குவரத்து முறைகள் (traffic patterns), வெளியீட்டுத் தொடர்ச்சி (deployment frequency) அல்லது குழுவின் அளவு தேவைப்படும்போது மட்டுமே சிக்கலான தளத்தைப் பயன்படுத்த வேண்டும்.

சேவைகளை குழுவின் உரிமையுடன் ஒருங்கிணைக்கவும்

சிறிய, தன்னாட்சி பெற்ற குழுக்கள் ஒரு சேவையின் முழு வாழ்க்கைச் சுழற்சியையும் (lifecycle) நிர்வகிக்க ஏதுவாகவே Microservices உருவாக்கப்பட்டன. ஒரு குழுவே பத்து சேவைகளுக்குப் பொறுப்பாக இருந்தால், ஒருங்கிணைப்புச் செலவுகள் (coordination costs) கடுமையாக உயர்ந்து, அதன் மூலம் கிடைக்கும் நன்மைகள் குறையும். பத்து பேருக்கும் குறைவான உறுப்பினர்களைக் கொண்ட குழுக்களுக்கு, ஒரு monolith கட்டமைப்பே சிறந்தது என்றும், அது எளிமையைப் பேணுவதோடு மட்டுமின்றி மட்டுப்படுத்தப்பட்ட மேம்பாட்டையும் (modular development) அனுமதிக்கும் என்றும் இந்த வழிகாட்டி கூறுகிறது.

மாற்று வாதம்: Microservices எப்போது சிறப்பாகச் செயல்படும்

Microservices அடிப்படையில் மோசமானவை என்று இந்த வழிகாட்டி கூறவில்லை. ஒரு பயன்பாட்டின் வெவ்வேறு பகுதிகள் முற்றிலும் மாறுபட்ட அளவீட்டுத் தேவைகளைக் (scaling requirements) கொண்டிருக்கும் சூழலிலோ அல்லது ஒழுங்குமுறை கட்டுப்பாடுகள் (regulatory constraints) கடுமையான தரவுத் தனிமைப்படுத்தலை (data isolation) கோரும் சூழலிலோ, இந்த முறை உண்மையான மதிப்பைக் கொடுக்கும். பல தயாரிப்பு வரிசைகளைக் கொண்ட பெரிய நிறுவனங்கள், தனித்தனி சேவைகள் குழுக்களுக்கு இடையிலான உராய்வைக் குறைப்பதோடு வேகமான வெளியீட்டுச் சுழற்சிகளையும் (release cycles) சாத்தியமாக்குவதை உணர்கின்றன.

இதன் முக்கிய அம்சம் திட்டமிட்ட செயல்பாடு (intentionality) ஆகும். ஒரு குறிப்பிட்ட அம்சத்திற்காக ஒரு வினாடிக்கு மில்லியன் கணக்கான கோரிக்கைகளைக் (requests) கையாள வேண்டியிருப்பதால் அல்லது ஒரு புதிய தயாரிப்பு வரிசையைத் தனி வணிகப் பிரிவு நிர்வகிக்க வேண்டியிருப்பதால் ஒரு குழு Microservices-ஐத் தேர்ந்தெடுத்தால், அந்தச் சிக்கலான கட்டமைப்பு நியாயமானதுதான். வெறும் விளம்பரத்திற்காக (hype) எடுக்கப்படும் முடிவுகளைக் குறித்தே இந்த வழிகாட்டியின் எச்சரிக்கைகள் உள்ளன, உறுதியான தேவைகளுக்காக அல்ல.

அடுத்து கவனிக்க வேண்டியவை

அதிகமான நிறுவனங்கள் cloud-native கட்டமைப்புகளைப் பின்பற்றுவதால், service mesh, distributed tracing மற்றும் automated canary deployments போன்ற கருவிகள் தொடர்ந்து முதிர்ச்சியடைந்து வருகின்றன. இந்த முன்னேற்றங்கள் செயல்பாட்டுத் தடைகளைக் குறைத்தாலும், வழிகாட்டியில் சுட்டிக்காட்டப்பட்டுள்ள அடிப்படை வடிவமைப்புத் தேர்வுகளை (design choices) நீக்கிவிடாது. குழுக்கள் observability platforms மற்றும் async messaging frameworks ஆகியவற்றின் வளர்ச்சியைத் தொடர்ந்து கவனிக்க வேண்டும், அதே சமயம் தாங்கள் உருவாக்கும் ஒவ்வொரு சேவைக்கும் தெளிவான காரணத்துடன் தொடங்குவது அவசியம்.

சுருக்கம்

Microservices என்பது ஒரு இலக்கை அடைய உதவும் ஒரு வழிமுறை மட்டுமே, அதுவே இலக்கல்ல. நன்கு கட்டமைக்கப்பட்ட monolith-உடன் தொடங்குங்கள், ஒவ்வொரு சேவைக்கும் அதன் தரவின் மீதான உண்மையான உரிமையை வழங்குங்கள், முடிந்தவரை asynchronous communication-ஐப் பயன்படுத்துங்கள், மேலும் முதல் வரியிலிருந்தே resilience மற்றும் observability ஆகியவற்றைச் சேர்த்துக் கொள்ளுங்கள். வணிக ரீதியான தேவை (business case) தெளிவாக இருக்கும்போது மட்டுமே, திட்டமிட்டு சேவைகளைப் பிரியுங்கள்; இல்லையெனில், சிக்கலுக்குத் தேவையான எளிமையான கட்டமைப்பையே வைத்திருங்கள்.