عنوان:

‫بهینه‌سازی عملکرد Nginx با استفاده از تمام قدرت سخت‌افزار موجود


نویسنده: وحید نصیری
تاریخ: ۱۴۰۴/۰۴/۱۴ ۰۸:۱۰
آدرس: www.dntips.ir
Nginx به صورت پیش‌فرض بسیار سریع است. اما تنظیمات اولیه آن طوری طراحی شده‌اند که روی هر نوع سخت‌افزاری، از یک سرور مجازی کوچک گرفته تا یک سرور فیزیکی قدرتمند، به صورت "ایمن" و بدون مشکل کار کنند. این تنظیمات اولیه، محافظه‌کارانه هستند و تمام قدرت سخت‌افزار شما را به کار نمی‌گیرند.
هدف این درس این است که یاد بگیریم چگونه با تنظیم دو پارامتر کلیدی، Nginx را برای سخت‌افزار اختصاصی سرور خودمان بهینه کنیم تا بتواند حداکثر بار ممکن را با بالاترین بازدهی مدیریت کند.

مقایسه: تصور کنید یک ماشین مسابقه دارید. تنظیمات کارخانه برای رانندگی در خیابان مناسب است. اما برای ثبت بهترین رکورد در پیست، باید موتور، تایرها و سیستم تعلیق را دقیقاً برای آن پیست خاص "تیون" کنید. ما هم امروز می‌خواهیم Nginx را برای پیست مسابقه (سرور پروداکشن) خود تیون کنیم.

۲. درک معماری فرآیندهای Nginx
قبل از دستکاری هر پارامتری، باید بدانیم Nginx چگونه کار می‌کند. Nginx از یک مدل استاد-کارگر (Master-Worker) استفاده می‌کند.
فرآیند استاد (Master Process):
  • "رئیس" سیستم است.
  • معمولاً با دسترسی root اجرا می‌شود.
  • وظیفه آن خواندن فایل‌های پیکربندی (nginx.conf)، باز کردن پورت‌ها (مانند 80 و 443) و مهم‌تر از همه، ایجاد و مدیریت فرآیندهای کارگر است.
  • این فرآیند به خودی خود به درخواست‌های کاربران پاسخ نمی‌دهد.

فرآیندهای کارگر (Worker Processes):
  • "کارمندان" واقعی سیستم هستند.
  • با یک کاربر غیرممتاز (مانند www-data) اجرا می‌شوند.
  • این فرآیندها هستند که منتظر درخواست‌های کاربران مانده و آن‌ها را پردازش می‌کنند.
  • هر فرآیند کارگر تک‌رشته‌ای (Single-Threaded) است و از یک مدل رویداد-محور و غیرمسدودکننده (Event-Driven, Non-Blocking I/O) استفاده می‌کند. این راز سرعت فوق‌العاده Nginx است که به آن اجازه می‌دهد هزاران کانکشن را به صورت همزمان با مصرف حافظه بسیار کم مدیریت کند.

مدل کاری:
[Master Process] -> (ایجاد می‌کند) -> [Worker 1], [Worker 2], [Worker 3], ...
هر Worker به صورت مستقل به مجموعه‌ای از کانکشن‌ها رسیدگی می‌کند.

۳. تنظیم worker_processes: استفاده از تمام قدرت CPU
این پارامتر مشخص می‌کند که فرآیند Master چه تعداد فرآیند Worker باید ایجاد کند.
قانون طلایی: تعداد worker_processes را برابر با تعداد هسته‌های پردازنده (CPU Cores) سرور خود قرار دهید.
  • چگونه تعداد هسته‌ها را پیدا کنیم؟
  • با یکی از دستورات زیر در ترمینال لینوکس:
nproc
# یا
grep -c processor /proc/cpuinfo
  • خروجی این دستور، تعداد هسته‌های منطقی پردازنده شماست.

چرا این مقدار بهینه است؟
  • از آنجایی که هر Worker تک‌رشته‌ای است، داشتن یک Worker به ازای هر هسته به سیستم‌عامل اجازه می‌دهد تا هر فرآیند را به یک هسته مجزا "سنجاق" کند. این کار از جابجایی‌های غیرضروری بین هسته‌ها (Context Switching) جلوگیری کرده و باعث استفاده حداکثری و موازی از تمام قدرت پردازشی سرور می‌شود.

پیامدهای تنظیم اشتباه:
  • مقدار خیلی کم: شما تمام قدرت CPU سرور خود را به کار نگرفته‌اید. اگر ۴ هسته دارید و فقط ۱ Worker تعریف کرده‌اید، ۳ هسته دیگر بیکار می‌مانند.
  • مقدار خیلی زیاد: اگر ۸ Worker روی یک سرور ۴ هسته‌ای تعریف کنید، این فرآیندها برای استفاده از هسته‌های محدود با یکدیگر رقابت می‌کنند که منجر به افزایش Context Switching و کاهش عملکرد کلی می‌شود.

