وصف المشكلة/الخطأ/السؤال
توقف سير العمل في نسخة n8n السحابية.
سير العمل الخاص بي كان يعمل بسلاسة لآخر 3 أشهر، لكن أمس فشل فجأة 3 مرات وقامت n8n بإيقافه تلقائياً. كان هناك حوادث حيث فشل النظام في أكثر من 30 عملية تنفيذ لكن لم يتم إيقافه. تم إيقاف هذا بعد 3 محاولات فقط. كما حاولت إعادة المحاولة 3 مرات على العقد التي فشلت لكنها توقفت بسبب نفاد مساحة الذاكرة. في الوثائق، يقول أن n8n سيقوم بإعادة تشغيل النسخة تلقائياً لكن هذا لم يحدث أيضاً وكان عليّ بدء تشغيلها يدويًا مرة أخرى بعد يوم من اليوم. ما الاحتياطات التي يمكنني اتخاذها في المستقبل؟
ما هي رسالة الخطأ (إن وجدت)؟
توقف التنفيذ عند هذه العقدة
قد تكون n8n قد نفدت من الذاكرة أثناء تنفيذ هذا الأمر. يمكنك الحصول على المزيد من السياق والنصائح حول كيفية تجنب هذا في الوثائق
يرجى مشاركة سير العمل الخاص بك
(حدد العقد على لوحتك واستخدم اختصارات لوحة المفاتيح CMD+C/CTRL+C و CMD+V/CTRL+V لنسخ ولصق سير العمل.)
شارك الإخراج الذي أرجعته آخر عقدة
معلومات حول إعداد n8n الخاص بك
- إصدار n8n:
- قاعدة البيانات (الافتراضي: SQLite):
- إعدادات n8n EXECUTIONS_PROCESS (الافتراضي: own, main):
- تشغيل n8n عبر (Docker, npm, n8n cloud, desktop app):
- نظام التشغيل:
مرحبًا @Aarush_Bisht
لمنع توقف النظام بسبب مشاكل الذاكرة، يجب عليك التركيز على تقليل «بصمة الذاكرة» للبيانات أثناء تنقلها عبر سير العمل.
أ. تطبيق معالجة دفعية (الخطوة الأهم) إذا كنت تعالج قائمة كبيرة من العناصر (على سبيل المثال، 1000+ صف من قاعدة بيانات أو واجهة برمجية)، فلا تمرر جميعها إلى العقدة التالية في نفس الوقت.
- استخدم عقدة “Split In Batches”: معالجة العناصر في أجزاء أصغر (على سبيل المثال، 50 أو 100 في المرة الواحدة). يضمن هذا أن n8n يحتفظ فقط بمجموعة فرعية صغيرة من البيانات في الذاكرة النشطة في أي لحظة.
ب. تجنب البيانات “الثقيلة” في الذاكرة
- تقييد الحقول: استخدم عقدة Set أو عقدة Edit Fields لإزالة البيانات غير الضرورية في بداية سير العمل. إذا أرجعت واجهة برمجية 50 حقلاً لكنك تحتاج فقط إلى 3، احذف الـ 47 الأخرى فورًا.
- معالجة البيانات الثنائية: إذا كنت تتعامل مع ملفات كبيرة (ملفات PDF وصور)، تجنب الاحتفاظ بنسخ متعددة من البيانات الثنائية في سير عمل النظام. استخدم عقد “Read/Write Binary File” أو التخزين الخارجي (مثل S3 أو Google Drive) ومرر فقط معرف الملف أو عنوان URL بين العقد.
ج. تحسين تنفيذ العقد
- تجنب الحلقات الكبيرة: الحلقات المتداخلة بعمق أو الاستدعاءات الاستكشافية يمكنها بسرعة استهلاك ذاكرة المكدس والكومة.
- عقد الانتظار: إذا كنت تضرب واجهة برمجية في حلقة، أضف عقدة Wait (حتى لمدة ثانية واحدة). هذا لا يمنع تقييد معدل الطلب فحسب، بل يمكنه أيضًا إعطاء مجمع القمامة في Node.js نافذة لمسح الذاكرة غير المستخدمة.
د. المراقبة والتنبيهات
- سير عمل الخطأ: أنشئ «سير عمل خطأ» مخصص (عبر إعدادات سير العمل) يرسل لك إشعار Slack أو بريد إلكتروني في اللحظة التي يحدث فيها فشل. يسمح لك هذا بالتدخل يدويًا قبل أن يصل النظام إلى حد «قاطع الدائرة» ويوقف سير العمل.
كان يعمل بشكل جيد لأشهر لكنه تعطل/ألغيت نشره في يوم واحد فقط بعد 3 مرات مختلفة من فشل التنفيذ. (لقد قمت بتنفيذ 3 محاولات إعادة لكل عقدة في كل تنفيذ). كمية البيانات أيضاً ليست كبيرة (حرفياً فقط 50-60 سطر من بيانات الموظفين). لقد قمت بتنفيذ معالجة الأخطاء أيضاً، قمت بـ “الإخراج الدائم للبيانات” وبعدها إذا تم اكتشاف خطأ سترسل لي رسالة. الجزء اللطيف هو أنه لم يتبع ذلك أيضاً. لم يحاول إعادة المحاولة، فقط فشل وتم إلغاء نشره.
هل ينطبق أي من هذه الحالات:
- حمولة كبيرة غير متوقعة: هل كان لدى أحد هؤلاء الـ 60 موظف حقل (مثل قسم “الملاحظات” أو “السيرة الذاتية”) يحتوي فجأة على كمية ضخمة من النصوص أو صورة/ملف مشفرة بصيغة base64 ضخمة؟
- استجابة API “لا نهائية”: هل أرجعت واجهة برمجة تطبيقات خارجية تستدعيها كائن JSON ضخم (مثل 10 ميجابايت أو أكثر) لمجرد سجل واحد من هذه الـ 60 سجل؟
- مرجع دائري: هل أنشأت البيانات حلقة تسببت في وصول محرك JavaScript إلى حد “Stack Overflow” أو “Out of Memory”؟
تحقق من سجلات السحابة الخاصة بك
- تحقق من سجل التنفيذ: ابحث عن التنفيذات الـ 3 الفاشلة. هل لديها حالة
Error أم أنها ببساطة Running (عالقة) أو مفقودة بالكامل؟ إذا كانت مفقودة أو عالقة في حالة “Running” رغم أن سير العمل مغلق، فهذا يؤكد حدوث عطل حاد.
- فحص البيانات: انظر إلى البيانات التي دخلت سير العمل أمس. قارنها بالأيام السابقة. ابحث عن أي نصوص كبيرة بشكل غير عادي أو صيغ غير متوقعة في هذه الـ 60 سطر.
- تحقق من “العقد الثقيلة”: هل لديك أي عقد أكواد (Code Nodes)؟ حتى خطأ منطقي صغير في عقدة أكواد (مثل حلقة
while لا نهائية) يمكنه استهلاك كل ذاكرة الوصول العشوائي المتاحة في ثوان، متجاوزًا جميع معالجات الأخطاء المدمجة في n8n.
50-60 سطر من البيانات كانت لموظف واحد.
وواحدة من الـ 3 التي فشلت كانت عقدة كود JavaScript حيث كنت أحاول بنفسي تقليل أبعاد البيانات.
{
“nodes”: [
{
“parameters”: {
“jsCode”: “\nconst updates = $node["Webhook"].json.body.data.fieldUpdatesIds.map(f => f.id);\n\nconst targetFields = [\n "work.site",\n "work.department",\n "work.siteId",\n "work.customColumns.column_1732603686850",\n "work.workChangeType",\n "work.title",\n "work.activeEffectiveDate",\n "work.reportsTo",\n "root.displayName"\n];\n\nconst check = updates.some(id => targetFields.includes(id));\n\nreturn [{check}];\n”
},
“type”: “n8n-nodes-base.code”,
“typeVersion”: 2,
“position”: [
-3104,
496
],
“id”: “7e8b7768-aa58-4218-98bb-24008a7ea4ef”,
“name”: “Code in JavaScript1”
}
],
“connections”: {
“Code in JavaScript1”: {
“main”: [
]
}
},
“pinData”: {},
“meta”: {
“instanceId”: “0f39d8fdd402ddce20d0eb724526828e8c2d8679170e3a08fe6cd471c799fab6”
}
}
لا يمكن التحقق من السجلات لهذه الـ 3 عمليات تنفيذ معينة لأن n8n يقول أن السجلات لم يتم حفظها بسبب فشل التنفيذ. (غريب، لأن سجلات الأخطاء أكثر أهمية).
عقدة واحدة فشلت وكانت موجودة فقط للحصول على رمز المصادقة. لا توجد حلقة، فقط ضربة API واحدة. الثالثة (عقدة HTTP) كانت تحتوي على بعض imageUrls في الاستجابة لكن ليس صور (بناءً على التنفيذات السابقة). فشلت جميع الثلاثة معاً في 3 عمليات تنفيذ مختلفة بنفس السبب.
هل يمكن أن يكون هناك خلل ما على جانب خادم n8n؟
غير محتمل جداً.
الكود الخاص بك بسيط من الناحية المنطقية ولا يجب أن يؤدي إلى تعطل الخادم مع 60 سطراً من البيانات. ومع ذلك، هناك خطر أداء في طريقة الوصول إلى البيانات:
const updates = $node["Webhook"].json.body.data.fieldUpdatesIds.map(f => f.id);
استخدام $node["NodeName"] يفرض على n8n الاحتفاظ بـ كائن البيانات الكامل للعقدة السابقة في ذاكرة الوصول العشوائي النشطة طوال مدة سير العمل. إذا كانت حمولة Webhook الخاصة بك كبيرة، وكان لديك عدة عقد تفعل هذا، فأنت تضاعف استخدام الذاكرة.
استبدل كود JavaScript الحالي بهذا الإصدار. يستخدم الصيغة الحديثة ويضيف “فحص أمان” لمنع العقدة من التعطل إذا كانت البيانات مفقودة (والتي قد تسبب بخلاف ذلك TypeError):
// استخدم صيغة $(...).item الحديثة لإدارة أفضل للذاكرة
const webhookData = $("Webhook").item.json.body?.data?.fieldUpdatesIds;
if (!Array.isArray(webhookData)) {
return [{ check: false, error: "No fieldUpdatesIds found" }];
}
const updates = webhookData.map(f => f.id);
const targetFields = [
"work.site",
"work.department",
"work.siteId",
"work.customColumns.column_1732603686850",
"work.workChangeType",
"work.title",
"work.activeEffectiveDate",
"work.reportsTo",
"root.displayName"
];
const check = updates.some(id => targetFields.includes(id));
return [{ check }];
للتأكد من أنك تحصل بالفعل على السجلات عند حدوث أخطاء:
- انتقل إلى إعدادات سير العمل (أيقونة الترس).
- تأكد من تشغيل “حفظ التنفيذات الفاشلة” على.
- اضبط “حفظ التنفيذات الناجحة” على إيقاف التشغيل (أو “فقط في حالة الخطأ”). هذا يحرر موارد قاعدة البيانات ويجعل من السهل اكتشاف تنفيذات “السم”.
بما أنك ذكرت أن عقدة HTTP كانت تحتوي على imageUrls، تحقق مما إذا كان أي من هذه عناوين URL تعيد بيانات وصفية ضخمة أو إذا كان نص الرد أكبر من المتوقع. حتى لو لم تكن الصورة نفسها، يمكن لاستجابة JSON ضخمة أن تزيد من استخدام الذاكرة.
لقد تحققت للتو من عمليات التنفيذ الفاشلة وكانت الحفظ الافتراضي. بيانات JSON كانت تحتوي فقط على روابط الصور، وليس شيئاً آخر من هذا القبيل. كما أنني نظرت للتو إلى البيانات التي يتلقاها جميع العقد من webhook (نعم، كانت عقدة الكود هذه تعالج تلك البيانات). إنه webhook حدث Slack أساسي يستقبل 20-30 سطراً من بيانات وصف طلب API (في الرؤوس) و10 أسطر من الجسم ومعلومات أخرى بصيغة JSON. (لا يبدو أن هناك مشكلة). مشكلتي أنه إذا ذهبت في إجازة وحدث هذا في أي وقت، فقد يكون النظام معطلاً لفترة من الوقت بعد ذلك.
احتمالان:
- تسرب تراكمي: على مدى 3 أشهر، قد لا تكون كميات صغيرة من الذاكرة قد تم مسحها بشكل صحيح. في النهاية، أصبح استخدام الذاكرة “الأساسي” مرتفعًا جدًا بحيث أن حتى webhook صغير من Slack دفعه فوق الحد.
- التزامن: إذا ضربت 5 أو 10 أحداث Slack webhook الخاص بك في نفس الثانية بالضبط، يقوم n8n بتشغيل عمليات متوازية متعددة. حتى لو كان كل واحد صغيرًا، يمكن لـ 10 عمليات متزامنة أن ترفع استخدام RAM وتؤدي إلى الانهيار.
بما أنك قلق بشأن توقف النظام أثناء إجازتك، لا يمكنك الاعتماد على n8n لمراقبة نفسه (لأنه إذا انهار، ستنهار المراقبة أيضًا). تحتاج إلى مراقبة خارجية.
استخدم خدمة مجانية مثل Better Stack أو UptimeRobot أو Cronitor.
- أنشئ سير عمل ثاني بسيط جدًا في n8n:
Webhook Trigger → Respond to Webhook (200 OK).
- اضبط المراقب الخارجي للاتصال بهذا URL كل 5 أو 10 دقائق.
- إذا حصل المراقب على خطأ 500 أو انقطاع في الاتصال، سيرسل لك بريدًا إلكترونيًا أو رسالة SMS على الفور. ستعرف أن المثيل معطل قبل أن يفقد سير عملك الرئيسي بيانات حرجة.
بالنظر إلى لقطة الشاشة الخاصة بك، لديك “Save successful production executions” معيّنة على “Save”.
- غيّر هذا إلى “Do not save”.
- لماذا؟ في كل مرة يتم حفظ عملية تنفيذ ناجحة، يتعين على n8n الاحتفاظ بتلك البيانات في الذاكرة وكتابتها على القرص. بالنسبة إلى webhook Slack عالي التكرار، يؤدي هذا إلى “ارتجاج” مستمر في ذاكرة المثيل. بحفظ الأخطاء فقط، تقلل بشكل كبير من الحمل على المثيل.
بما أن بياناتك صغيرة بشكل موضوعي وكنت تعمل لمدة 3 أشهر، قد تكون هذه مشكلة في “العقدة” المحددة (الخادم الفعلي) المضيف لمثيلك.
- أرسل لدعم سحابة n8n أو help@n8n.io لقطة شاشة العملية المنفذة “Interrupted”.
- أخبرهم: “سير عملي يعالج حمولات Slack صغيرة جدًا، لكنني أرى عمليات تنفيذ ‘Interrupted’ و Circuit Breaker يقوم بإلغاء نشر سير عملي. هل يمكنك التحقق مما إذا كان المثيل الخاص بي يواجه ضغطًا على الذاكرة أم يجب نقلي إلى مضيف مختلف؟”
هل يمكنني فعل شيء ما لإصلاح التسريبات التراكمية؟ مثل إعادة تشغيل سير العمل أو شيء من هذا القبيل؟ قد لا يكون إيقاف التشغيل للتكرارات الناجحة خياراً لي (مثيل الشركة، لذا أحتاج إلى الاحتفاظ بالسجلات الكاملة على الأقل لبعض الأيام الماضية). قد تكون التزامن مشكلة محتملة حيث حدثت جميع التنفيذات الفاشلة الثلاث معاً (لكنني رأيت n8n يتعامل مع 8-10، وأحياناً أكثر). قد لا تكون هناك حاجة لمراقبة خارجية حيث أن n8n نفسه يرسل رسالة بريد إلكترونية بأنهم أيقفوا التشغيل وتم إبلاغنا (أردت أن أقول من يأخذ جهاز كمبيوتر الشركة في الإجازة
)
إعادة تشغيل سير العمل نفسه لن تؤدي إلى مسح التسرب؛ نقطة الإعادة تعيين هي مثيل التشغيل أو العامل. في هذه الحالة، الفهم الأكثر دقة هو أن الأعطال الثلاثة حدثت معاً، وليس أن عقدة الكود ثقيلة.
تحقق من نافذة واحدة، لا توجد حاجة لبيانات الموظفين: هل بدأت عمليات تنفيذ webhook في Slack الثلاث خلال نفس بضع ثوان، وهل كانت هناك أي عمليات تنفيذ أخرى تعمل في تلك اللحظة؟ إذا كانت الإجابة بنعم، فإن الحد التالي هو بوابة طابور صغيرة/متسلسلة قبل مسار تحديث الموظف، لذلك يتم الاعتراف بـ Slack بسرعة لكن يتم معالجة وظيفة تحديث واحدة فقط في كل مرة. إذا كانت متباعدة، فتعامل معها كحادث Cloud/runtime وقدم للدعم معرّفات التنفيذ الثلاثة بالإضافة إلى طابع زمني للتعطيل التلقائي.
قد تكون هذه مشكلة تزامن. هل هناك طريقة للتعامل معها؟ مثلاً هل يمكننا تأخير التنفيذات التي تحدث في نفس الوقت بفترة زمنية ما؟
نعم، لكن لا تضع التأخير بعد العقد الثقيلة. إذا بدأت ثلاث أحداث Slack بالفعل سير العمل الكامل، فإن عقدة Wait ستترك ثلاث عمليات تعمل في نفس الوقت.
أبقِ استقبال Slack صغيراً: استقبل الحدث، وأقِرّ به، وضع فقط معرّف الحدث/النص المطلوب لتحديث الموظف خلف بوابة واحد تلو الآخر. ثم قم بمعالجة هذا الجزء الثاني على أساس جدول زمني أو قائمة انتظار. يمكنك الاحتفاظ بسجلات التنفيذ؛ ما تحتاج إلى تقليله هو العمل المتوازي في فرع تحديث الموظف، وليس الاحتفاظ بالسجلات في حد ذاته.
أعتقد أن الحدث كان صغيراً بالفعل حيث أن بيانات webhook لم تكن كبيرة (بحد أقصى 50-60 سطر json) ونحتاج إلى حقول قليلة منها (ما كان عقدة الكود تقوم به - تقليل أبعاد البيانات). المشكلة فقط أن الطلب جاء بشكل متوازي. لقد رأيت طلبات https تتلقى MBs من البيانات ولا تتعطل. على أي حال، سأحاول إيصال هذا إلى فريق n8n (إن أمكنني ذلك). شكراً على المساعدة، سأحاول تطبيق هذه الاقتراحات في سير العمل المستقبلي.