يأتي ملف إعدادات Nginx مزوداً بإعدادات افتراضية معقولة. لكن "الإعدادات الافتراضية المعقولة" و"أقصى إنتاجية ممكنة" أمران مختلفان تماماً. إذا كنت تشغّل خادم ويب مشغولاً ولم تتطرق إلى إعدادات عمليات Worker، فأنت على الأرجح تُهدر أداءً كان بإمكانك الاستفادة منه.
يستعرض هذا الدليل التوجيهات الرئيسية التي تتحكم في كيفية تعامل Nginx مع الاتصالات المتزامنة — وكيفية ضبطها وفقاً لمواصفات جهازك وطبيعة عمله. سنتناول الأرقام والمنطق الكامن وراءها، والمقايضات التي تحتاج إلى فهمها قبل إجراء أي تغييرات.
لماذا يُعدّ ضبط عمليات Worker مهماً لتحسين أداء Nginx
يعتمد Nginx على بنية غير متزامنة مدفوعة بالأحداث. على عكس نموذج Apache القائم على عملية لكل طلب، يُنشئ Nginx عدداً صغيراً من عمليات Worker، كل منها قادرة على التعامل مع آلاف الاتصالات في آنٍ واحد. هذا ما يجعله بالغ الكفاءة تحت الضغط.
لكن هذه الكفاءة تعتمد على توافق إعداداتك مع مواصفات جهازك. إذا ضبطت عدداً قليلاً جداً من Workers فستُهدر أنوية CPU. وإذا ضبطت عدداً كبيراً جداً فستُدخل تكلفة إضافية ناجمة عن تبديل السياق مما يُبطئ الأمور فعلياً. الهدف هو إيجاد النقطة المثلى لخادمك.
إذا كنت مهتماً بمعرفة كيف تنعكس خيارات الإعداد على مستوى الخادم على المقاييس الفعلية، فقد تناولنا هذه العلاقة بالتفصيل في لماذا يُكلّفك وقت أول بايت تحويلاتك (وكيف تُصلح ذلك).
تحديد العدد الصحيح لعمليات Worker
يتحكم التوجيه worker_processes في ملف nginx.conf في عدد عمليات Worker التي يُنشئها Nginx. التوصية الأكثر شيوعاً هي مطابقة هذا العدد مع عدد أنوية CPU المتاحة على خادمك.
worker_processes auto;استخدام auto يُخبر Nginx باكتشاف عدد أنوية CPU وضبط القيمة وفقاً لذلك. هذا هو الخيار الصحيح لمعظم الإعدادات. إذا أردت ضبطه يدوياً، تحقق أولاً من عدد الأنوية:
nproc --allثم اضبطه صراحةً:
worker_processes 4; # لخادم رباعي الأنويةتفصيل مهم: إذا كان خادمك مخصصاً بالكامل لـ Nginx، فإن مطابقة الأنوية مع Workers هو الخيار المثالي. أما إذا كنت تشغّل عمليات أخرى كثيفة الاستخدام لـ CPU إلى جانب Nginx (مثل PHP-FPM أو MySQL أو Redis)، فقد ترغب في ترك نواة أو نواتين حرتين لتجنب التنافس على الموارد.
تحسين أداء Nginx: اتصالات Worker والحسابات الكامنة وراءها
يحدد التوجيه worker_connections الحد الأقصى لعدد الاتصالات المتزامنة التي يمكن لكل عملية Worker التعامل معها. ويقع داخل كتلة events:
events { worker_connections 1024; }إجمالي الحد الأقصى للاتصالات التي يمكن لخادمك التعامل معها هو:
max_connections = worker_processes × worker_connectionsإذن خادم رباعي الأنوية مع worker_connections 1024 يمكنه نظرياً التعامل مع 4,096 اتصالاً متزامناً. من الناحية العملية، ستصطدم بحدود واصفات الملفات على مستوى نظام التشغيل قبل أن تصل إلى هذا السقف — وهذا ما يقودنا إلى الإعداد التالي.
رفع حد واصفات الملفات
كل اتصال يستهلك واصف ملف. بشكل افتراضي، يحدد Linux هذا بـ 1,024 لكل عملية. إذا تجاوز worker_connections هذا الحد، ستواجه أخطاء تحت الضغط.
اضبط الحد في nginx.conf بـ:
worker_rlimit_nofile 65535;وحدّث حدود النظام في /etc/security/limits.conf:
nginx soft nofile 65535 nginx hard nofile 65535حدّث أيضاً /etc/sysctl.conf لرفع حد واصفات الملفات على مستوى النظام بأكمله:
fs.file-max = 200000طبّق التغيير بـ sysctl -p. هذه التغييرات الثلاثة تعمل معاً — إغفال أي منها قد يتسبب في فشل الاتصالات تحت الحمل الثقيل.
تقارب CPU: تثبيت Workers على الأنوية
بشكل افتراضي، يقرر جدول مهام نظام التشغيل أي نواة CPU تشغّل كل Worker في Nginx. هذا عادةً مقبول، لكن تحت حركة مرور عالية جداً يمكنك تقليل أخطاء الذاكرة المؤقتة وتبديل السياق عن طريق تثبيت كل Worker على نواة محددة باستخدام worker_cpu_affinity.
# لخادم رباعي الأنوية مع 4 Workers worker_cpu_affinity 0001 0010 0100 1000;كل قناع بت يتوافق مع نواة CPU. يُثبَّت Worker الأول على النواة 0، والثاني على النواة 1، وهكذا. لخادم ثماني الأنوية مع 8 Workers:
worker_cpu_affinity auto;قيمة auto (المتاحة في Nginx 1.9.10+) تتولى التثبيت تلقائياً. هذا هو الخيار الأنظف إذا كنت تستخدم إصداراً حديثاً من Nginx.
يُظهر ضبط تقارب CPU أكبر فائدة على الخوادم التي تتعامل مع أكثر من 10,000 طلب في الثانية. دون هذا الحد، تكون المكاسب عادةً ضئيلة.
توجيها Multi-Accept وUse
إعدادان آخران داخل كتلة events يستحقان المعرفة:
events { worker_connections 4096; multi_accept on; use epoll; }multi_accept on يُخبر كل Worker بقبول أكبر عدد ممكن من الاتصالات الجديدة في مرور واحد، بدلاً من واحد في كل مرة. هذا يقلل زمن الاستجابة تحت حركة المرور المتقطعة. يستحق التفعيل دائماً تقريباً.
use epoll يضبط صراحةً طريقة معالجة الاتصالات على epoll، وهي الخيار الأكثر كفاءة على Linux. يختار Nginx هذا عادةً تلقائياً، لكن التصريح به لا يضر ويجعل إعداداتك موثقة ذاتياً.
اتصالات Keepalive وإنتاجية Worker
تتيح اتصالات Keepalive لاتصال TCP واحد خدمة طلبات HTTP متعددة. هذا يقلل التكلفة الإضافية لإنشاء الاتصالات وإنهائها — وهو أمر مهم جداً على نطاق واسع.
http { keepalive_timeout 65; keepalive_requests 100; }keepalive_timeout يحدد المدة التي يبقى فيها الاتصال الخامل مفتوحاً. keepalive_requests يحدد عدد الطلبات التي يمكن لاتصال واحد خدمتها قبل إغلاقه.
بالنسبة للمواقع ذات حركة المرور العالية، يمكن أن يؤدي رفع keepalive_requests إلى 500 أو حتى 1000 إلى تقليل ملحوظ في تكلفة الاتصالات. فقط كن على دراية بأن مهل keepalive الطويلة جداً قد تُقيّد اتصالات Worker مع عملاء خاملين — لذا لا تضبط keepalive_timeout بقيمة عالية جداً (65 ثانية كريمة بالفعل لمعظم حالات الاستخدام).
مثال كامل لتحسين أداء Nginx
إليك كتلة إعداد موحدة تطبق كل ما تم تناوله أعلاه، مناسبة لخادم ويب مخصص رباعي الأنوية:
worker_processes auto; worker_rlimit_nofile 65535; events { worker_connections 4096; multi_accept on; use epoll; } http { keepalive_timeout 65; keepalive_requests 500; sendfile on; tcp_nopush on; tcp_nodelay on; # ... بقية إعدادات http }توجيهات sendfile وtcp_nopush وtcp_nodelay تستحق التضمين أيضاً. sendfile يتيح للنواة نقل الملفات مباشرةً دون نسخ البيانات عبر فضاء المستخدم. tcp_nopush يجمع ترويسات الاستجابة وبداية الملف في حزمة واحدة. tcp_nodelay يُعطّل خوارزمية Nagle لتسليع أسرع للحزم الصغيرة. معاً، تقلل زمن الاستجابة لتقديم الملفات الثابتة.
كيفية التحقق من أن تغييراتك تعمل
بعد تحديث إعداداتك، اختبر دائماً قبل إعادة التحميل:
nginx -tثم أعد التحميل دون إسقاط الاتصالات:
nginx -s reloadلقياس التأثير، استخدم wrk أو ab (Apache Bench) لمحاكاة الحمل المتزامن:
# 12 خيطاً، 400 اتصال متزامن، اختبار لمدة 30 ثانية wrk -t12 -c400 -d30s https://yourdomain.com/قارن الطلبات في الثانية ونسب زمن الاستجابة قبل تغييراتك وبعدها. يجب أن يُظهر الخادم المضبوط جيداً انخفاضاً ملحوظاً في زمن استجابة p99 تحت الحمل المستمر.
للاطلاع على نظرة أشمل حول ما يؤثر على درجات سرعة خادمك، يُعدّ Core Web Vitals والاستضافة: لماذا خادمك إما يساعد أو يضر بدرجاتك قراءة مكملة ممتازة.
عندما لا يكفي ضبط Nginx وحده
يُقطع ضبط عمليات Worker شوطاً طويلاً، لكنه طبقة واحدة من منظومة أداء أكبر. إذا كان تطبيقك بطيئاً — استعلامات قاعدة بيانات بطيئة، أو PHP غير محسّن، أو غياب التخزين المؤقت للكائنات — فإن Nginx سيُقدّم استجابات بطيئة بأمانة وبشكل أسرع. هذا ليس نفس الشيء كموقع سريع.
الجمع بين إعداد Nginx الجيد والتخزين المؤقت على جانب الخادم (مثل التخزين المؤقت للكائنات باستخدام Redis) وطبقة تطبيق مضبوطة جيداً هو المكان الذي تتضاعف فيه المكاسب الحقيقية. نشغّل التخزين المؤقت للكائنات المدعوم بـ Redis على جميع خوادمنا المُدارة بشكل افتراضي، مما يعني تقديم نتائج استعلامات قاعدة البيانات من الذاكرة بدلاً من إعادة تنفيذها مع كل طلب — وهو مضاعف كبير فوق أي تحسين أداء Nginx تقوم به.
للاطلاع على استراتيجيات التخزين المؤقت التي تكمّل إعداد Nginx لديك، راجع كيفية إعداد Redis للتخزين المؤقت على خادمك دون كسر أي شيء.
الخلاصة
تحسين أداء Nginx على مستوى Worker ليس معقداً، لكنه يتطلب فهم ما يفعله كل توجيه فعلياً. الملخص المختصر: طابق worker_processes مع أنوية CPU لديك، ارفع حدود واصفات الملفات لتتوافق مع worker_connections، فعّل multi_accept، واستخدم epoll. ثم قِس الأداء للتأكد من أن التغييرات تُحقق التأثير المتوقع.
التغييرات الصغيرة في الإعداد على هذا المستوى يمكن أن تُترجم إلى تحسينات قابلة للقياس في الإنتاجية وزمن الاستجابة — خاصةً تحت الحمل المتزامن المستمر. ابدأ بـ auto حيثما كان متاحاً، قِس، وعدّل من هناك.
لمزيد من المعلومات حول الصورة الكاملة لتحسين الأداء، تغطي نظرة عامة على الأداء لدينا كيف يندرج الضبط على مستوى الخادم ضمن المنظومة الأشمل.