نحوه تنظیم:
  • فایل اصلی پیکربندی Nginx را باز کنید: sudo nano /etc/nginx/nginx.conf
# /etc/nginx/nginx.conf

user www-data;
# این خط را ویرایش کنید
worker_processes auto; # 'auto' بهترین گزینه است و به صورت خودکار تعداد هسته‌ها را تشخیص می‌دهد
# یا به صورت دستی
# worker_processes 4; # برای یک سرور ۴ هسته‌ای

pid /run/nginx.pid;
...

۴. تنظیم worker_connections: مدیریت کاربران همزمان
این پارامتر مشخص می‌کند که هر فرآیند کارگر حداکثر چه تعداد کانکشن همزمان را می‌تواند مدیریت کند.
محاسبه حداکثر کانکشن:
  • حداکثر کانکشن‌های تئوریک = worker_processes * worker_connections
  • برای مثال، با worker_processes 4; و worker_connections 1024;، سرور شما می‌تواند به صورت تئوریک 4 * 1024 = 4096 کانکشن همزمان را مدیریت کند.

محدودیت سیستم‌عامل: File Descriptors
  • هر کانکشن در Nginx (چه از سمت کلاینت به Nginx و چه از Nginx به سرویس پشتیبان مانند Kestrel) یک توصیف‌گر فایل (File Descriptor) در سیستم‌عامل مصرف می‌کند. لینوکس به صورت پیش‌فرض محدودیتی برای تعداد فایل‌های باز برای هر فرآیند دارد.
  • برای مشاهده این محدودیت، از دستور زیر استفاده کنید:
ulimit -n
  • خروجی معمولاً 1024 است که برای یک وب‌سرور مدرن بسیار کم است.

چگونه مقدار بهینه را انتخاب کنیم؟
  • مقدار پیش‌فرض worker_connections (معمولاً 768 یا 1024) برای محیط پروداکشن کم است.
  • یک نقطه شروع خوب برای یک وب‌سرور اختصاصی، مقداری بین 4096 تا 8192 است. این مقدار به میزان حافظه RAM سرور شما نیز بستگی دارد.
  • مهم: اگر worker_connections را افزایش دهید، باید محدودیت File Descriptor را نیز افزایش دهید، در غیر این صورت Nginx با خطا مواجه شده و اجرا نخواهد شد.
  • راه‌حل: افزایش محدودیت با worker_rlimit_nofile
  • به جای تغییرات سراسری در سیستم‌عامل، بهترین راه استفاده از یک دستور داخلی خود Nginx است. این دستور، محدودیت تعداد فایل‌های باز را فقط برای فرآیندهای کارگر Nginx افزایش می‌دهد.
نحوه تنظیم:
  • در فایل nginx.conf:
# /etc/nginx/nginx.conf

worker_processes auto;
# این دستور محدودیت فایل‌های باز را برای هر Worker به 16384 افزایش می‌دهد
worker_rlimit_nofile 16384; 

...

events {
    # این مقدار باید کمتر از worker_rlimit_nofile باشد
    worker_connections 4096;

    # نکته امتیازی: این دستور به Worker اجازه می‌دهد تمام کانکشن‌های در صف را یکجا بپذیرد
    # multi_accept on; 
}

۵. جمع‌بندی و نتیجه‌گیری
خلاصه قوانین بهینه‌سازی:
  • worker_processes: مقدار آن را برابر با تعداد هسته‌های CPU سرور خود قرار دهید (بهترین گزینه: auto).
  • worker_connections: یک مقدار بالا و منطقی بر اساس RAM انتخاب کنید (مثلاً 4096).
  • worker_rlimit_nofile: مقدار آن را کمی بالاتر از worker_connections قرار دهید تا از خطای "Too many open files" جلوگیری کنید.
  • فرمول نهایی:Max Connections ≈ worker_processes * worker_connections

با اعمال این تنظیمات، شما Nginx را از یک برنامه با تنظیمات عمومی به یک وب‌سرور کاملاً بهینه و تیون شده برای سخت‌افزار خود تبدیل کرده‌اید که آماده مدیریت ترافیک سنگین است. به یاد داشته باشید که پس از هر تغییر، عملکرد سرور (مصرف CPU و RAM) را تحت بار واقعی نظارت کرده و در صورت نیاز، این پارامترها را دقیق‌تر تنظیم کنید.