نشر الكناري (Canary Deployments) بلغة C#: إصدار آمن بدون توقف

مدرب بايثون أونلاين للمبتدئين

تعلم Python بسهولة دون إرهاق نظري. حل مهام عملية مع التحقق التلقائي واكتب الكود مباشرة في المتصفح.

ابدأ الدورة

ما هو نشر الكناري (Canary Deployments) ولماذا سينقذ بيئة الإنتاج الخاصة بك؟

\n

هل سبق لك أن قمت بنشر تحديث في منتصف الليل، متوسلاً ألا يحدث أي عطل؟ مألوف. وماذا لو أخبرتك أنه يمكنك اختبار كود جديد على مستخدمين حقيقيين، ولكن بطريقة لا يتضرر فيها أحد؟ الحديث عن نشر الكناري (canary deployments) — استراتيجية نشر حيث تحصل النسخة الجديدة من التطبيق أولاً على جزء صغير فقط من حركة المرور. إذا كان كل شيء على ما يرام — تزداد حركة المرور. إذا لم يكن كذلك — التراجع في ثوانٍ.

\n

في عالم .NET و C#، هذا مهم بشكل خاص: الخدمات المصغرة، الأحمال العالية، متطلبات الاستقرار. سنكتب الكود، ونضبط نشر الكناري (canary deployment)، ونحلل أمثلة حقيقية. هيا بنا!

\n\n

لماذا الكناري (Canary) ليس مجرد كلمة موضة؟

\n

النشر التقليدي الأزرق-الأخضر (blue-green deployment) يحول كل حركة المرور مرة واحدة. التحديث المتداول (Rolling update) — تدريجياً، ولكن بدون تحكم دقيق. الكناري (Canary) يمنحك قوة خارقة: تقوم بإصدار النسخة الجديدة، ولكنك توجه إليها، على سبيل المثال، 5% من المستخدمين. أما الـ 95% المتبقية فتعمل على النسخة القديمة المستقرة. تراقب المقاييس، الأخطاء، التأخيرات. إذا كان كل شيء على ما يرام — تزيد النسبة تدريجياً إلى 100. إذا لم يكن كذلك — تقوم ببساطة بإيقاف تشغيل الكناري.

\n

لمطور C#، هذا مريح بشكل خاص: يمكننا استخدام أدوات ASP.NET Core المضمنة، Kubernetes، أعلام الميزات (Feature Flags) أو حتى موازن تحميل بسيط. الشيء الرئيسي هو البنية الصحيحة.

\n\n

بنية نشر الكناري (Canary Deployment) لتطبيق .NET

\n

لنتخيل أن لدينا واجهة برمجة تطبيقات ويب (Web API) على ASP.NET Core تقوم بمعالجة الطلبات. نريد إصدار منطق جديد لحساب الخصومات. بدلاً من تحديث جميع الحاويات (pods) مرة واحدة، نقوم بما يلي:

\n
    \n
  • تشغيل نسختين من الخدمة: مستقرة (v1) وكناري (v2).
  • \n
  • ضبط موازن التحميل (مثل Nginx أو Kubernetes Service) بحيث تذهب 95% من حركة المرور إلى v1، و 5% إلى v2.
  • \n
  • إضافة رأس HTTP X-Canary: true في استجابات نسخة الكناري لتحديد الهوية.
  • \n
  • جمع المقاييس (كود 200/500، زمن الاستجابة، عدد الطلبات).
  • \n
  • إذا لم تكن الأخطاء خلال 30 دقيقة أكثر من v1، نزيد وزن الكناري إلى 50%، ثم إلى 100%.
  • \n
\n\n

التنفيذ بلغة C#: من البسيط إلى المعقد

\n\n

الطريقة 1: الكناري عبر رؤوس HTTP وموازن التحميل

\n

أبسط طريقة هي استخدام طبقة وسيطة (middleware) في ASP.NET Core تقوم بتمييز الطلبات. لكن أولاً، دعنا نرى كيف يبدو الكود الذي يميز نسخة الكناري.

\n
// Startup.cs أو Program.cs\npublic class CanaryMiddleware\n{\n    private readonly RequestDelegate _next;\n    private readonly string _version;\n\n    public CanaryMiddleware(RequestDelegate next, string version)\n    {\n        _next = next;\n        _version = version;\n    }\n\n    public async Task InvokeAsync(HttpContext context)\n    {\n        // إضافة رأس لتحديد هوية النسخة\n        context.Response.Headers.Add("X-App-Version", _version);\n        await _next(context);\n    }\n}\n\n// التسجيل\napp.UseMiddleware<CanaryMiddleware>("v2-canary");\n
\n

الآن على مستوى موازن التحميل (مثل Nginx)، نقرر أي نسبة من حركة المرور نرسلها إلى حاوية الكناري:

\n
upstream backend {\n    server app-stable:5000 weight=95;\n    server app-canary:5000 weight=5;\n}\n
\n

الإيجابيات: البساطة. السلبيات: لا يوجد تحكم برمجي، صعوبة في إجراء اختبار A/B حسب المستخدمين.

\n\n

الطريقة 2: أعلام الميزات (Feature Flags) في C#

\n

نهج أكثر مرونة هو استخدام أعلام الميزات (feature flags). تقوم بتشغيل المنطق الجديد فقط لمجموعة معينة من المستخدمين. في ASP.NET Core، هناك دعم مدمج:

\n
// قم بتثبيت الحزمة Microsoft.FeatureManagement.AspNetCore\n// أضف في Program.cs\nbuilder.Services.AddFeatureManagement();\n\n// حدد العلم في appsettings.json\n{\n  "FeatureManagement": {\n    "NewDiscountLogic": false\n  }\n}\n\n// استخدمه في المتحكم (controller)\n[ApiController]\n[Route                

المدونات

توصيات الكتب