متحمس دائماً للمشاريع الجديدة والتعاون مع الأفكار المبتكرة.
+968 97716144
contact@aljulanda.info
https://aljulanda.info
سلطنة عمان - نزوى
نظام Odoo عندك صار بطيء؟ قبل ما تفكر بترحيل السيرفر، افحص إعدادات الـ workers وتوزيع الرام وحدود الذاكرة وصحة autovacuum في PostgreSQL بالأرقام الرسمية من Odoo.
Odoo كبرنامج، بحد ذاته، نادراً ما يكون هو السبب في بطء التشغيل الذاتي (on-premise). السبب في الغالبية الساحقة من الحالات واحد من ثلاثة: السيرفر شغّال في وضع لا يتحمّل مستخدمين متزامنين، أو الذاكرة المخصصة لكل worker process غير متناسبة مع الواقع، أو أن PostgreSQL يتضخّم بصمت من شهور لأن أحد ما راجع autovacuum. ولا واحدة من هذي الثلاث تظهر كرسالة خطأ واضحة. كلها تظهر بشكل "اليوم النظام بطيء"، وهذا بالضبط سبب تشخيصها الخاطئ كـ"عيب في Odoo" و"حلّها" برمي VM أكبر على المشكلة بدل تصحيح الإعدادات.
افتح ملف إعدادات Odoo (عادة /etc/odoo/odoo.conf) وشوف قيمة workers. إذا كانت غير موجودة أو مضبوطة على 0، فأنت شغّال بالوضع الخيطي (threaded mode) — عملية واحدة تعالج كل طلب بالتسلسل، واحد ورا الثاني. هذا مقبول على لابتوب مطوّر، لكنه غير مقبول أبداً لخمسة أو عشرة مستخدمين يضغطون على نفس السيرفر بنفس الوقت، لأن تقرير ثقيل واحد أو استيراد كبير راح يجمّد كل شي وراه. إذا كان نظامك الإنتاجي فيه أكثر من عدد بسيط من المستخدمين المتزامنين وقيمة workers لسه صفر، فأنت غالباً لقيت مشكلتك الرئيسية قبل ما تلمس أي شيء ثاني.
وضع Multi-processing يوزّع الطلبات الواردة على عمليات worker منفصلة بدل خيط واحد يحاول يسوي كل شي. المثال المرجعي الرسمي من Odoo لبيئة إنتاجية يستقر عند 8 HTTP workers بالإضافة إلى cron worker واحد مخصص — وهذا الرقم هو نقطة الارتكاز اللي تعتمد عليها، مو رقم مخمّن من منتدى. راقب حمل المعالج (CPU load) وقت ذروة استخدام المستخدمين — باستخدام top أو htop أو أداة المراقبة اللي تستخدمها — وقارنه مع عدد الـ workers المفعّل فعلياً. إذا كان المعالج شبه خامل والمستخدمين يشتكون من التعليق، فمشكلتك في نقص عدد الـ workers مو في ضعف الهاردوير. وإذا كان المعالج عالق عند 100% وعندك فقط اثنين أو ثلاثة workers، فإضافة workers أكثر على نفس الجهاز الضعيف بيعمل swapping فقط، مو تسريع.
هذي الخطوة اللي يتجاوزها الجميع تقريباً، وهي السبب وراء عمليات OOM (نفاد الذاكرة) — السيرفر يقتل worker process بصمت في منتصف الطلب، والمستخدم يحس بها فقط كـ"الصفحة ما فتحت". طريقة Odoo الرسمية للتحجيم معادلة مرجّحة:
الذاكرة = عدد الـ workers × ((0.8 × ذاكرة الطلب الخفيف) + (0.2 × ذاكرة الطلب الثقيل))
بمعنى آخر: أغلب الطلبات خفيفة (عرض قوائم، فتح نماذج بسيطة)، لكن خُمس حركة المرور تقريباً طلبات ثقيلة (تقارير، استيراد بيانات، عمليات بحث كبيرة)، وميزانية الرام عندك لازم تغطي الاثنين مو المعدل فقط. في المثال المحسوب رسمياً من Odoo، هذي المعادلة توصل إلى تقريباً 3 غيغابايت لعمليات Odoo نفسها في إعداد بـ 8 workers — وهذا الرقم (3 غيغا) هو اللي يُستخدم بعدين لتحديد حدود الذاكرة لكل worker اللي بنتكلم عنها بالخطوة الجاية. إذا كان سيرفرك كله 4 غيغابايت رام وعليه أيضاً PostgreSQL وmail relay وربما مشاركة Samba على نفس الجهاز، فأنت أصلاً غارق قبل ما يسجّل دخول أي مستخدم.
أربع معاملات تتحكم بمدى صرامة حماية Odoo لنفسه من عملية واحدة هاربة تلتهم السيرفر كامل. الإعداد المرجعي الرسمي من Odoo يضبطها كالتالي:
limit_memory_soft = 629145600 (≈600 ميغابايت) — إذا تجاوز الـ worker هذا الحد أثناء طلب معين، يخلي Odoo الطلب ينتهي، وبعدها يقتل الـ worker ويعيد إنشاءه قبل ما يستقبل الطلب التالي.limit_memory_hard = 1677721600 (≈1.6 غيغابايت) — إذا تجاوزه، يُقتل الـ worker فوراً بدون أي مهلة، حماية لباقي النظام.limit_time_cpu = 600 — أقصى عدد ثواني معالج (CPU seconds) يُسمح فيها للطلب قبل ما يُقتل.limit_time_real = 1200 — أقصى وقت فعلي بالثواني (wall-clock) قبل قتل الطلب، ويشمل وقت الانتظار على I/O كذلك.limit_request = 8192 — عدد الطلبات اللي يعالجها الـ worker قبل ما يعيد تدوير نفسه، وهذا يساعد ضد التسرب البطيء بالذاكرة.إذا ملف الإعدادات عندك لسه فيه القيم الافتراضية اللي جاية من التنصيب ولم تلمسها أبداً، فأنت تشتغل بدون رؤية. الحدود الأصغر من اللازم تقتل تقارير ثقيلة مشروعة وهي شغّالة. والحدود الأكبر من اللازم (أو عدم وجودها أصلاً) تخلي طلب سيء واحد يرفع استهلاك الرام لين يتدخل OOM killer في نواة النظام ويضحّي بأحد الـ workers — وأحياناً مو حتى اللي سبب المشكلة أصلاً.
الـ cron worker (المعامل max_cron_threads، مضبوط على 1 في المثال الرسمي) يتكفّل بالمهام المجدولة — تشغيل الفوترة، تقييم المخزون، الإيميلات الآلية. إذا كان مفقود أو مضبوط على 0، فمهامك الخلفية تتراكم بصمت وفي النهاية تبدأ تنافس حركة المستخدمين الفعلية على الموارد.
من جهة ثانية، إذا تستخدم LiveChat في Odoo، فوضع multi-processing يشغّل تلقائياً worker مخصص لـ LiveChat يستمع على --gevent-port. والمشكلة هنا: بشكل افتراضي، طلبات HTTP تستمر توصل لعمالك العاديين بدل ما توصل لـ worker الـ LiveChat. تحتاج reverse proxy (وNginx هو الخيار المعتاد) أمام Odoo يوجّه تحديداً أي مسار يبدأ بـ /websocket/ إلى منفذ worker الـ LiveChat. إذا تجاهلت هذي الخطوة، إما LiveChat ما يشتغل صح أو يضعف بصمت أداء مجموعة الـ workers العادية عندك.
وأنت تعدّل إعدادات الـ proxy، تأكد إن Odoo يعمل بخيار --proxy-mode مفعّل. بدونه، Odoo يثق برؤوس (headers) الـ proxy نفسها بدل اسم المضيف والبروتوكول وعنوان IP الحقيقي للعميل — وهذا يكسر التسجيل (logging) والفحوصات الأمنية وأي شي يعتمد على معرفة هوية الطرف اللي يتصل فعلاً.
ممكن تضبط الـ workers والرام بشكل مثالي تماماً وبرضو النظام بطيء لأن قاعدة البيانات نفسها متضخمة. كل عملية update وdelete في PostgreSQL تترك خلفها صفوف ميتة (dead tuples) — نسخ صفوف قديمة ما تُنظّف تلقائياً بالوقت الفعلي. هذا شغل autovacuum، ويتحكم فيه معاملات موجودة في postgresql.conf. عملية autovacuum launcher daemon تعمل بشكل افتراضي ("on")، لكنها تعتمد على تفعيل track_counts — إذا كان هذا الخيار مطفي، فـ autovacuum فعلياً ما يسوي شي حتى لو يبدو "مفعّل" في الإعدادات.
قيمتان افتراضيتان مهمتان جداً مع نمو قاعدة البيانات: autovacuum_vacuum_threshold افتراضياً 50 صف فقط، وautovacuum_vacuum_insert_threshold (المسؤول عن تفعيل التنظيف في الجداول الكثيرة الإدخال) افتراضياً 1000 صف. هذي القيم كانت منطقية لقواعد بيانات صغيرة. أغلب تنصيبات Odoo الذاتية ما ترجع تراجع هالقيم مع نمو حجم المعاملات إلى ملايين الصفوف — حركات المخزون، سطور القيود المحاسبية، رسائل البريد — ويبدأ autovacuum يتأخر عن مواكبة الحجم، فتتضخم الجداول والفهارس. كل استعلام على جدول متضخم يمسح وزن ميت أكثر من اللازم، وما فيه أي ضبط للـ workers أو الرام يعالج هذي المشكلة.
شغّل الاستعلام SELECT relname, n_dead_tup, n_live_tup FROM pg_stat_user_tables ORDER BY n_dead_tup DESC LIMIT 15; وشوف النتيجة. إذا عدد الصفوف الميتة يفوق الصفوف الحية بشكل كبير في أكبر جداولك، فهذي إجابتك.
workers مضبوط وأكبر من 0 — بدون multi-processing ما فيه تزامن حقيقي.limit_memory_soft وlimit_memory_hard وlimit_time_cpu وlimit_time_real مضبوطة صراحة، مو فارغة.max_cron_threads مضبوط، وإن الـ proxy يوجّه حركة /websocket/ بشكل صحيح إذا كنت تستخدم LiveChat.track_counts مفعّل، واستعلم عن pg_stat_user_tables لمعرفة عدد الصفوف الميتة في أكبر جداولك.راجع هذي القائمة كاملة قبل ما تلمس ميزانيتك لشراء هاردوير جديد. في أغلب الحالات، الحل هو تعديل بملف الإعدادات وعملية vacuum لقاعدة البيانات، مو سيرفر أكبر.
مصدر الصورة: dylanroscover — BY-SA
لن يتم نشر عنوان بريدك الإلكتروني. الحقول المطلوبة مشار إليها بـ *
Cookie preferences