सेवा को कैसे अपडेट करें, बिना उपयोगकर्ताओं को जगाए?
\n\nकल्पना करें: शुक्रवार, शाम, आपने जल्दी से प्रोड पर बगफिक्स डालने का फैसला किया। आप deploy दबाते हैं — और आपका मैसेंजर, ऑनलाइन सिनेमा या CRM 30 सेकंड के लिए डाउन हो जाता है। हजारों उपयोगकर्ता उस समय 502 Bad Gateway देखते हैं। और अगर यह भुगतान गेटवे है? नुकसान गिनें।
\n\nZero-downtime डिप्लॉय (शून्य डाउनटाइम के साथ तैनाती) आधुनिक TypeScript सेवाओं के लिए विलासिता नहीं, बल्कि एक मानक है। इस लेख में हम वास्तविक तकनीकों पर चर्चा करेंगे जो प्रोडक्शन में उपयोग की जाती हैं: graceful shutdown से लेकर ब्लू-ग्रीन डिप्लॉय और रोलिंग अपडेट तक। आपको TypeScript में उपयोग के लिए तैयार पैटर्न मिलेंगे।
\n\nसामान्य TypeScript एप्लिकेशन डिप्लॉय खतरनाक क्यों है?
\n\nजब आप npm run build && node dist/index.js चलाते हैं, तो कई समस्याएं होती हैं:
- \n
- कनेक्शन टूटना — पुरानी प्रक्रिया मार दी जाती है जबकि नए अनुरोध अभी भी आ रहे हैं। \n
- मेमोरी में डेटा का नुकसान — सहेजे न गए सत्र, कैश, कतारें। \n
- गंदा स्टार्ट — नई प्रक्रिया वार्म अप नहीं हुई है, लेकिन पहले से ही ट्रैफिक प्राप्त कर रही है। \n
TypeScript (Node.js) में, एसिंक्रोनसिटी के कारण यह और बढ़ जाता है: आप नहीं जानते कि कौन से प्रॉमिस अभी भी निष्पादित हो रहे हैं। लेकिन समाधान मौजूद है।
\n\nतकनीक #1: Graceful Shutdown (विनम्र समाप्ति)
\n\nZero-downtime का आधार — OS सिग्नल का सही हैंडलिंग। जब ऑर्केस्ट्रेटर (Kubernetes, PM2) आपकी सेवा को रोकने का निर्णय लेता है, तो वह SIGTERM भेजता है। आपके कोड को नए अनुरोध स्वीकार करना बंद करना चाहिए, वर्तमान अनुरोधों के पूरा होने की प्रतीक्षा करनी चाहिए, और उसके बाद ही समाप्त होना चाहिए।
Express के साथ TypeScript में कार्यान्वयन
\n\nimport express, { Request, Response } from 'express';\nimport http from 'http';\n\nconst app = express();\nlet server: http.Server;\n\napp.get('/health', (req: Request, res: Response) => {\n res.status(200).json({ status: 'ok' });\n});\n\n// Docker/K8s से सिग्नल\nprocess.on('SIGTERM', async () => {\n console.log('SIGTERM प्राप्त हुआ, graceful shutdown शुरू...');\n \n // 1. नए कनेक्शन सुनना बंद करें\n server.close(() => {\n console.log('HTTP सर्वर बंद हुआ');\n // 2. DB, Redis आदि से कनेक्शन बंद करें\n // await db.disconnect(); \n process.exit(0);\n });\n\n // 3. वर्तमान अनुरोधों को समय दें (30 सेकंड टाइमआउट)\n setTimeout(() => {\n console.error('टाइमआउट द्वारा जबरन समाप्ति');\n process.exit(1);\n }, 30000);\n});\n\nconst PORT = process.env.PORT || 3000;\nserver = app.listen(PORT, () => {\n console.log(`सेवा पोर्ट ${PORT} पर शुरू हुई`);\n});\n\n\nमहत्वपूर्ण: TypeScript में, http मॉड्यूल से http.Server का उपयोग करें, Express प्रकार का नहीं। server.close() विधि keep-alive कनेक्शन को सही ढंग से संभालती है।
तकनीक #2: Rolling Update (क्रमिक अद्यतन)
\n\nयदि आपके पास सेवा की कई प्रतिकृतियां हैं (3-5 इंस्टेंस चल रहे हैं), तो रोलिंग अपडेट उन्हें एक-एक करके अपडेट करता है। जब एक पुनरारंभ हो रहा होता है, तो अन्य ट्रैफिक स्वीकार करते हैं।
\n\nKubernetes Deployment के लिए उदाहरण
\n\n# deployment.yaml\napiVersion: apps/v1\nkind: Deployment\nmetadata:\n name: my-typescript-service\nspec:\n replicas: 3\n strategy:\n type: RollingUpdate\n rollingUpdate:\n maxUnavailable: 1 # कितने पॉड अनुपलब्ध हो सकते हैं\n maxSurge: 1 # योजना से अधिक कितने नए पॉड बनाए जा सकते हैं\n template:\n spec:\n containers:\n - name: app\n image: myregistry/service:v2\n ports:\n - containerPort: 3000\n livenessProbe:\n httpGet:\n path: /health\n port: 3000\n initialDelaySeconds: 5\n periodSeconds: 10\n readinessProbe:\n httpGet:\n path: /ready\n port: 3000\n initialDelaySeconds: 3\n periodSeconds: 5\n\n\nअपने TypeScript एप्लिकेशन में /ready एंडपॉइंट जोड़ें, जो केवल तभी 200 लौटाता है जब सेवा तैयार हो।