Get a quote

تشغيل المهام المجدولة والدُفعية على AWS ECS مع Go: ما يعمل في الإنتاج

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

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

الأساليب الثلاثة ومتى يفشل كل منها

هناك ثلاثة أساليب شائعة لتشغيل العمل المجدول في خادم SaaS:

Cron داخل العملية باستخدام مكتبة Go. حزمة مثل robfig/cron تشغل goroutine بجدول زمني داخل عملية التطبيق الرئيسي. سهل التطبيق، لا تكلفة بنية تحتية. يفشل بمجرد أن تحتاج تشغيل أكثر من نسخة واحدة من خدمتك، لأن جميع النسخ ستشغل المهمة في آن واحد.

AWS Lambda مع EventBridge. EventBridge يُشغِّل دالة Lambda بتعبير cron. حمل تشغيلي منخفض، يتوسع إلى صفر عند عدم التشغيل. يفشل في المهام التي تعمل أكثر من 15 دقيقة أو تحتاج أكثر من 3GB ذاكرة.

ECS Scheduled Tasks. EventBridge يُشغِّل تعريف مهمة ECS كمهمة ECS مستقلة. المهمة تعمل حتى الاكتمال ثم تنتهي. لا قيود Lambda، لا قيود cold start. العيب الرئيسي هو أن إطلاق مهمة ECS يضيف 20 إلى 40 ثانية من وقت البدء.

لخوادم Go التي تعمل بالفعل على ECS، المهام المجدولة على ECS هي الخيار الصحيح الافتراضي لمعظم العمل المجدول.

إعداد ECS Scheduled Task لخادم Go

النمط هو تطبيق جميع المهام المجدولة كأوامر فرعية في نفس الثنائي:

func main() {
    if len(os.Args) < 2 {
        runHTTPServer()
        return
    }
    switch os.Args[1] {
    case "billing-run":
        runBillingJob()
    case "report-aggregation":
        runReportAggregation()
    }
}

تعريف مهمة ECS للمهمة المجدولة يستخدم نفس صورة Docker مع تجاوز الأمر. قاعدة EventBridge تحدد تعبير cron والهدف كمجموعة ECS وتعريف المهمة.

التعامل مع الفشل وإعادة المحاولة

المهام المجدولة على ECS لا تعيد المحاولة تلقائياً عند خروج المهمة برمز خطأ. يجب التعامل مع اكتشاف الفشل والإشعار بشكل صريح.

النمط الذي يعمل: لف منطق المهمة الرئيسي في دالة مؤجلة تتحقق من الأعطال وترسل تنبيهاً إذا خرجت المهمة بخطأ. للمهام التي يجب أن تكتمل (تشغيل الفواتير)، نفِّذ الـ idempotency في منطق المهمة نفسه. المهمة يجب أن تكون آمنة للتشغيل مرة أخرى إذا أطلقها EventBridge مرتين في نفس اليوم.

اعتبارات التكلفة على Fargate

مهمة فوترة ليلية تعمل 3 دقائق على 0.5 vCPU و1GB ذاكرة تكلف تقريباً $0.002 إلى $0.003 لكل تشغيل. للمهام اليومية، هذا أقل من $1 شهرياً.

قفل موزع للمهام داخل العملية

نمط القفل الاستشاري لـ PostgreSQL يعمل جيداً في Go:

func tryAcquireAdvisoryLock(db *pgxpool.Pool, lockID int64) (bool, error) {
    var acquired bool
    err := db.QueryRow(ctx,
        "SELECT pg_try_advisory_lock($1)", lockID).Scan(&acquired)
    return acquired, err
}

دروس من الإنتاج

استخدم ECS Scheduled Tasks لمعظم مهام خادم Go. وقت بدء التشغيل مقبول للمهام التي تعمل كل ساعة أو أقل تكراراً.

طبِّق الـ idempotency في كل مهمة مجدولة. EventBridge يضمن التسليم مرة على الأقل. مهمتك ستعمل مرتين أحياناً. صمِّم لذلك.

احفظ حالة التنفيذ في PostgreSQL، وليس في الذاكرة. إعادة تشغيل الحاويات تحدث.

أرسل مقياس heartbeat من المهام طويلة الأمد. مهمة تعالج 100,000 سجل بصمت وتنتهي صعبة التصحيح عند حدوث خطأ.

هل تحتاج مساعدة في بناء بنية المهام المجدولة؟

Voxire تبني وتدير خوادم Go على AWS ECS لمنتجات SaaS في لبنان ومنطقة الشرق الأوسط. إذا كنت تصمم بنية للمهام المجدولة أو تواجه مشاكل موثوقية في نهجك الحالي، يمكننا المساعدة.

https://voxire.com/get-a-quote/

العودة إلى المدونة
Chat on WhatsApp