N8n Queue Mode: كيفية تحديد آخر عقدة تم تنفيذها بنجاح عند قطع اتصال Redis؟

أنا أقوم بتشغيل n8n في Queue Mode (Redis + Worker + Database) وواجهت مشكلة حيث لا يمكنني تحديد العقدة (Node) المنفذة الأخيرة بشكل موثوق عندما يصبح Redis غير متاح.

وصف المشكلة/الخطأ/السؤال

أثناء تنفيذ سير العمل، إذا تم قطع الاتصال بـ Redis أو تم إعادة تشغيله، يحدث السلوك التالي:
يبقى التنفيذ في حالة قيد التشغيل في قاعدة البيانات
لا يكون هناك رؤية لتقدم التنفيذ في واجهة المستخدم
بعد استرجاع Redis، لا يستأنف التنفيذ أو تحديث التقدم
بعد إعادة تشغيل مثيل n8n الرئيسي، يتم تحديث حالة التنفيذ إلى متعطل (crashed)
ومع ذلك، واجهة المستخدم وبيانات التنفيذ لا تظهر بوضوح العقدة التي توقف سير العمل عندها

معلومات إعداد n8n الخاص بك

  • إصدار n8n: 2.11.4
  • قاعدة البيانات (الافتراضية: SQLite): pgsql
  • إعداد EXECUTIONS_PROCESS في n8n (الافتراضي: own, main):
  • تشغيل n8n عبر (Docker, npm, n8n cloud, تطبيق سطح المكتب): Docker
  • نظام التشغيل:

السؤال

  1. هل توجد أي طريقة رسمية أو موصى بها لتحديد آخر عقدة تم إكمالها بنجاح في هذا السيناريو؟

مرحباً @halouprogramer

إعدادك n8n يستخدم Redis كـ “رسول” لتنسيق العمل بين النظام الرئيسي والعمال. عندما ينقطع اتصال Redis، يختفي الرسول، مما يعني أن النظام الرئيسي لا يتلقى أبداً الإشارة بأن المهمة قد انتهت. هذا يترك المهمة عالقة في حالة “قيد التشغيل”. عند إعادة تشغيل النظام، يلاحظ n8n أن المهمة لم تنتهِ رسمياً ويضعها علامة “تحطمت” كطريقة لتنظيف النظام.

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

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

SELECT data 
FROM execution_entity 
WHERE id = YOUR_EXECUTION_ID;

ملاحظة: قم بتشغيل الاستعلام التالي في مثيل Postgres الخاص بك (استبدل YOUR_EXECUTION_ID بمعرّف فعلي)

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

أهلا بك في المجتمع @halouprogramer!

في وضع الطابور (queue mode)، ما تراه للأسف هو السلوك المتوقع: عندما ينقطع اتصال Redis أثناء التنفيذ، لا تتلقى النسخة الرئيسية إشارة واضحة “انتهيت” من العامل (worker)، لذا يبقى التشغيل في حالة “قيد التنفيذ” (running) حتى يتم تنظيفه، وعندما يتم تنظيفه فعلاً يتم وضع علامة عليه بأنه “متعطل” (crashed) دون سياق على مستوى العقدة (node) في الواجهة.

إذا كنت تريد فعلاً معرفة “أين توقف هذا؟”، فلديك خيارين:

  • للمستقبل: فعّل خيار “Save Execution Progress” لهذا الـ workflow، بحيث يكتب n8n البيانات بعد كل عقدة (node) ويمكنك رؤية آخر عقدة تم إكمالها حتى عندما تكون الحالة النهائية متعطلة.

  • الآن / بأثر رجعي: ابحث في جدول Postgres الخاص بك عن execution_entity بمعرّف التنفيذ المحدد وافحص حمل (payload) البيانات data مباشرة – هذا ملف JSON الخام عادة ما يحتوي على آخر عقدة تمكنت من حفظ مخرجاتها، حتى وإن لم تعرضها الواجهة للتشغيلات المتعطلة.

بعيداً عن ذلك، الحل الحقيقي الوحيد هو الحفاظ على استقرار Redis (المهل الزمنية، إعادة الاتصال، جانب البنية التحتية)، لأنه طالما يمكن للـ “رسول” (messenger) أن يختفي بشكل عشوائي، لا تملك n8n طريقة موثوقة لإغلاق الحلقة وتحديد التنفيذ بحالة نهائية دقيقة.

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