الإغلاق الرشيق (Graceful Shutdown): ليه النشر بيقطع طلبات مستخدمينك
لو كل deploy بيرجّع أخطاء 503 لثوانٍ للمستخدمين، المشكلة مش في الكود ولا في السيرفر. المشكلة إن العملية بتموت قبل ما تخلّص الطلبات اللي في إيديها. هنا هتوصل لصفر طلب مقطوع في كل نشر.
المشكلة باختصار
وقت الـ rolling update، Kubernetes بيبعت SIGTERM للحاوية القديمة عشان توقف. المشكلة إن إشارة الإيقاف والتوقّف عن توجيه الترافيك بيحصلوا في نفس اللحظة تقريبًا، مش بالترتيب. النتيجة: العملية تموت وهي لسه بتستقبل طلبات، فالطلبات دي بتترفض بـ 503 أو بـ connection reset.
على خدمة بـ 50 ألف طلب/دقيقة أثناء نشر يومي، ده بيترجم لمئات الأخطاء في كل rollout. رقم تقديري شائع: حوالي 2.1% من الطلبات تفشل خلال ثواني التبديل لو مفيش إغلاق رشيق.
ليه بيحصل ده بالظبط (المفهوم الأساسي)
تخيّل إنك بتقفل محل. الإغلاق المفاجئ معناه إنك تطفّي النور وتقفل الباب على زباين لسه جوّه بينتظروا. الإغلاق الرشيق معناه: تبطّل تدخّل زباين جدد، تخلّص اللي جوّه خدمتهم، وبعد كده تقفل الباب. نفس الفكرة بالظبط في الخدمات.
علميًا: لما البود يتشال، الـ kubelet بيعمل حاجتين على التوازي. بيشيل البود من قائمة الـ Endpoints (عشان الـ Service يبطّل يوجّهله)، وبيبعت SIGTERM للحاوية. إزالة الـ Endpoint بتاخد وقت لتنتشر على كل العقد (kube-proxy، الـ Ingress، موازن الحمل). في الفجوة دي، الترافيك لسه بيوصل لعملية بتموت.
الحل إنك تفصل الخطوتين زمنيًا: أوقف قبول الجديد أولًا، استنى انتشار إزالة التسجيل، وبعدها اخرج.
الحل: الإغلاق الرشيق خطوة بخطوة
- استقبل SIGTERM بدل ما تتجاهله.
- خلّي فحص الجاهزية (readiness) يفشل فورًا عشان تخرج من مجموعة موازن الحمل.
- استنى فترة قصيرة لحد ما إزالة التسجيل تنتشر (10–15 ثانية عادة).
- اقفل السيرفر: بطّل قبول اتصالات جديدة وخلّص الجارية.
- اخرج بـ
exit 0قبل ما ينتهي وقت المهلة.
الجزء البرمجي في Node.js:
const server = app.listen(3000);
let shuttingDown = false;
// فحص الجاهزية: يرجّع 503 بمجرد بدء الإغلاق
app.get('/healthz/ready', (req, res) =>
res.sendStatus(shuttingDown ? 503 : 200));
process.on('SIGTERM', () => {
shuttingDown = true; // 1) اخرج من مجموعة موازن الحمل
setTimeout(() => { // 2) استنى انتشار إزالة التسجيل
server.close(() => process.exit(0)); // 3) خلّص الطلبات الجارية ثم اخرج
}, 15000);
});