إستراتيجيات النشر بدون توقف: حافظ على تشغيل تطبيقك أثناء التحديثات

قم بتنفيذ عمليات النشر بدون توقف باستخدام إستراتيجيات اللون الأزرق والأخضر والمتداول والكناري. يغطي عمليات ترحيل قاعدة البيانات والفحوصات الصحية وأنماط التراجع التلقائي.

E
ECOSIRE Research and Development Team
|16 مارس 20267 دقائق قراءة1.4k كلمات|

إستراتيجيات النشر بدون توقف: حافظ على تشغيل تطبيقك أثناء التحديثات

تكلف فترات التوقف المخطط لها الشركات ما متوسطه 5,600 دولار أمريكي للدقيقة. ومع ذلك، فإن 43% من الشركات لا تزال تأخذ تطبيقاتها دون اتصال بالإنترنت أثناء عمليات النشر. إن النشر بدون توقف ليس ترفا --- بل هو توقع. يقوم العملاء ومحركات البحث وشركاء التكامل بمعاقبة التطبيقات التي تصبح غير متصلة بالإنترنت، حتى لفترة وجيزة.

يغطي هذا الدليل استراتيجيات النشر الأساسية الثلاثة لعدم التوقف عن العمل، وتقنيات ترحيل قاعدة البيانات التي تحافظ على وقت التشغيل، وآليات التراجع التلقائية.

الوجبات الرئيسية

  • يعد النشر باللونين الأزرق والأخضر هو الإستراتيجية الأكثر أمانًا: التراجع الفوري عن طريق تحويل حركة المرور مرة أخرى إلى الإصدار السابق
  • يجب أن تكون عمليات ترحيل قاعدة البيانات متوافقة مع الإصدارات السابقة --- يجب أن يعمل إصدار التطبيق القديم مع المخطط الجديد
  • تمنع عمليات التحقق من السلامة وتحقيقات الاستعداد توجيه حركة المرور إلى الكبسولات غير الجاهزة للخدمة
  • يؤدي التراجع التلقائي استنادًا إلى مراقبة معدل الأخطاء إلى تقليل متوسط وقت الاسترداد إلى أقل من دقيقتين

مقارنة الإستراتيجية

استراتيجيةالتعقيدسرعة التراجعتكلفة البنية التحتيةالأفضل لـ
الأزرق والأخضرمنخفضفورية (ثواني)2x أثناء النشرالتطبيقات الهامة، عمليات النشر النادرة
التحديث المتداولمتوسطةدقائق1.25x أثناء النشرKubernetes، عمليات النشر المتكررة
كناريعاليةسريع (ثواني)1.05x أثناء النشرحركة مرور عالية وحساسة للمخاطر
ميزة الأعلاممتوسطةفوري1xطرح ميزة تدريجية

النشر الأزرق والأخضر

###الهندسة المعمارية

Load Balancer
    |
    |--- [ACTIVE] Blue environment (v2.0.0) <-- receives 100% traffic
    |
    |--- [IDLE] Green environment (v2.1.0) <-- deployed, tested, waiting

عند النشر:

  1. قم بنشر الإصدار 2.1.0 في البيئة الخاملة (الخضراء).
  2. قم بإجراء اختبارات الدخان مقابل اللون الأخضر
  3. قم بتبديل موازن التحميل إلى اللون الأخضر
  4. يصبح اللون الأزرق خاملاً (متاح للتراجع الفوري)

التنفيذ باستخدام Nginx

# /etc/nginx/conf.d/app.conf
upstream blue {
    server 10.0.1.10:3000;
    server 10.0.1.11:3000;
}

upstream green {
    server 10.0.2.10:3000;
    server 10.0.2.11:3000;
}

# Active environment - change this during deployment
map $host $active_upstream {
    default blue;  # Change to 'green' to switch
}

