وقتی رم سرور لینوکس تمام میشود، کرنل با OOM Killer یکی از پروسهها (اغلب دیتابیس یا برنامهٔ اصلی) را میکشد و سایت با خطای 502 یا قطعی روبهرو میشود. ابتدا با free -h و htop مصرف را ببینید، با dmesg رخداد OOM را تأیید کنید، پروسهٔ پرمصرف را پیدا و محدود کنید، یک swap کوچک بسازید و اگر مصرف واقعی بیشتر از رم است، پلن بزرگتر بسازید.
نشانهها
- سایت یا سرویس ناگهان قطع میشود و پس از ریاستارت درست میشود.
- در لاگ Nginx خطای 502 یا
connection refusedبه پروسهٔ پشتی دیده میشود. - دیتابیس (MySQL/PostgreSQL) بیدلیل متوقف شده است.
- SSH بسیار کند است یا گاهی وصل نمیشود.
گام ۱: وضعیت فعلی رم
free -h
نمونه:
total used free shared buff/cache available
Mem: 1.9Gi 1.6Gi 80Mi 20Mi 250Mi 150Mi
Swap: 0B 0B 0B
- ستون available مهم است، نه free. لینوکس رم آزاد را برای کش دیسک (buff/cache) استفاده میکند و در صورت نیاز آزاد میکند.
- available زیر ۱۰ درصد کل و Swap صفر = خطر OOM.
گام ۲: تأیید OOM Killer
sudo dmesg -T | grep -iE "out of memory|killed process" | tail
sudo journalctl -k --since "24 hours ago" | grep -i oom
خروجی مانند Out of memory: Killed process 1234 (mysqld) یعنی کرنل همان پروسه را بهخاطر کمبود رم کشته است.
$ dmesg -T | grep -i 'killed process'Out of memory: Killed process 1234 (python3)$ journalctl -k | grep -i oom$
گام ۳: پیدا کردن پروسههای پرمصرف
# ۱۵ پروسهٔ پرمصرف بر اساس رم
ps aux --sort=-%mem | head -15
# مجموع مصرف بر اساس نام برنامه (مثلاً همهٔ php-fpm ها)
ps -eo comm,rss --sort=-rss | awk '{a[$1]+=$2} END {for (i in a) printf "%-20s %6.0f MB\n", i, a[i]/1024}' | sort -k2 -nr | head
# در داکر
docker stats --no-stream
گام ۴: ساخت swap (کمک اضطراری)
swap فضایی روی دیسک است که وقتی رم پر شود استفاده میشود. کندتر از رم است، اما جلوی کشته شدن ناگهانی پروسهها را میگیرد:
sudo fallocate -l 1G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab
# استفادهٔ محافظهکارانه از swap
echo 'vm.swappiness=10' | sudo tee /etc/sysctl.d/99-swap.conf
sudo sysctl --system
برای سرورهای ۱ تا ۲ گیگ رم، swap یک تا دو گیگ مناسب است. اگر swap مدام پر است، رم واقعاً کم است.
$ sudo fallocate -l 2G /swapfile$ sudo chmod 600 /swapfile$ sudo mkswap /swapfile && sudo swapon /swapfile$ echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab$
گام ۵: محدود کردن برنامههای پرمصرف
MySQL / MariaDB
مهمترین تنظیم، innodb_buffer_pool_size است. روی سرورهایی که دیتابیس و وبسرور با هم اجرا میشوند، حدود ۲۵ تا ۴۰ درصد رم کافی است:
# /etc/mysql/mariadb.conf.d/60-tuning.cnf (مسیر بسته به نسخه)
[mysqld]
innodb_buffer_pool_size = 512M
max_connections = 50
PHP-FPM
هر پروسهٔ PHP-FPM معمولاً دهها مگابایت رم میگیرد. pm.max_children را بر اساس رم آزاد تقسیم بر مصرف هر پروسه تنظیم کنید:
; /etc/php/8.3/fpm/pool.d/www.conf
pm = dynamic
pm.max_children = 10
pm.start_servers = 2
pm.min_spare_servers = 2
pm.max_spare_servers = 4
Node.js و Python
- تعداد worker ها (PM2 cluster، Gunicorn workers) را با رم هماهنگ کنید.
- نشت حافظه (Memory leak) را با پایش مصرف در طول زمان تشخیص دهید؛ اگر مصرف مدام بالا میرود و پایین نمیآید، نشت وجود دارد.
داکر
برای هر کانتینر سقف رم بگذارید تا یک کانتینر کل سرور را از کار نیندازد:
services:
app:
image: myapp
mem_limit: 512m
گام ۶: ریاستارت خودکار سرویسها
حتی با تنظیمات درست، بهتر است سرویسها پس از کرش خودکار بالا بیایند:
sudo systemctl edit mariadb
[Service]
Restart=on-failure
RestartSec=5
در داکر از restart: unless-stopped استفاده کنید.
کی پلن بزرگتر لازم است؟
اگر پس از بهینهسازیها همچنان available در ساعات عادی زیر ۱۵ درصد است یا swap بهطور پیوسته استفاده میشود، رم واقعاً کم است. جدول انتخاب رم و پردازنده کمک میکند پلن مناسب را انتخاب کنید. با صورتحساب ساعتی، سرور بزرگتر را بسازید، دادهها را منتقل و سرور قبلی را حذف کنید.
| پلن | پردازنده | رم | دیسک | ساعتی (تومان) | ماهانه تقریبی (تومان) | |
|---|---|---|---|---|---|---|
| IR-۱ | ۱ هسته | ۱ گیگابایت | ۱۰ گیگابایت | ۱٬۲۰۰ | ۸۷۶٬۰۰۰ | ساخت |
| IR-۲ | ۲ هسته | ۲ گیگابایت | ۱۵ گیگابایت | ۲٬۱۰۰ | ۱٬۵۳۳٬۰۰۰ | ساخت |
| IR-۳ | ۲ هسته | ۴ گیگابایت | ۲۰ گیگابایت | ۳٬۰۰۰ | ۲٬۱۹۰٬۰۰۰ | ساخت |
| IR-۴ | ۴ هسته | ۴ گیگابایت | ۳۰ گیگابایت | ۴٬۲۰۰ | ۳٬۰۶۶٬۰۰۰ | ساخت |
| IR-۵ | ۴ هسته | ۸ گیگابایت | ۵۰ گیگابایت | ۶٬۵۰۰ | ۴٬۷۴۵٬۰۰۰ | ساخت |
| IR-۶ | ۸ هسته | ۱۶ گیگابایت | ۱۰۰ گیگابایت | ۱۲٬۹۰۰ | ۹٬۴۱۷٬۰۰۰ | ساخت |
قیمتها زنده از سامانهٔ کلودیفای در تاریخ ۱۱ آبان ۱۴۰۵ خوانده شدهاند. ترافیک دانلود جداگانه، هر گیگابایت ۱٬۲۵۰ تومان؛ آپلود رایگان.
سؤالات متداول
چرا لینوکس رم را «پر» نشان میدهد در حالی که مشکلی نیست؟
لینوکس رم آزاد را برای کش دیسک استفاده میکند. ستون available نشان میدهد واقعاً چقدر رم برای برنامهها در دسترس است.
swap روی SSD به دیسک آسیب میزند؟
با swappiness پایین و استفادهٔ گاهبهگاه، اثر قابلتوجهی ندارد. swap دائماً پر نشانهٔ کمبود رم است، نه راهحل.
OOM Killer کدام پروسه را میکشد؟
معمولاً پروسهای که بیشترین رم را دارد (امتیاز oom_score بالاتر)؛ به همین دلیل اغلب دیتابیس قربانی میشود.
میتوانم از کشته شدن یک پروسهٔ مهم جلوگیری کنم؟
با OOMScoreAdjust=-500 در سرویس systemd میتوانید احتمال آن را کم کنید، اما بهتر است علت کمبود رم را رفع کنید.
از ۱٬۲۰۰ تومان در ساعت · پرداخت ریالی



