راهنمای جامع ulimit در لینوکس و برطرف کردن خطا Too many open files

تعریف

ابزار ulimit مخفف (user limit) ابزاری است که در پوسته (Shell) برای مشاهده و تنظیم محدودیت‌های منابع در سطح فرایند (Process) به‌کار می‌رود. این محدودیت‌ها مشخص می‌کنند یک کاربر یا یک برنامه تا چه اندازه می‌تواند از منابع سیستم مانند فایل، حافظه یا زمان CPU استفاده کند.

مشکل Too many open files به خاطر محدودیت پیشفرض ulimit -n (تعداد فایل دیسکریپتور باز) هست که در اکثر توزیع‌های لینوکس روی 1024 ست شده است.

سطوح محدودیت

هر محدودیت دو سطح دارد:

  • محدودیت نرم Soft Limit : مقدار پیش‌فرضی است که در حالت عادی توسط فرایند استفاده می‌شود. کاربر می‌تواند این مقدار را تا سقف Hard Limit افزایش دهد.

  • محدودیت سخت Hard Limit : بیشینه مقداری است که برای یک محدودیت تعیین شده و فقط کاربر ریشه (root) قادربه افزایش آن است.

ستون ۱ ستون ۲
ulimit -n حداکثر تعداد فایل‌های باز (File Descriptors)
ulimit -u حداکثر تعداد فرایندهایی که یک کاربر می‌تواند ایجاد کند
ulimit -f حداکثر اندازه فایل قابل ایجاد (بر حسب بلوک)
ulimit -v حداکثر میزان حافظه مجازی قابل استفاده
ulimit -s اندازه پشته (Stack Size)
ulimit -t حداکثر زمان استفاده از CPU (ثانیه)
ulimit -l حداکثر میزان حافظه قابل قفل شدن در RAM

بررسی مقدار فعلی

داخل هر ترمینال جدید مقدار پیشفرض رو ببینید:

ulimit -n

خروجی معمولاً مقدار زیر است:

1024

تغییر موقت

تغییر مقدار محدودیت در یک نشست فعال:

ulimit -n 65535

این تغییر فقط در همان نشست معتبر است و پس از خروج یا راه‌اندازی مجدد از بین می‌رود.

تغییر دائمی

برای اعمال محدودیت‌ها به‌صورت دائمی باید از فایل‌های پیکربندی استفاده شود. در 4 حالت مختلف این مورد را بررسی خواهیم کرد:

1. در سطح تمام کاربران و نشست (PAM):
فایل‌های زیر:

nano /etc/security/limits.conf

nano /etc/security/limits.d/*.conf

به عنوان مثال مقادیر زیر وارد شود:

* soft nofile 65535
* hard nofile 65535

2. برای یک کاربر خاص میتوان به شکل زیر عمل کرد:

در فایل‌های زیر:

nano /etc/security/limits.conf

nano /etc/security/limits.d/*.conf

به طور مثال مقادیر زیر وارد شود:

username soft nofile 65535
username hard nofile 65535

همچنین باید اطمینان حاصل شود که در فایل‌های PAM مانند

 /etc/pam.d/common-session  و /etc/pam.d/common-session-noninteractive 

خط زیر وجود داشته باشد:

session required pam_limits.so

3. در سطح سرویس‌های systemd:

در نظر داشته باشید که Systemd به صورت پیشفرض مقادیر limits.conf رو برای سرویس‌ها اعمال نمی‌کند.
برای اینکه همه‌ی سرویس‌ها مقدار جدید بگیرند:

برای همه سرویس‌ها فایل های زیر ویرایش گردد:

nano /etc/systemd/system.conf
nano /etc/systemd/user.conf

مقدار زیر وارد گردد:

DefaultLimitNOFILE=65535

پس از تغییر ذخیره و کد زیر برای ریلود وارد شود:

sudo systemctl daemon-reexec

4. برای یک سرویس مشخص:

فایل سرویس مدنظر ویرایش می کنیم:

sudo systemctl edit service-name.service

و سپس مقدار زیر اضافه شود:

[Service]
LimitNOFILE=65535

پس از تغییر ذخیره و کدهای زیر وارد شود:

sudo systemctl daemon-reexec
sudo systemctl restart service-name

5. تست تغییرات

  • برای session جدید از کد زیر میتوانید استفاده کنید:

ulimit -n

  • برای سرویس systemd مثلاً (Asterisk):

sudo systemctl show asterisk | grep NOFILE

باید ببینید:

LimitNOFILE=65535


ملاحظات

  • تنظیم مقادیر بیش از اندازه نیاز می‌تواند منجر به مصرف بالای منابع هسته (Kernel) شود.

  • مقادیر مناسب باید متناسب با نوع سرویس انتخاب شوند به‌عنوان مثال برای Asterisk، Nginx یا دیتابیس‌ها معمولاً 32768 یا 65535 توصیه می‌شود.

  • تغییر در ulimit برای نشست‌های پوسته روی سرویس‌های systemd تأثیری ندارد و باید به‌طور مستقل در systemd پیکربندی شود.


نتیجه‌گیری

ابزار ulimit ابزاری اساسی در مدیریت منابع سیستم است که امکان کنترل رفتار فرایندها را در برابر استفاده بیش‌ازحد از منابع فراهم می‌سازد. برای تغییر موقت می‌توان از دستور مستقیم استفاده کرد، اما برای اعمال دائمی باید از ترکیب فایل‌های پیکربندی PAM و systemd استفاده شود.

2 پسندیده