Go Academy · درس

التراجع وإعادة المحاولة

أعد المحاولة مع تراجع تدريجي

الدرس 4 من 413 خطوة

التراجع وإعادة المحاولة درس مجاني في Go Academy على CoddyKit. هذا هو الدرس 4 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في Go Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة Go Academy 4 دروس في المجموع.

لماذا نعيد المحاولة

غالبًا ما تنجح حالات الفشل المؤقتة، وانتهاء المهلات، وانقطاع الاتصالات، واستجابات 503 القصيرة عند المحاولة مرة ثانية. يحوّل إعادة المحاولة العملية غير المستقرة إلى عملية موثوقة من دون إزعاج المستدعي.

إعادة المحاولة الساذجة خطرة

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

التراجع الأسي

يضاعف التراجع الأسي مدة الانتظار بعد كل فشل: 100ms، ثم 200ms، ثم 400ms، ثم 800ms. ويمنح ذلك الخدمة التابعة فرصة للتعافي.

delay := 100 * time.Millisecond
for attempt := 0; attempt < 5; attempt++ {
    // try, on failure:
    time.Sleep(delay)
    delay *= 2
}

إضافة Jitter

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

jitter := time.Duration(rand.Int63n(int64(delay) / 2))
time.Sleep(delay + jitter)

وضع حد للتأخير

ينمو التراجع الأسي بسرعة كبيرة. ضعوا حدًا أقصى للتأخير حتى لا تنتظروا دقائق بين المحاولات.

if delay > 2*time.Second {
    delay = 2 * time.Second
}

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

حدّدوا دائمًا عدد المحاولات. بعد بلوغ الحد، أعيدوا الخطأ الأخير ليقرر المستدعي ما يفعله بدلًا من إعادة المحاولة إلى ما لا نهاية.

أعيدوا محاولة العمليات القابلة للتكرار فقط

تكون إعادة المحاولة آمنة فقط عندما يمكن تنفيذ العملية مرتين من دون ضرر. يُعد GET قابلًا للتكرار؛ أما POST غير القابل للتكرار الذي يخصم مبلغًا من بطاقة فلا ينبغي إعادة محاولته عشوائيًا. استخدموا مفاتيح idempotency عند الحاجة.

إعادة محاولة كاملة مع التراجع

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

package main

import (
    "errors"
    "fmt"
    "time"
)

func flaky(attempt int) error {
    if attempt < 2 {
        return errors.New("temporary failure")
    }
    return nil
}

func main() {
    delay := 50 * time.Millisecond
    var err error
    for attempt := 0; attempt < 5; attempt++ {
        err = flaky(attempt)
        if err == nil {
            fmt.Println("succeeded on attempt", attempt)
            return
        }
        fmt.Printf("attempt %d failed, waiting %v\n", attempt, delay)
        time.Sleep(delay)
        delay *= 2
    }
    fmt.Println("gave up:", err)
}

احترام context

مرّروا context إلى حلقة إعادة المحاولة، واستخدموا select على ctx.Done() أثناء النوم. يتيح ذلك للمستدعي الذي أُلغي أو انتهت مهلته إيقاف إعادة المحاولة فورًا.

select {
case <-ctx.Done():
    return ctx.Err()
case <-time.After(delay):
}

تمييز الأخطاء

ليست كل الأخطاء قابلة لإعادة المحاولة. سيفشل الخطأ 400 Bad Request إلى الأبد. افحصوا الخطأ أو رمز الحالة، وأعيدوا المحاولة فقط عند الفئات المؤقتة مثل انتهاء المهلات و429 و5xx.

قواطع الدائرة

عندما تستمر حالات الفشل، يوقف قاطع الدائرة إرسال الطلبات لفترة تهدئة بدلًا من إعادة محاولة كل استدعاء. وهو يكمل التراجع بحماية التبعية المتوقفة بوضوح.

تحقق سريع

اختبروا معرفتكم بالتراجع.

مراجعة

لقد تعلّمتم التراجع وإعادة المحاولة:

  • يضاعف التراجع الأسي التأخير مع كل فشل
  • تمنع Jitter عواصف إعادة المحاولة المتزامنة
  • ضعوا حدًا للتأخير وحدّدوا عدد المحاولات
  • أعيدوا محاولة الأخطاء القابلة للتكرار أو القابلة لإعادة المحاولة فقط
  • احترموا context لدعم الإلغاء
البدء مجانًا

تعلم Go مع معلم ذكاء اصطناعي — مجانًا

اكتب وقم بتشغيل أكوادك الفعلية في المتصفح، واحصل على مساعدة فورية من معلم ذكاء اصطناعي متاح 24/7، واستمر من حيث توقفت على الويب أو في التطبيق.

الدورات
51
الدروس
203

الأسئلة الشائعة

هل درس «التراجع وإعادة المحاولة» مجاني؟

نعم — نص درس «التراجع وإعادة المحاولة» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة Go Academy، انتقل إلى CoddyKit PRO. تتضمن دورة Go Academy 4 دروس في المجموع.

ماذا ستتعلم في «التراجع وإعادة المحاولة»؟

أعد المحاولة مع تراجع تدريجي تتمرن على Go Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.

هل أحتاج إلى خبرة سابقة لأبدأ Go Academy؟

لا تُشترط خبرة سابقة. Go Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 4 من أصل 4.

كم من الوقت يستغرق درس «التراجع وإعادة المحاولة»؟

معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.

هل يمكنني كتابة وتشغيل أكواد في درس Go Academy هذا؟

نعم. كل درس في Go Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.

جميع الدروس في هذه الدورة

  1. مفهوم دلو الرموز
  2. golang.org/x/time/rate
  3. خنق Goroutines
  4. التراجع وإعادة المحاولة
← العودة إلى Go Academy