server {
    listen 443 ssl;
    server_name app.example.com;

    location / {
        proxy_pass http://$active_upstream;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}

البرنامج النصي للنشر

#!/bin/bash
set -e

CURRENT=$(cat /etc/nginx/active-env)  # "blue" or "green"
TARGET=$( [ "$CURRENT" = "blue" ] && echo "green" || echo "blue" )

echo "Current: $CURRENT, deploying to: $TARGET"

# Deploy to inactive environment
ssh "deploy@$TARGET-1" "cd /opt/app && git pull && pnpm install --frozen-lockfile && pnpm build && pm2 restart all"
ssh "deploy@$TARGET-2" "cd /opt/app && git pull && pnpm install --frozen-lockfile && pnpm build && pm2 restart all"

# Wait for health checks
for i in 1 2; do
  echo "Checking $TARGET-$i health..."
  for attempt in $(seq 1 30); do
    if curl -sf "http://$TARGET-$i:3000/health" > /dev/null; then
      echo "$TARGET-$i is healthy"
      break
    fi
    sleep 2
  done
done

# Run smoke tests
pnpm test:smoke --base-url "http://$TARGET-1:3000"

# Switch traffic
sed -i "s/default $CURRENT/default $TARGET/" /etc/nginx/conf.d/app.conf
nginx -s reload
echo "$TARGET" > /etc/nginx/active-env

echo "Traffic switched to $TARGET. Rollback: change active-env back to $CURRENT"

التحديث المتداول

تحل التحديثات المتوالية محل المثيلات بشكل متزايد، مما يضمن توفر بعض السعة دائمًا.

التحديث المستمر لـ Kubernetes

apiVersion: apps/v1
kind: Deployment
metadata:
  name: api
spec:
  replicas: 5
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1        # Create 1 extra pod during update
      maxUnavailable: 0   # Never reduce below desired replicas
  template:
    spec:
      containers:
        - name: api
          image: registry.example.com/api:v2.1.0
          readinessProbe:
            httpGet:
              path: /health
              port: 3001
            initialDelaySeconds: 5
            periodSeconds: 5
          livenessProbe:
            httpGet:
              path: /health
              port: 3001
            initialDelaySeconds: 15
            periodSeconds: 10

عملية التحديث المتداول مع maxSurge: 1 وmaxUnavailable: 0:

  1. قم بإنشاء حاوية واحدة جديدة باستخدام الإصدار 2.1.0 (إجمالي 6 وحدات: 5 قديمة + 1 جديدة)
  2. انتظر مرور مسبار جاهزية الكبسولة الجديدة
  3. إنهاء 1 جراب قديم (5 كبسولات: 4 قديمة + 1 جديدة)
  4. إنشاء جراب جديد آخر (6 جرابات: 4 قديمة + 2 جديدة)
  5. كرر ذلك حتى تصبح جميع القرون v2.1.0

نشر الكناري

تقسيم حركة المرور

# Istio VirtualService for canary routing
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: api-canary
spec:
  hosts:
    - api.example.com
  http:
    - route:
        - destination:
            host: api-stable
            port:
              number: 3001
          weight: 95
        - destination:
            host: api-canary
            port:
              number: 3001
          weight: 5

طرح الكناري التقدمي

المرحلةكناري ترافيكالمدةمعايير النجاح
11%10 دقائقمعدل الخطأ <0.1%، زمن الوصول <500 مللي ثانية
25%30 دقيقةمعدل الخطأ <0.1%، زمن الوصول <500 مللي ثانية
325%1 ساعةمعدل الخطأ <0.5%، زمن الوصول <1s
450%ساعتينمعدل الخطأ <0.5%، زمن الوصول <1s
5100%الطرح الكاملثابت لمدة 24 ساعة

عمليات ترحيل قاعدة البيانات دون توقف

التحدي الأكبر في النشر بدون توقف هو تغييرات مخطط قاعدة البيانات. يجب أن يعمل إصدار التطبيق القديم مع المخطط الجديد، والعكس صحيح.

نمط العقد الموسع

المرحلة الأولى: التوسيع (تغيير مخطط النشر)

-- Add new column (nullable, no default)
ALTER TABLE orders ADD COLUMN shipping_method VARCHAR(50);

يتجاهل رمز التطبيق القديم العمود الجديد. يكتب رمز التطبيق الجديد إلى كل من الأعمدة القديمة والجديدة.

المرحلة الثانية: ترحيل البيانات

-- Backfill existing data
UPDATE orders SET shipping_method = 'standard' WHERE shipping_method IS NULL;

المرحلة 3: العقد (نشر التعليمات البرمجية التي تستخدم عمودًا جديدًا حصريًا)

بعد كل مثيلات التطبيق، استخدم العمود الجديد:

-- Make column required
ALTER TABLE orders ALTER COLUMN shipping_method SET NOT NULL;
ALTER TABLE orders ALTER COLUMN shipping_method SET DEFAULT 'standard';

أنماط الهجرة الخطرة

نمطخطرالبديل الآمن
إعادة تسمية العموديكسر الكود القديمإضافة عمود جديد، وترحيله، وإسقاط العمود القديم
إسقاط العموديكسر الكود القديمتوقف عن الاستخدام، ثم قم بإسقاط الإصدار التالي
أضف عمودًا غير فارغأقفال الجدولإضافة لاغية، ردم، تغيير إلى NOT NULL
تغيير نوع العمودتأمين الجدول، فواصل الاستعلاماتإضافة عمود جديد بنوع جديد، وترحيل
إضافة فهرس فريدأقفال الجدول على طاولات كبيرةCREATE INDEX CONCURRENTLY

التراجع الآلي

التراجع على أساس معدل الخطأ

#!/bin/bash
# post-deploy-monitor.sh

DEPLOY_TIME=$(date +%s)
MONITOR_DURATION=300  # 5 minutes
ERROR_THRESHOLD=0.02  # 2%

while [ $(($(date +%s) - DEPLOY_TIME)) -lt $MONITOR_DURATION ]; do
  ERROR_RATE=$(curl -s "http://prometheus:9090/api/v1/query?query=rate(http_requests_total{status=~'5..'}[2m])/rate(http_requests_total[2m])" | jq -r '.data.result[0].value[1]')

  if (( $(echo "$ERROR_RATE > $ERROR_THRESHOLD" | bc -l) )); then
    echo "ERROR: Rate $ERROR_RATE exceeds threshold $ERROR_THRESHOLD"
    echo "Initiating rollback..."
    kubectl rollout undo deployment/api
    exit 1
  fi

  sleep 15
done

echo "Deployment healthy for $MONITOR_DURATION seconds"

الأسئلة المتداولة

ما هي الإستراتيجية التي يجب أن نبدأ بها؟

ابدأ بالنشر باللون الأزرق والأخضر. إنه الأسهل في التنفيذ، ويوفر التراجع الفوري، ويعمل مع أي بنية تطبيق. تعد التحديثات المتوالية أفضل لبيئات Kubernetes التي تحتوي على العديد من النسخ المتماثلة. عمليات نشر Canary مخصصة للتطبيقات ذات حركة المرور العالية حيث تريد التحقق من صحة التغييرات من خلال حركة مرور حقيقية قبل الطرح الكامل.

كيف نتعامل مع مهام الخلفية طويلة الأمد أثناء النشر؟

استخدام الاغلاق رشيقة. عندما تتلقى الحجرة إشارة إنهاء، توقف عن قبول المهام الجديدة، وقم بإنهاء المهام قيد التقدم (مع انتهاء المهلة)، ثم قم بإيقاف التشغيل. في Kubernetes، قم بتكوين terminationGracePeriodSeconds لإتاحة الوقت الكافي لإكمال المهام. بالنسبة للوظائف التي تستغرق وقتًا أطول من فترة السماح، استخدم قائمة انتظار المهام (Redis، RabbitMQ) التي تعيد محاولة المهام الفاشلة للعمال الباقين على قيد الحياة.

ماذا عن اتصالات WebSocket أثناء النشر؟

اتصالات WebSocket طويلة الأمد ويجب التعامل معها بعناية. أثناء التحديث المستمر، تظل الاتصالات الموجودة على الكبسولة القديمة نشطة حتى تنتهي الكبسولة. يجب على العملاء تنفيذ منطق إعادة الاتصال التلقائي. بالنسبة لعمليات النشر ذات اللون الأزرق والأخضر، قم بتبديل الاتصالات الجديدة إلى البيئة الجديدة مع السماح للاتصالات الموجودة باستنزاف البيئة القديمة مع انتهاء المهلة.

كيف يمكننا اختبار عمليات النشر بدون توقف؟

قم بإجراء اختبار التحميل أثناء النشر. استخدم k6 أو أداة مشابهة لإنشاء حركة مرور مستمرة، ثم قم بتشغيل النشر. تحقق من وجود أي أخطاء، أو زيادة في زمن الوصول، أو انقطاع الاتصالات أثناء التمرير. راجع دليل اختبار التحميل للحصول على تفاصيل التنفيذ.


ما يأتي بعد ذلك

يعد النشر بدون توقف شرطًا أساسيًا للإصدارات المتكررة والواثقة. ادمجها مع أتمتة CI/CD لمسار النشر الكامل والمراقبة للتحقق بعد النشر.

اتصل بـ ECOSIRE للحصول على استشارات حول إستراتيجية النشر، أو استكشف دليل DevOps للحصول على خريطة طريق البنية التحتية الكاملة.


تم النشر بواسطة ECOSIRE - لمساعدة الشركات على الانتشار دون انقطاع.

E

بقلم

ECOSIRE Research and Development Team

بناء منتجات رقمية بمستوى المؤسسات في ECOSIRE. مشاركة رؤى حول تكاملات Odoo وأتمتة التجارة الإلكترونية وحلول الأعمال المدعومة بالذكاء الاصطناعي.

الدردشة على الواتساب