مجله ایرانیکاسرورآموزش سرور، هاست، وردپرس و شبکه
آموزشی

اجرای چند گیم سرور روی یک VPS؛ آموزش جداسازی CPU و RAM و جلوگیری از خرابی بازی‌ها

آیا می‌توان چند گیم سرور را هم‌زمان روی یک VPS اجرا کرد؟ بله. برای مثال، می‌توانید روی یک سرور مجازی لینوکسی، سرور Minecraft و Counter-Strike 2 را در کنار یکدیگر راه‌اندازی کنید. اما اگر…

اجرای چند گیم سرور روی یک VPS؛ آموزش جداسازی CPU و RAM و جلوگیری از خرابی بازی‌ها
خلاصه سریع این آموزش

آیا می‌توان چند گیم سرور را هم‌زمان روی یک VPS اجرا کرد؟ بله. برای مثال، می‌توانید روی یک سرور مجازی لینوکسی، سرور Minecraft و Counter-Strike 2 را در کنار یکدیگر…

۳۵ دقیقه مطالعه ۰ دیدگاه ۱۲ آبان ۱۴۰۵ آخرین به‌روزرسانی

فهرست مطالب

آیا می‌توان چند گیم سرور را هم‌زمان روی یک VPS اجرا کرد؟ بله. برای مثال، می‌توانید روی یک سرور مجازی لینوکسی، سرور Minecraft و Counter-Strike 2 را در کنار یکدیگر راه‌اندازی کنید. اما اگر منابع آن‌ها را مدیریت نکنید، ممکن است افزایش مصرف RAM یک بازی باعث بسته شدن بازی دیگر شود یا فشار CPU یکی از سرورها، تجربه تمام بازیکنان را مختل کند.

راه‌حل این مشکل فقط خرید VPS با RAM بیشتر نیست. باید هر گیم سرور را به‌عنوان یک سرویس مستقل اجرا کنید، برای مصرف CPU و حافظه محدودیت مناسب در نظر بگیرید، پورت‌ها و فایل‌های آن‌ها را جدا نگه دارید و برای هر بازی سیستم پایش و Backup مستقل داشته باشید.

در این مقاله به‌صورت عملی یاد می‌گیرید چگونه چند گیم سرور روی VPS اجرا کنید؛ به شکلی که خرابی یک بازی تا حد امکان روی بازی‌های دیگر تأثیر نگذارد. برای این کار، قابلیت‌های systemd، کنترل منابع با cgroups v2، روش CPU Affinity، کانتینرهای Docker، تنظیم Firewall و پایش منابع را بررسی می‌کنیم.

این آموزش برای مدیریت هم‌زمان بازی‌هایی مانند Minecraft، CS2، Valheim و سایر Dedicated Serverهای لینوکسی کاربرد دارد؛ البته روش نصب و اجرای اولیه هر بازی باید مطابق مستندات خود آن انجام شده باشد.

چرا اجرای چند گیم سرور روی یک VPS باعث کندی یا خرابی می‌شود؟

وقتی چند Dedicated Server روی یک سیستم‌عامل اجرا می‌شوند، همه آن‌ها از منابع مشترک استفاده می‌کنند. این منابع شامل پردازنده، حافظه RAM، دیسک و شبکه است.

اگر هیچ محدودیتی تعریف نشده باشد، یک بازی می‌تواند بخش زیادی از منابع موجود را مصرف کند. برای مثال، سرور Minecraft هنگام بارگذاری Chunkهای جدید یا اجرای Modهای سنگین ممکن است به CPU و حافظه بیشتری نیاز پیدا کند. هم‌زمان، اگر سرور CS2 در حال برگزاری یک مسابقه باشد، فشار روی پردازنده می‌تواند باعث افزایش تأخیر پردازش در بازی شود.

چهار نوع تداخل رایج بین گیم سرورها

  • تداخل CPU: یک بازی زمان پردازنده زیادی مصرف می‌کند و سایر بازی‌ها دیرتر پردازش می‌شوند.
  • فشار حافظه: مصرف RAM افزایش پیدا می‌کند و سیستم وارد وضعیت Memory Pressure یا OOM می‌شود.
  • تداخل دیسک: Backup، استخراج فایل یا دانلود آپدیت باعث افزایش تأخیر خواندن و نوشتن داده‌های سایر بازی‌ها می‌شود.
  • تداخل شبکه: استفاده از پورت یکسان یا افزایش ترافیک باعث اختلال در اتصال بازیکنان می‌شود.

همچنین اگر تمام بازی‌ها را با یک کاربر Linux اجرا کنید، خرابی یا دسترسی غیرمجاز در یکی از آن‌ها ممکن است فایل‌های بازی دیگر را نیز در معرض خطر قرار دهد.

آیا افزایش RAM به‌تنهایی کافی است؟

خیر. RAM بیشتر می‌تواند فضای بیشتری برای پردازش فراهم کند، اما مشکل تداخل CPU، مصرف دیسک، تداخل پورت و دسترسی به فایل‌ها را حل نمی‌کند.

برای داشتن یک VPS چندبازی پایدار، باید علاوه بر انتخاب منابع کافی، برای هر سرویس محدوده مشخصی از مصرف منابع تعریف کنید.

برای اجرای هم‌زمان چند گیم سرور چقدر RAM و CPU نیاز داریم؟

هیچ عدد ثابتی برای تعداد بازی‌های قابل اجرا روی یک VPS وجود ندارد. یک سرور Minecraft سبک با چند بازیکن ممکن است مصرف بسیار متفاوتی نسبت به یک سرور دارای صدها Mod داشته باشد. همین موضوع درباره CS2، Valheim و سایر بازی‌ها نیز صدق می‌کند.

بهترین روش، اندازه‌گیری مصرف واقعی هر سرور در شرایط شلوغ و سپس محاسبه مجموع آن‌ها همراه با منابع موردنیاز سیستم‌عامل است.

فرمول ساده برنامه‌ریزی حافظه

برای تخمین RAM موردنیاز می‌توانید از رابطه زیر استفاده کنید:

RAM کل موردنیاز = مجموع حافظه اوج بازی‌ها + حافظه سیستم‌عامل و ابزارها + حاشیه اطمینان

مقادیر اوج مصرف را در زمان فعالیت واقعی بازیکنان اندازه‌گیری کنید؛ نه فقط چند دقیقه بعد از روشن شدن سرور.

همچنین توجه داشته باشید که سقف‌های MemoryMax الزاماً نشان‌دهنده مصرف واقعی نیستند. این سقف‌ها صرفاً میزان مصرف مجاز را محدود می‌کنند.

چرا باید مقداری RAM آزاد بماند؟

سیستم‌عامل، شبکه، SSH، سرویس‌های مدیریتی، حافظه کش فایل‌ها و ابزارهای مانیتورینگ نیز به منابع نیاز دارند. اگر تمام حافظه را به بازی‌ها اختصاص دهید، ممکن است خود VPS در زمان افزایش مصرف با مشکل مواجه شود.

به‌عنوان نقطه شروع می‌توانید در یک VPS کوچک حدود ۱۵ تا ۲۵ درصد ظرفیت حافظه را برای سیستم‌عامل و حاشیه اطمینان کنار بگذارید. این درصد یک قانون رسمی نیست و در سیستم‌های مختلف باید بر اساس مصرف واقعی تنظیم شود.

سناریوی عملی: اجرای Minecraft و CS2 روی یک VPS هشت گیگابایتی

فرض کنیم یک VPS با منابع زیر در اختیار داریم:

  • سیستم‌عامل Ubuntu 24.04 LTS
  • ۴ vCPU
  • ۸ گیگابایت RAM
  • فضای ذخیره‌سازی SSD یا NVMe
  • یک IPv4 عمومی

می‌خواهیم دو سرور Minecraft و Counter-Strike 2 را هم‌زمان اجرا کنیم و تا حد امکان مانع تأثیرگذاری مصرف یکی بر دیگری شویم.

نمونه تقسیم منابع

بخش سقف RAM نمونه سقف CPU نمونه پورت نمونه
Minecraft ۲٫۵ گیگابایت ۱۵۰٪ معادل حداکثر ۱٫۵ CPU 25565/TCP
Counter-Strike 2 ۳٫۵ گیگابایت ۲۰۰٪ معادل حداکثر ۲ CPU 27015/UDP
سیستم‌عامل و سایر مصرف‌ها ۲ گیگابایت باقی‌مانده ظرفیت باقیمانده و اشتراکی بر اساس سرویس‌ها

توجه: این جدول فقط یک نمونه برای توضیح نحوه تقسیم منابع است. مقدار حافظه موردنیاز CS2 یا Minecraft با توجه به نسخه، بازیکنان، نقشه‌ها و افزونه‌ها تغییر می‌کند. اگر بازی شما واقعاً به RAM بیشتری نیاز دارد، محدودیت خیلی پایین می‌تواند باعث کندی یا Crash شود.

همچنین CPUQuota ظرفیت CPU را رزرو نمی‌کند؛ فقط یک سقف مصرف تعیین می‌کند. در VPSهایی با vCPU اشتراکی، عملکرد نهایی به منابع فیزیکی و سیاست تخصیص پردازنده ارائه‌دهنده نیز وابسته است.

برای اجرای چند بازی، systemd بهتر است یا Docker؟

قبل از اعمال محدودیت منابع باید تصمیم بگیرید بازی‌ها چگونه اجرا شوند. انتخاب روش اجرا روی مدیریت، به‌روزرسانی، سازگاری و جداسازی سرویس‌ها تأثیر مستقیم دارد.

ویژگی systemd + cgroups Docker Compose VPS جداگانه
مدیریت CPU و RAM بله بله در سطح هر VPS
جداسازی محیط اجرایی محدودتر؛ با کاربران و Sandbox بیشتر؛ با Namespace و cgroups قوی‌تر؛ مرز ماشین مجازی
نیاز به تصویر کانتینری سازگار خیر بله خیر
مدیریت سرویس systemctl docker compose مستقل روی هر VPS
مدیریت پورت مستقیم روی میزبان با Docker Networking مستقل بر اساس IP و شبکه
اثر خرابی کامل سیستم‌عامل میزبان همه بازی‌ها آسیب می‌بینند همه بازی‌ها آسیب می‌بینند محدود به VPS آسیب‌دیده
مناسب برای سرورهای نصب‌شده مستقیم استقرارهای کانتینری سازگار بازی‌های مهم و مستقل

چه زمانی systemd انتخاب بهتری است؟

اگر بازی را قبلاً با SteamCMD یا نصب‌کننده معمول Linux نصب کرده‌اید و برای آن یک سرویس systemd دارید، معمولاً نیازی نیست صرفاً برای جداسازی منابع آن را به Docker منتقل کنید.

systemd به کمک cgroups می‌تواند مصرف CPU، RAM و تعداد پردازش‌ها را کنترل کند و پس از خرابی، سرویس را بر اساس سیاست تعریف‌شده مجدداً اجرا کند.

چه زمانی Docker مناسب‌تر است؟

اگر برای بازی موردنظر یک Docker Image قابل اعتماد، سازگار و قابل نگهداری وجود دارد، Docker Compose می‌تواند مدیریت چند سرویس و جداسازی محیط اجرای آن‌ها را ساده‌تر کند.

اما Docker به‌تنهایی منابع را محدود نمی‌کند. باید محدودیت‌هایی مانند cpus و mem_limit را تنظیم کنید.

چه زمانی VPS جداگانه لازم است؟

اگر دو بازی برای کسب‌وکار شما مهم هستند و قطع شدن هم‌زمان آن‌ها قابل قبول نیست، دو VPS مستقل انتخاب مطمئن‌تری است.

حتی با بهترین تنظیمات systemd یا Docker، خرابی Kernel، قطع شدن شبکه اصلی VPS، پر شدن کامل دیسک میزبان یا خاموش شدن ماشین مجازی می‌تواند تمام بازی‌های همان VPS را تحت تأثیر قرار دهد.

بررسی پیش‌نیازهای لینوکس قبل از جداسازی منابع

دستورهای این بخش برای Ubuntu 24.04 نوشته شده‌اند. قبل از تغییر تنظیمات یک سرور فعال، از سرویس‌های موجود Backup بگیرید و دسترسی مدیریتی جایگزین برای مواقع اضطراری داشته باشید.

بررسی تعداد پردازنده‌های قابل مشاهده

nproc
lscpu

بررسی حافظه و فضای ذخیره‌سازی

free -h
df -h
lsblk

بررسی نسخه systemd

systemctl --version

بررسی فعال بودن cgroups v2

findmnt -no FSTYPE /sys/fs/cgroup

در سیستمی که از ساختار یکپارچه cgroups v2 استفاده می‌کند، خروجی معمولاً چنین است:

cgroup2

تنظیماتی مانند AllowedCPUs و کنترل حافظه جدید systemd به پشتیبانی مناسب cgroups v2 نیاز دارند.

اگر خروجی متفاوت بود، بدون بررسی ساختار cgroup و وضعیت Kernel، تنظیمات این آموزش را کورکورانه اعمال نکنید.

مرحله اول: جداسازی فایل‌ها و کاربران هر گیم سرور

اولین اصل این است که هر بازی، مسیر فایل‌ها و حساب اجرایی مشخص خود را داشته باشد.

برای مثال، یک ساختار پیشنهادی می‌تواند به شکل زیر باشد:

/srv/games/
├── minecraft/
│   ├── server.jar
│   ├── server.properties
│   ├── world/
│   └── logs/
└── cs2/
    ├── game/
    ├── config/
    └── logs/

این ساختار مفهومی است؛ محل واقعی فایل‌ها به موتور بازی و روش نصب بستگی دارد. اگر سرورهای شما اکنون در مسیر دیگری نصب شده‌اند، برای اجرای این آموزش لازم نیست آن‌ها را جابه‌جا کنید.

چرا استفاده از کاربر Linux جداگانه مهم است؟

اگر هر دو بازی تحت یک حساب کاربری اجرا شوند، فرآیندهای آن حساب ممکن است به فایل‌های هر دو سرور دسترسی داشته باشند.

با تعریف حساب‌های مستقل، می‌توانید مالکیت و مجوز فایل‌ها را جدا کنید. به این ترتیب دسترسی یک بازی به فایل‌های خصوصی بازی دیگر محدودتر می‌شود.

برای نصب جدید، می‌توان از حساب‌هایی مانند game-mc و game-cs2 استفاده کرد؛ اما اگر سرویس فعلی شما با کاربر مشخصی کار می‌کند، تغییر حساب اجرایی را بدون بررسی مالکیت فایل‌ها و مسیرهای SteamCMD انجام ندهید.

جداسازی Log و Backup

برای هر سرور، مسیر مستقل لاگ و پشتیبان داشته باشید:

/var/backups/games/minecraft/
/var/backups/games/cs2/

بهتر است پوشه Backup از نظر سطح دسترسی محافظت شود و یک نسخه دیگر در فضای ذخیره‌سازی مستقل از VPS نگهداری شود.

مرحله دوم: جداسازی سرویس‌ها با systemd

فرض می‌کنیم Minecraft و CS2 قبلاً نصب شده‌اند و سرویس‌های مستقل دارند. در این بخش، بدون تغییر دستور اجرای خود بازی‌ها، محدودیت منابع آن‌ها را تنظیم می‌کنیم.

برای مثال، نام سرویس‌ها را minecraft.service و cs2.service در نظر می‌گیریم. اگر سرویس‌های فعلی شما نام دیگری دارند، در تمام دستورها همان نام واقعی را استفاده کنید.

بررسی سرویس‌های موجود

systemctl list-units --type=service --all

قبل از ویرایش، تنظیمات فعلی هر سرویس را مشاهده و در یک فایل ذخیره کنید:

sudo systemctl cat minecraft.service
sudo systemctl cat cs2.service

ساخت Slice مشترک برای بازی‌ها

در systemd می‌توان سرویس‌های مرتبط را داخل یک Slice قرار داد تا مصرف گروهی آن‌ها آسان‌تر مشاهده شود.

فایل زیر را ایجاد کنید:

sudo nano /etc/systemd/system/games.slice

محتوای زیر را وارد کنید:

[Unit]
Description=Game Servers Slice

[Slice]
CPUAccounting=yes
MemoryAccounting=yes
IOAccounting=yes
TasksAccounting=yes

این تنظیمات امکان حسابداری مصرف منابع را فراهم می‌کنند. هنوز هیچ سقف سختی برای مصرف کل بازی‌ها تعریف نشده است.

عمداً در این مرحله برای games.slice مقدار MemoryMax مشترک قرار نمی‌دهیم؛ زیرا می‌خواهیم برای هر سرویس محدودیت مستقل داشته باشیم و بدون بررسی دقیق، یک سقف حافظه مشترک جدید به همه بازی‌ها تحمیل نکنیم.

ویرایش امن با Drop-in

به‌جای بازنویسی فایل اصلی سرویس، از دستور systemctl edit استفاده کنید. این روش تغییرات شما را در فایل جداگانه‌ای ذخیره می‌کند و معمولاً هنگام آپدیت فایل سرویس اصلی بهتر قابل نگهداری است.

sudo systemctl edit minecraft.service

در ویرایشگر بازشده، تنظیمات اختصاصی Minecraft را مطابق بخش بعدی وارد کنید.

مرحله سوم: محدود کردن RAM هر گیم سرور با MemoryHigh و MemoryMax

در Linux مدرن می‌توان محدودیت حافظه را با systemd و cgroups تعریف کرد.

دو گزینه مهم در این بخش عبارت‌اند از MemoryHigh و MemoryMax.

تفاوت MemoryHigh و MemoryMax

تنظیم رفتار کاربرد
MemoryHigh افزایش فشار بازپس‌گیری حافظه و کند شدن فرآیند هنگام عبور از آستانه کنترل نرم‌تر مصرف RAM
MemoryMax سقف سخت مصرف حافظه؛ ممکن است به OOM منجر شود آخرین خط دفاعی در برابر مصرف بی‌رویه
MemorySwapMax محدود کردن Swap مصرفی سرویس کنترل استفاده از حافظه مبادله‌ای

طبق مستندات systemd و Kernel، عبور از MemoryHigh به‌خودی‌خود باعث اجرای OOM Killer نمی‌شود؛ اما عبور از MemoryMax، در صورت ناتوانی سیستم در آزادسازی حافظه، می‌تواند باعث خاتمه فرآیندهای داخل cgroup شود.

تنظیم نمونه برای Minecraft

در فایل Drop-in مربوط به minecraft.service، نمونه زیر را قرار دهید:

[Unit]
StartLimitIntervalSec=120
StartLimitBurst=3

[Service]
Slice=games.slice
CPUAccounting=yes
MemoryAccounting=yes
IOAccounting=yes

CPUQuota=150%
MemoryHigh=2G
MemoryMax=2500M
TasksMax=1024

OOMPolicy=kill
Restart=on-failure
RestartSec=15s

این تنظیمات باعث می‌شوند مصرف حافظه Minecraft ابتدا در آستانه ۲ گیگابایت تحت فشار کنترل قرار بگیرد و در محدوده سخت ۲۵۰۰ مگابایت محدود شود.

اگر سرور Minecraft با Java اجرا می‌شود، تنظیم Xmx باید با در نظر گرفتن حافظه خارج از Heap، مانند Metaspace، Threadها و Native Memory انجام شود. برای مثال، اختصاص Xmx برابر کل MemoryMax می‌تواند باعث OOM شود.

مقادیر این نمونه باید با Modpack و مصرف واقعی سرور هماهنگ شوند.

تنظیم نمونه برای Counter-Strike 2

سرویس CS2 را نیز با نام واقعی آن ویرایش کنید:

sudo systemctl edit cs2.service

نمونه تنظیمات:

[Unit]
StartLimitIntervalSec=120
StartLimitBurst=3

[Service]
Slice=games.slice
CPUAccounting=yes
MemoryAccounting=yes
IOAccounting=yes

CPUQuota=200%
MemoryHigh=3G
MemoryMax=3500M
TasksMax=1024

OOMPolicy=kill
Restart=on-failure
RestartSec=15s

در این مثال، سقف RAM سرویس CS2 برابر ۳۵۰۰ مگابایت است. این عدد یک مقدار پیشنهادی برای مثال ۸ گیگابایتی است و الزاماً برای تمام سرورهای CS2 مناسب نیست.

اعمال تغییرات

پس از ذخیره هر دو فایل:

sudo systemctl daemon-reload
sudo systemd-analyze verify minecraft.service cs2.service

ابتدا خطاهای احتمالی را رفع کنید. سپس در یک زمان مناسب، سرویس‌ها را جداگانه Restart کنید تا تنظیمات جدید روی فرآیندهای اجرایی اعمال شوند:

sudo systemctl restart minecraft.service
sudo systemctl status minecraft.service --no-pager

پس از تأیید سلامت Minecraft، همین کار را برای CS2 انجام دهید:

sudo systemctl restart cs2.service
sudo systemctl status cs2.service --no-pager

اگر سرویس‌های فعلی از نوع oneshot هستند یا اسکریپت اجرای آن‌ها فرآیند اصلی را به پس‌زمینه می‌فرستد، ابتدا روش اجرای سرویس را بررسی کنید. سیاست Restart در چنین ساختارهایی ممکن است مطابق انتظار عمل نکند.

تأیید محدودیت‌های اعمال‌شده

systemctl show minecraft.service \
-p Slice -p CPUQuotaPerSecUSec \
-p MemoryHigh -p MemoryMax -p OOMPolicy

systemctl show cs2.service \
-p Slice -p CPUQuotaPerSecUSec \
-p MemoryHigh -p MemoryMax -p OOMPolicy

خروجی‌ها را با مقادیر مورد انتظار مقایسه کنید. اگر سرویس در یک Slice دیگر قرار دارد یا محدودیت نمایش داده نمی‌شود، فایل‌های Drop-in و نسخه systemd را بررسی کنید.

مرحله چهارم: جلوگیری از مصرف بیش از حد CPU با CPUQuota و CPU Affinity

پردازنده یکی از منابع مهم برای گیم سرورها است؛ زیرا تأخیر پردازش می‌تواند به شکل Lag، Tick Delay یا کاهش پاسخ‌گویی سرور ظاهر شود.

در systemd دو روش مهم برای کنترل پردازنده وجود دارد: CPUQuota و AllowedCPUs.

CPUQuota چیست؟

CPUQuota حداکثر زمان پردازنده‌ای را مشخص می‌کند که یک سرویس می‌تواند در هر بازه زمانی مصرف کند.

در systemd مقدار ۱۰۰٪ معادل ظرفیت زمانی یک CPU منطقی است. بنابراین:

  • CPUQuota=100% یعنی حداکثر معادل یک CPU منطقی.
  • CPUQuota=150% یعنی حداکثر معادل ۱٫۵ CPU منطقی.
  • CPUQuota=200% یعنی حداکثر معادل دو CPU منطقی.

این درصدها تضمین نمی‌کنند CPU همیشه در اختیار بازی باشد؛ بلکه سقف مصرف تعیین می‌کنند.

CPU Affinity یا AllowedCPUs چیست؟

CPU Affinity مشخص می‌کند یک سرویس اجازه اجرا روی کدام CPUهای منطقی را داشته باشد.

برای مثال، اگر VPS دارای چهار CPU منطقی با شماره‌های ۰ تا ۳ باشد، می‌توانید برای Minecraft از تنظیم زیر استفاده کنید:

AllowedCPUs=0-1

و برای CS2:

AllowedCPUs=2-3

این گزینه را می‌توانید در بخش Service همان فایل Drop-in اضافه کنید.

آیا همیشه باید CPUها را جدا کنیم؟

خیر. CPU Affinity همیشه باعث افزایش عملکرد نمی‌شود. اگر یک بازی فقط روی دو CPU مجاز باشد و هر دو درگیر شوند، ممکن است با وجود ظرفیت آزاد روی CPUهای دیگر، آن بازی دچار تأخیر شود.

برای بسیاری از VPSهای کوچک، بهتر است ابتدا فقط CPUQuota و MemoryMax را تنظیم کنید و CPU Affinity را پس از بررسی مصرف و آزمایش عملکرد به کار ببرید.

همچنین در VPSهایی با vCPU اشتراکی، AllowedCPUs به معنی اختصاص یک هسته فیزیکی مستقل از سایر مشتریان نیست.

چطور بفهمیم CPU محدود شده است؟

ابتدا مصرف پردازنده سرویس‌ها را از طریق systemd-cgtop بررسی کنید. برای تشخیص دقیق‌تر، آمار Throttling مربوط به cgroup در فایل cpu.stat قابل مشاهده است.

می‌توانید مسیر cgroup سرویس را مشاهده کنید:

systemctl show minecraft.service -p ControlGroup

سپس در مسیر متناظر داخل /sys/fs/cgroup فایل cpu.stat را بررسی کنید. افزایش مداوم شاخص‌های Throttling همراه با افت عملکرد بازی می‌تواند نشانه پایین بودن بیش از حد CPUQuota باشد.

روش جایگزین: اجرای چند گیم سرور با Docker Compose

اگر بازی‌های موردنظر شما Docker Image سازگار و قابل اعتماد دارند، می‌توانید هر بازی را به‌صورت یک سرویس مستقل در Docker Compose اجرا کنید.

مزیت این روش، جدا بودن محیط اجرایی، مدیریت Volumeها و قابلیت استقرار مجدد کانتینرها است.

با این حال، قبل از استفاده از هر Image باید مشخص کنید آیا سازنده بازی از اجرای کانتینری پشتیبانی می‌کند و آیا Image موردنظر به‌روزرسانی و نگهداری می‌شود یا خیر.

نمونه ساختار Docker Compose

نمونه زیر نحوه تعریف دو بازی با محدودیت متفاوت RAM و CPU را نشان می‌دهد. نام Imageها نمونه هستند و باید با Image واقعی، سازگار و بررسی‌شده هر بازی جایگزین شوند.

services:
  minecraft:
    image: YOUR_TESTED_MINECRAFT_IMAGE:PINNED_TAG
    restart: unless-stopped
    cpus: "1.5"
    mem_limit: 2500m
    mem_reservation: 2g
    pids_limit: 1024
    ports:
      - "25565:25565/tcp"
    volumes:
      - ./minecraft-data:/data

  cs2:
    image: YOUR_TESTED_CS2_IMAGE:PINNED_TAG
    restart: unless-stopped
    cpus: "2.0"
    mem_limit: 3500m
    mem_reservation: 3g
    pids_limit: 1024
    ports:
      - "27015:27015/udp"
    volumes:
      - ./cs2-data:/data

این فایل یک الگوی آموزشی است، نه پیکربندی آماده اجرای هر Image. مسیر /data، متغیرهای محیطی، دستور اجرای سرور و پورت‌های لازم باید مطابق مستندات Image واقعی اصلاح شوند.

برای مثال، برخی Imageهای Minecraft به پذیرش EULA و تنظیمات اختصاصی Java نیاز دارند. کانتینر CS2 نیز ممکن است به تنظیمات اضافی شبکه، SteamCMD و پورت‌های موردنیاز سرویس‌های خود احتیاج داشته باشد.

معنی تنظیمات مهم Docker

  • cpus: حداکثر CPU قابل استفاده کانتینر را محدود می‌کند.
  • mem_limit: سقف سخت حافظه کانتینر را تعریف می‌کند.
  • mem_reservation: یک آستانه نرم برای حافظه است، نه تضمین رزرو RAM.
  • pids_limit: تعداد پردازش‌ها و Threadهای قابل ایجاد را محدود می‌کند.
  • restart: سیاست تلاش برای اجرای مجدد کانتینر را مشخص می‌کند.
  • volumes: داده‌های مهم بازی را خارج از چرخه عمر کانتینر نگه می‌دارد.
  • ports: پورت کانتینر را روی میزبان منتشر می‌کند.

آیا Docker کاملاً از مصرف بیش از حد RAM جلوگیری می‌کند؟

Docker می‌تواند سقف حافظه تعیین کند، اما اگر بازی به حافظه بیشتری نیاز داشته باشد، ممکن است در همان کانتینر با OOM مواجه شود. بنابراین محدودیت باید بر اساس اندازه‌گیری واقعی مصرف تنظیم شود.

همچنین نباید برای حل مشکل حافظه، OOM Killer را بدون شناخت پیامدها غیرفعال کنید.

چرا Docker همیشه بهترین انتخاب نیست؟

بعضی بازی‌ها در محیط کانتینری نیازمند تنظیمات خاص هستند. همچنین انتقال یک سرور موجود به Docker ممکن است مسیر Save، مجوز فایل‌ها، اسکریپت‌های آپدیت یا تنظیمات Firewall را تغییر دهد.

اگر سرور فعلی با systemd به‌خوبی کار می‌کند، استفاده از systemd و cgroups اغلب ساده‌تر از مهاجرت غیرضروری به Docker است.

مرحله پنجم: جلوگیری از تداخل پورت چند گیم سرور

در یک VPS با یک IP عمومی، می‌توانید چند بازی را هم‌زمان اجرا کنید؛ به شرط آنکه ترکیب آدرس IP، پورت و پروتکل سرویس‌ها با یکدیگر تداخل نداشته باشد.

مثال پورت دو بازی

بازی پورت نمونه پروتکل
Minecraft Java 25565 TCP
Counter-Strike 2 27015 UDP
Minecraft دوم 25566 TCP

این جدول فقط پورت‌های اصلی نمونه را نشان می‌دهد. هر بازی ممکن است برای Query، RCON، Bedrock یا امکانات دیگر به پورت‌های اضافی نیاز داشته باشد.

چطور پورت‌های اشغال‌شده را پیدا کنیم؟

sudo ss -lntup

برای بررسی دو پورت خاص:

sudo ss -lntup | grep -E ':25565|:27015'

خروجی را بررسی کنید تا مشخص شود هر پورت توسط چه فرآیندی استفاده می‌شود.

باز کردن پورت‌ها در UFW

اگر UFW از قبل فعال است و بازی‌ها مستقیماً روی میزبان اجرا می‌شوند، می‌توانید Ruleهای موردنیاز را اضافه کنید:

sudo ufw allow 25565/tcp
sudo ufw allow 27015/udp
sudo ufw status numbered

اگر پورت‌های فعلی متفاوت‌اند، همین دستورها را با پورت صحیح تغییر دهید. قبل از فعال‌سازی یا بازنشانی Firewall مطمئن شوید دسترسی SSH شما محفوظ است.

تداخل پورت در Docker

در Docker دو کانتینر می‌توانند داخل شبکه‌های مستقل از یک شماره پورت یکسان استفاده کنند؛ اما اگر هر دو بخواهند همان پورت و پروتکل را روی یک آدرس میزبان منتشر کنند، تداخل ایجاد می‌شود.

برای مثال، در صورت پشتیبانی Image از این روش، می‌توانید پورت داخلی 25565 کانتینر دوم Minecraft را به پورت خارجی 25566 متصل کنید:

ports:
  - "25566:25565/tcp"

این کار با تغییر پورت واقعی برنامه متفاوت است. اگر بازی باید آدرس یا پورت بیرونی خود را به سرویس دیگری معرفی کند، تنظیمات مربوط به آن نیز باید اصلاح شوند.

نکته امنیتی مهم درباره Docker و UFW

طبق مستندات Docker، انتشار پورت‌های کانتینر می‌تواند ترافیک را قبل از عبور از زنجیره‌های معمول UFW هدایت کند. بنابراین نباید تصور کنید هر پورتی که UFW مسدود کرده است، الزاماً برای کانتینر منتشرشده نیز بسته خواهد بود.

برای Docker از تنظیمات شبکه و Firewall سازگار با Docker استفاده کنید و دسترسی خارجی پورت‌ها را واقعاً آزمایش کنید. همچنین می‌توانید دسترسی‌ها را در Firewall شبکه ارائه‌دهنده VPS محدود کنید.

مرحله ششم: جلوگیری از دسترسی یک بازی به اطلاعات بازی دیگر

جداسازی CPU و RAM کافی نیست. برای جلوگیری از گسترش آسیب ناشی از یک افزونه خراب یا آسیب‌پذیر، سطح دسترسی بازی‌ها نیز باید محدود شود.

اجرای بازی‌ها بدون root

تا جای ممکن هر بازی را با کاربر غیرمدیر و مستقل اجرا کنید. اجرای دائمی سرور بازی با root باعث افزایش خطر در صورت اجرای کد مخرب یا آسیب‌پذیری می‌شود.

جدا بودن فایل‌های تنظیمات

رمز RCON، توکن Steam، اطلاعات اتصال پایگاه داده و کلیدهای خصوصی نباید برای تمام بازی‌ها در یک فایل مشترک و قابل دسترسی قرار بگیرند.

برای فایل‌های حساس، سطح دسترسی مناسب تعیین کنید و آن‌ها را در مخازن عمومی منتشر نکنید.

باز نکردن پورت مدیریتی برای همه کاربران اینترنت

پورت‌های بازی که باید برای بازیکنان عمومی در دسترس باشند با پورت‌های مدیریتی متفاوت‌اند.

در صورت امکان، دسترسی RCON و رابط مدیریتی را فقط از IPهای مشخص یا از طریق یک شبکه مدیریتی امن مجاز کنید.

آیا Docker یک مرز امنیتی کامل است؟

خیر. کانتینرهای Docker از Kernel میزبان استفاده می‌کنند و نباید آن‌ها را معادل ماشین مجازی مستقل دانست. برای سرویس‌های حساس، تنظیم مجوزهای کانتینر، Volumeها، قابلیت‌های Linux و دسترسی شبکه ضروری است.

مرحله هفتم: جلوگیری از زنجیره خرابی گیم سرورها

فرض کنید یکی از بازی‌ها به دلیل یک Mod خراب متوقف شده است. اگر مدیریت سرویس‌ها درست طراحی شده باشد، باید بتوانید همان بازی را بررسی و Restart کنید، بدون اینکه سایر بازی‌ها نیز مجبور به راه‌اندازی مجدد شوند.

تفاوت Restart مستقل با Restart کل VPS

برای راه‌اندازی مجدد فقط Minecraft:

sudo systemctl restart minecraft.service

و فقط برای CS2:

sudo systemctl restart cs2.service

این روش فقط زمانی مستقل عمل می‌کند که وابستگی‌های اجباری میان سرویس‌ها تعریف نکرده باشید و هر سرویس فرآیند اصلی خودش را به‌درستی مدیریت کند.

چرا Restart نامحدود خطرناک است؟

اگر یک بازی بلافاصله بعد از اجرا Crash کند و سرویس بدون توقف دوباره و دوباره اجرا شود، ممکن است CPU، دیسک و Logها تحت فشار قرار بگیرند.

گزینه‌های StartLimitIntervalSec و StartLimitBurst برای جلوگیری از تلاش‌های بی‌پایان در بازه زمانی کوتاه کاربرد دارند.

برای مثال، تنظیم نمونه این مقاله اجازه نمی‌دهد سرویس بدون محدودیت در هر ۱۲۰ ثانیه بارها Restart شود. پس از رسیدن به محدودیت، مدیر باید خطا را رفع و وضعیت سرویس را بررسی کند.

اگر بازی به سقف حافظه برسد چه می‌شود؟

ممکن است Kernel فرآیندهای همان cgroup را خاتمه دهد. گزینه OOMPolicy=kill به systemd کمک می‌کند هنگام وقوع OOM در سرویس، فرآیندهای مربوط به آن را به‌صورت گروهی مدیریت کند.

اما هیچ‌کدام از این تنظیمات تضمین نمی‌کنند که در شرایط فشار شدید حافظه یا اختلال Kernel، سایر سرویس‌ها هرگز آسیب نبینند.

آیا Swap مشکل کمبود RAM را حل می‌کند؟

Swap می‌تواند در برخی شرایط به جلوگیری از کمبود ناگهانی حافظه کمک کند، اما جایگزین RAM واقعی نیست. استفاده سنگین از Swap برای یک گیم سرور حساس به تأخیر می‌تواند باعث کندی محسوس شود.

بهتر است کمبود دائمی RAM را با کاهش بار یا افزایش منابع حل کنید، نه با اتکا به Swap زیاد.

جلوگیری از اختلال ناشی از دیسک

فشار روی دیسک فقط با CPUQuota و MemoryMax کنترل نمی‌شود. برای مثال، استخراج یک آرشیو چندگیگابایتی یا اجرای هم‌زمان Backup تمام بازی‌ها ممکن است باعث افزایش تأخیر I/O شود.

برای کاهش این مشکل، Backup و آپدیت بازی‌ها را در زمان‌های جداگانه انجام دهید و در صورت نیاز قابلیت‌های IOWeight یا محدودیت‌های I/O مربوط به cgroups را بررسی کنید.

قابلیت‌های کنترل I/O به نوع دستگاه ذخیره‌سازی، Kernel و پیکربندی cgroup بستگی دارند و پیش از اعمال محدودیت باید آزمایش شوند.

مرحله هشتم: مانیتورینگ مصرف منابع هر گیم سرور

برای مدیریت چند بازی، صرفاً مشاهده مصرف کلی RAM یا CPU VPS کافی نیست. باید بتوانید مشخص کنید هر سرویس چقدر منابع مصرف می‌کند و آیا به محدودیت تعیین‌شده نزدیک شده است یا خیر.

مشاهده مصرف سرویس‌ها با systemd-cgtop

sudo systemd-cgtop

این ابزار مصرف منابع را در سطح cgroup نمایش می‌دهد. برای دقیق بودن آمار، باید حسابداری منابع مانند MemoryAccounting و CPUAccounting فعال باشد.

بررسی حافظه فعلی هر سرویس

systemctl show minecraft.service \
-p MemoryCurrent -p MemoryMax -p NRestarts

systemctl show cs2.service \
-p MemoryCurrent -p MemoryMax -p NRestarts

بسته به نسخه systemd و Kernel، ممکن است برخی مقدارها در دسترس نباشند یا تا زمان فعال شدن حسابداری منابع نمایش داده نشوند.

بررسی فشار حافظه و CPU

Linux اطلاعات Pressure Stall Information یا PSI را در فایل‌های زیر ارائه می‌کند:

cat /proc/pressure/cpu
cat /proc/pressure/memory
cat /proc/pressure/io

این اطلاعات نشان می‌دهند فرآیندها چه میزان از زمان را به علت کمبود یا رقابت منابع در انتظار بوده‌اند.

اگر Memory Pressure یا I/O Pressure در زمان شلوغی دائماً بالا بماند، ممکن است حتی پیش از رسیدن به OOM نیز عملکرد بازیکنان افت کند.

بررسی رخدادهای OOM

در cgroups v2، فایل memory.events شمارنده‌هایی برای رخدادهای مرتبط با حافظه ارائه می‌کند.

ابتدا مسیر cgroup را به دست آورید:

systemctl show minecraft.service -p ControlGroup

سپس فایل memory.events را در مسیر متناظر cgroup بررسی کنید. افزایش شمارنده oom_kill نشان می‌دهد یک یا چند فرآیند مربوط به آن گروه بر اثر OOM کشته شده‌اند.

مانیتورینگ حرفه‌ای با Prometheus و Grafana

اگر چند گیم سرور فعال یا تعداد زیادی کاربر دارید، می‌توانید از Prometheus و Grafana برای مشاهده نمودارهای مصرف منابع استفاده کنید.

ابزار Node Exporter امکان جمع‌آوری شاخص‌های میزبان مانند CPU، RAM، دیسک و شبکه را فراهم می‌کند.

برای پایش دقیق هر سرویس یا کانتینر، به جمع‌آوری شاخص‌های مربوط به cgroup و ابزارهای تکمیلی متناسب با محیط خود نیز نیاز دارید.

مستندات رسمی Prometheus Node Exporter

برای چه مواردی هشدار تنظیم کنیم؟

  • توقف یا Restartهای غیرمنتظره هر سرویس بازی.
  • افزایش مداوم مصرف RAM تا نزدیکی سقف تعیین‌شده.
  • تکرار رخدادهای OOM یا Memory Pressure.
  • افزایش CPU Throttling همراه با افت عملکرد.
  • کاهش فضای آزاد دیسک و رشد غیرعادی Logها.
  • قطع شدن دسترسی واقعی بازیکنان به پورت بازی.
  • ناموفق بودن Backup یا تست بازیابی.

توجه کنید که فعال بودن یک سرویس در systemd لزوماً به معنی قابل بازی بودن آن نیست. بهتر است علاوه بر بررسی وضعیت Process، تست سلامت متناسب با پروتکل همان بازی نیز داشته باشید.

مرحله نهم: Backup مستقل هر گیم سرور و بازیابی پس از خرابی

وقتی چند بازی روی یک VPS هستند، نباید همه اطلاعات آن‌ها را بدون برنامه در یک پوشه Backup ذخیره کنید.

بهتر است هر بازی نسخه پشتیبان مستقل داشته باشد تا در صورت خرابی Save یا آپدیت یکی از آن‌ها، نیازی به بازگرداندن کل VPS نباشد.

چه اطلاعاتی باید Backup شوند؟

  • دنیاها، نقشه‌ها و فایل‌های Save هر بازی.
  • پیکربندی‌های سرور و فایل‌های اختصاصی آن.
  • لیست بازیکنان، مجوزها، Banها و تنظیمات مدیران.
  • فایل‌های افزونه‌ها و اطلاعات پایگاه داده آن‌ها در صورت نیاز.
  • فایل سرویس systemd یا پیکربندی Docker Compose.
  • نسخه و تنظیمات موردنیاز برای بازیابی محیط اجرا.

در بسیاری از موارد نیازی نیست تمام فایل‌های قابل دانلود بازی در هر Backup کپی شوند؛ اما باید مطمئن باشید می‌توانید همان نسخه نرم‌افزار را دوباره نصب کنید.

چرا Backup هنگام نوشتن Save خطرناک است؟

اگر بازی در حال ذخیره‌سازی دنیا یا اطلاعات بازیکنان باشد، کپی ساده فایل‌ها ممکن است نسخه پشتیبان ناسازگار یا ناقص ایجاد کند.

برای تهیه Backup سازگار می‌توانید از دستور Save یا Snapshot رسمی همان بازی استفاده کنید. در صورت نبود چنین روشی، توقف کنترل‌شده سرویس پیش از Backup یکی از گزینه‌های امن‌تر است.

نمونه اسکریپت Backup مستقل Minecraft

در این مثال فرض می‌کنیم فایل‌های سرور داخل /srv/games/minecraft قرار دارند و نام سرویس minecraft.service است.

این نمونه، برای تهیه Backup سازگار، سرویس Minecraft را موقتاً متوقف می‌کند. بنابراین بهتر است در زمان خلوت اجرا شود.

فایل زیر را ایجاد کنید:

sudo nano /usr/local/sbin/backup-minecraft.sh

محتوای اسکریپت:

#!/usr/bin/env bash
set -Eeuo pipefail

UNIT="minecraft.service"
SOURCE="/srv/games/minecraft"
DEST="/var/backups/games/minecraft"

mkdir -p "$DEST"
chmod 700 "$DEST"

systemctl stop "$UNIT"
trap 'systemctl start "$UNIT"' EXIT

tar -C "$(dirname "$SOURCE")" \
    -czf "$DEST/minecraft-$(date +%Y%m%d-%H%M%S).tar.gz" \
    "$(basename "$SOURCE")"

این نسخه تمام پوشه Minecraft را فشرده می‌کند؛ پس اگر فایل‌های اجرایی حجیم در آن قرار دارند، حجم Backup می‌تواند زیاد شود. در محیط عملی بهتر است فهرست فایل‌های ضروری را براساس ساختار واقعی سرور مشخص کنید.

پیش از اجرا، نام سرویس و مسیرها را اصلاح کرده و وجود فضای کافی روی دیسک را بررسی کنید.

آزمایش و اجرای اسکریپت

sudo bash -n /usr/local/sbin/backup-minecraft.sh
sudo chmod 700 /usr/local/sbin/backup-minecraft.sh
sudo /usr/local/sbin/backup-minecraft.sh

در این اسکریپت از trap استفاده شده تا هنگام خروج از اجرای اسکریپت، برای راه‌اندازی مجدد Minecraft تلاش شود. با این حال، در شرایطی مانند خاموش شدن کامل VPS یا قطع برق، اجرای دستورات بعدی تضمین‌شده نیست؛ بنابراین وضعیت سرویس باید پایش شود.

چگونه سلامت فایل Backup را بررسی کنیم؟

پس از تولید آرشیو، می‌توانید فهرست فایل‌های آن را بدون استخراج مشاهده کنید:

sudo tar -tzf /var/backups/games/minecraft/BACKUP_FILE.tar.gz

نام BACKUP_FILE.tar.gz را با نام واقعی فایل جایگزین کنید.

این بررسی صرفاً خوانایی آرشیو را آزمایش می‌کند. برای اطمینان از قابل بازیابی بودن اطلاعات، باید هر از گاهی Backup را در یک محیط آزمایشی استخراج و بررسی کنید.

چرا Backup روی همان VPS کافی نیست؟

اگر دیسک VPS آسیب ببیند، سیستم‌عامل حذف شود یا یک مهاجم به تمام فایل‌های میزبان دسترسی پیدا کند، Backupهای محلی نیز ممکن است از بین بروند.

بهتر است از روش 3-2-1 الهام بگیرید: چند نسخه از اطلاعات مهم داشته باشید و حداقل یکی از نسخه‌ها را خارج از VPS اصلی نگهداری کنید.

برای Backup رمزنگاری‌شده و نگهداری نسخه‌ها، ابزارهایی مانند restic قابل استفاده هستند.

بازیابی فقط یک بازی

اگر Save Minecraft خراب شود، به‌جای Restore کل VPS، ابتدا همان بازی را متوقف کنید و فایل‌های موردنیاز را از Backup معتبر به مسیر آزمایشی استخراج کنید.

پس از بررسی فایل‌ها، اطلاعات مربوط به Minecraft را بازیابی کنید و CS2 را دست‌نخورده باقی بگذارید.

بازیابی کل VPS را برای خرابی‌های گسترده‌تر مانند از دست رفتن سیستم‌عامل یا ماشین مجازی نگه دارید.

مرحله دهم: آپدیت بازی‌ها بدون قطع شدن تمام سرورها

یکی از مزیت‌های جداسازی سرویس‌ها این است که می‌توانید هر بازی را در زمان مناسب خودش به‌روزرسانی کنید.

برای مثال، هنگام آپدیت Minecraft لازم نیست CS2 را متوقف کنید؛ مگر اینکه وابستگی مشترکی وجود داشته باشد یا عملیات آپدیت فشار غیرقابل‌قبولی روی VPS ایجاد کند.

ترتیب مناسب آپدیت یک بازی

  1. اطلاع‌رسانی به بازیکنان همان سرور.
  2. تهیه Backup از Save و پیکربندی آن بازی.
  3. توقف کنترل‌شده همان سرویس.
  4. اجرای روش آپدیت مخصوص بازی.
  5. بررسی فایل‌های تنظیمات و سازگاری Mods.
  6. راه‌اندازی مجدد همان سرویس.
  7. بررسی Log و تست اتصال یک بازیکن.

چرا نباید همه بازی‌ها را هم‌زمان آپدیت کنیم؟

دانلود چند بسته بزرگ، اجرای چند SteamCMD و استخراج هم‌زمان فایل‌ها می‌تواند مصرف شبکه و دیسک را افزایش دهد و باعث تأخیر بازی‌هایی شود که همچنان در حال اجرا هستند.

بنابراین حتی اگر بازی‌ها از نظر CPU و RAM محدود شده باشند، بهتر است عملیات سنگین آپدیت و Backup را زمان‌بندی و از نظر مصرف I/O کنترل کنید.

بازگشت به نسخه قبلی

قبل از آپدیت مهم، نسخه فعلی فایل‌های تنظیمات، Save و اطلاعات نسخه بازی را ثبت کنید.

اگر نسخه جدید باعث ناسازگاری شد، بازگشت به نسخه قبلی فقط زمانی امن است که فایل‌های Save و افزونه‌ها نیز با آن سازگار باشند.

در بعضی بازی‌ها، Save ایجادشده با نسخه جدید ممکن است در نسخه قدیمی قابل استفاده نباشد.

عیب‌یابی مشکلات اجرای چند گیم سرور روی یک VPS

مشکل اول: با شلوغ شدن Minecraft، سرور CS2 لگ می‌شود

ابتدا مصرف CPU هر سرویس را بررسی کنید. اگر هر دو بازی CPU زیادی مصرف می‌کنند، ممکن است پردازنده VPS به سقف توان خود رسیده باشد.

CPUQuota می‌تواند مصرف یک بازی را محدود کند، اما اگر مقدار آن بیش از حد پایین باشد، همان بازی کند می‌شود. همچنین اگر vCPUهای VPS اشتراکی باشند، افزایش منابع یا مهاجرت به سرویس مناسب‌تر ممکن است لازم باشد.

مشکل دوم: یکی از بازی‌ها با پیام OOM متوقف می‌شود

احتمالاً MemoryMax کمتر از مصرف واقعی بازی تنظیم شده یا خود بازی دارای نشت حافظه و مصرف غیرعادی است.

ابتدا Logها و شمارنده‌های memory.events را بررسی کنید. سپس مصرف واقعی حافظه را اندازه بگیرید و فقط در صورت وجود ظرفیت آزاد، سقف را افزایش دهید.

افزایش بی‌برنامه تمام سقف‌ها ممکن است مشکل را از سطح یک بازی به کل VPS منتقل کند.

مشکل سوم: پس از Restart بازی، بقیه سرورها نیز قطع می‌شوند

بررسی کنید آیا واقعاً فقط همان سرویس Restart شده است یا اسکریپت مدیریتی شما کل VPS، Docker Daemon یا یک گروه مشترک از فرآیندها را متوقف می‌کند.

در systemd همچنین وابستگی‌های بین سرویس‌ها را بررسی کنید.

مشکل چهارم: Port already in use

این خطا معمولاً نشان می‌دهد ترکیب IP، پورت و پروتکل موردنیاز قبلاً توسط سرویس دیگری اشغال شده است.

از ss برای شناسایی فرآیند استفاده‌کننده از پورت کمک بگیرید و در صورت نیاز پورت یکی از بازی‌ها را تغییر دهید.

مشکل پنجم: بعد از فعال کردن CPU Affinity عملکرد بدتر شده است

احتمال دارد بازی روی تعداد محدودی CPU محصور شده و نتواند از ظرفیت آزاد سایر CPUها استفاده کند.

AllowedCPUs را موقتاً حذف کنید و عملکرد را دوباره در شرایط مشابه آزمایش کنید.

مشکل ششم: فضای دیسک به‌سرعت پر می‌شود

پوشه‌های Backup، Log، Cache و فایل‌های دانلودشده را بررسی کنید.

df -h
sudo du -h -d 1 /var/backups/games
sudo journalctl --disk-usage

اگر فایل‌های ذخیره‌سازی مهم در مسیر خاصی قرار دارند، پیش از هر عملیات پاک‌سازی ماهیت آن‌ها را بررسی کنید. پاک کردن خودکار پوشه‌های بازی یا Backup بدون بررسی می‌تواند باعث از دست رفتن اطلاعات شود.

مشکل هفتم: Docker Port باز است اما UFW آن را مسدود نشان می‌دهد

Docker برای انتشار پورت‌ها قواعد شبکه خود را ایجاد می‌کند و ممکن است مسیر عبور ترافیک با انتظار شما از UFW متفاوت باشد.

تنظیمات انتشار پورت، شبکه Docker و Firewall ارائه‌دهنده VPS را بررسی کنید و دسترسی را از خارج سرور آزمایش کنید.

مشکل هشتم: سرویس Active است ولی بازیکنان متصل نمی‌شوند

وضعیت Active فقط نشان می‌دهد systemd سرویس را فعال تشخیص داده است. ممکن است بازی هنوز در حال بارگذاری نقشه باشد یا اتصال شبکه به علت مشکل نسخه، توکن، Firewall یا پورت برقرار نشود.

برای نتیجه قطعی باید Log بازی و یک تست اتصال واقعی با کلاینت سازگار را بررسی کنید.

چک‌لیست نهایی اجرای چند گیم سرور روی VPS

پیش از اینکه VPS چندبازی را در اختیار کاربران قرار دهید، موارد زیر را بررسی کنید:

  • هر بازی سرویس و مسیر داده مستقل دارد.
  • بازی‌ها تا حد امکان با کاربر Linux غیرمدیر و جداگانه اجرا می‌شوند.
  • مصرف RAM در شرایط شلوغ اندازه‌گیری شده است.
  • MemoryHigh و MemoryMax متناسب با مصرف واقعی تنظیم شده‌اند.
  • CPUQuota بدون ایجاد Throttling شدید آزمایش شده است.
  • CPU Affinity فقط در صورت نیاز و پس از Benchmark اعمال شده است.
  • پورت‌ها و پروتکل‌های هر بازی مشخص و بدون تداخل هستند.
  • دسترسی مدیریتی و RCON بی‌دلیل برای تمام اینترنت باز نیست.
  • Restart یک سرویس باعث توقف سایر بازی‌ها نمی‌شود.
  • Logها و رخدادهای OOM برای هر سرویس قابل مشاهده‌اند.
  • Backup هر بازی مستقل و بازیابی آن آزمایش شده است.
  • فضای کافی برای سیستم‌عامل، Logها و عملیات آپدیت باقی مانده است.
  • تست اتصال واقعی با چند بازیکن انجام شده است.
  • برای خرابی کامل VPS نیز نسخه پشتیبان خارج از میزبان وجود دارد.

سؤالات متداول درباره اجرای چند گیم سرور روی VPS

آیا می‌توان چند گیم سرور را روی یک VPS اجرا کرد؟

بله. به شرط آنکه منابع، پورت‌ها، فایل‌ها و سرویس‌های هر بازی به‌درستی مدیریت شوند، اجرای هم‌زمان چند Dedicated Server روی یک VPS امکان‌پذیر است.

آیا با یک IP می‌توان چند سرور بازی داشت؟

بله. بازی‌ها می‌توانند با پورت‌ها و پروتکل‌های مناسب از یک IP عمومی استفاده کنند. باید از تداخل پورت جلوگیری کنید.

برای دو گیم سرور چقدر RAM لازم است؟

مقدار RAM به بازی‌ها، تعداد بازیکنان و Modها بستگی دارد. باید مصرف اوج هر بازی را اندازه بگیرید و منابع سیستم‌عامل و حاشیه اطمینان را نیز محاسبه کنید.

آیا VPS با ۸ گیگابایت RAM برای Minecraft و CS2 کافی است؟

ممکن است برای برخی تنظیمات و ظرفیت‌های کوچک مناسب باشد، اما تضمینی نیست. در سرورهای دارای بازیکنان زیاد یا Modهای سنگین، منابع بیشتری لازم خواهد بود.

systemd بهتر است یا Docker؟

برای سرویس‌هایی که مستقیم روی Linux نصب شده‌اند، systemd همراه با cgroups اغلب ساده‌تر است. Docker برای بازی‌هایی با Image سازگار و قابل اعتماد می‌تواند مدیریت و جداسازی محیط اجرا را آسان‌تر کند.

آیا Docker به‌صورت خودکار RAM بازی‌ها را محدود می‌کند؟

خیر. برای محدود کردن مصرف باید گزینه‌هایی مانند mem_limit و cpus را در تنظیمات Docker یا Compose تعریف کنید.

MemoryMax چیست؟

MemoryMax سقف سخت حافظه یک سرویس systemd را تعیین می‌کند. در صورت رسیدن به این سقف و آزاد نشدن حافظه کافی، امکان وقوع OOM وجود دارد.

MemoryHigh چه تفاوتی با MemoryMax دارد؟

MemoryHigh باعث افزایش فشار بازپس‌گیری حافظه و محدودسازی نرم‌تر می‌شود، درحالی‌که MemoryMax سقف سخت حافظه را مشخص می‌کند.

CPUQuota=200% یعنی چه؟

یعنی سرویس می‌تواند حداکثر معادل زمان پردازشی دو CPU منطقی مصرف کند. این مقدار به معنی رزرو دو هسته اختصاصی نیست.

آیا CPU Affinity باعث کاهش Lag می‌شود؟

گاهی می‌تواند به کنترل رقابت پردازنده کمک کند، اما در بعضی شرایط عملکرد را بدتر می‌کند. بهتر است فقط پس از اندازه‌گیری و آزمایش استفاده شود.

اگر یکی از بازی‌ها Crash کند، بقیه بازی‌ها هم بسته می‌شوند؟

در ساختار درست با سرویس‌ها و محدودیت‌های مستقل، خرابی یک بازی لزوماً نباید بقیه بازی‌ها را متوقف کند. با این حال، خرابی کل VPS یا منابع مشترک می‌تواند همه سرویس‌ها را تحت تأثیر قرار دهد.

برای هر بازی به یک IP جدا نیاز داریم؟

خیر. در بسیاری از بازی‌ها یک IP عمومی به همراه پورت‌های متفاوت کافی است. البته بعضی بازی‌ها یا تنظیمات خاص ممکن است نیازهای شبکه‌ای دیگری داشته باشند.

چطور بفهمیم کدام بازی RAM زیادی مصرف می‌کند؟

با systemd-cgtop، systemctl show و شاخص‌های cgroup می‌توانید مصرف منابع سرویس‌ها را بررسی کنید.

آیا باید برای هر بازی Backup جداگانه بگیریم؟

بله، بهتر است هر بازی نسخه پشتیبان مستقل داشته باشد تا هنگام خرابی یا آپدیت یک سرویس، نیاز به بازیابی کل VPS نباشد.

آیا Backup روی همان VPS کافی است؟

خیر. برای محافظت در برابر خرابی دیسک، حذف VPS یا مشکلات گسترده‌تر، حداقل یک نسخه پشتیبان خارج از سرور اصلی نگهداری کنید.

آیا می‌توان فقط یک بازی را بدون قطع شدن بقیه آپدیت کرد؟

بله. اگر بازی‌ها مستقل اجرا شوند، می‌توانید سرویس موردنظر را متوقف و آپدیت کنید. البته عملیات سنگین آپدیت ممکن است روی منابع مشترک فشار ایجاد کند.

اگر چند گیم سرور برای کسب‌وکار مهم باشند، یک VPS کافی است؟

برای کاهش هزینه و مدیریت ساده‌تر ممکن است مناسب باشد؛ اما اگر خرابی هم‌زمان قابل قبول نیست، تقسیم بازی‌ها روی چند VPS مستقل انتخاب بهتری است.

جمع‌بندی

اجرای چند گیم سرور روی یک VPS امکان‌پذیر است، اما برای جلوگیری از اختلال باید به مسئله جداسازی منابع توجه ویژه داشته باشید.

اگر بازی‌ها مستقیماً روی Linux نصب شده‌اند، استفاده از systemd و cgroups v2 می‌تواند روشی مناسب برای کنترل CPU، RAM و فرآیندهای هر سرویس باشد. با گزینه‌هایی مانند CPUQuota، MemoryHigh و MemoryMax می‌توانید مصرف منابع را مدیریت کنید و احتمال سرایت مشکلات یک بازی به بازی‌های دیگر را کاهش دهید.

Docker Compose نیز برای بازی‌هایی که Image مناسب دارند، امکان مدیریت مستقل کانتینرها را فراهم می‌کند؛ اما در این روش نیز محدودیت منابع، Volumeها و تنظیمات شبکه باید به‌درستی تعریف شوند.

در کنار این موارد، مدیریت پورت‌ها، اجرای بازی‌ها با کاربران مستقل، تهیه Backup جداگانه، پایش OOM و جلوگیری از آپدیت هم‌زمان، نقش مهمی در پایداری سرور دارند.

در نهایت، اگرچه جداسازی منابع می‌تواند احتمال خرابی زنجیره‌ای را کاهش دهد، یک VPS همچنان یک نقطه خرابی مشترک است. برای سرویس‌های مهم‌تر یا پرطرفدارتر، استفاده از چند VPS مستقل می‌تواند دسترس‌پذیری و انعطاف‌پذیری بیشتری فراهم کند.

منابع و مستندات رسمی

برای بررسی تنظیمات و محدودیت‌های فنی این آموزش از مستندات رسمی systemd، Linux Kernel، Docker، Prometheus و restic استفاده شده است.

۱. systemd — Resource Control

مرجع رسمی CPUQuota، AllowedCPUs، MemoryHigh، MemoryMax و سایر تنظیمات کنترل منابع.

مطالعه مستندات کنترل منابع systemd

۲. Linux Kernel — Control Group v2

توضیحات رسمی Kernel درباره cgroups، محدودیت حافظه، CPU و رخدادهای OOM.

مطالعه مستندات cgroups v2

۳. Docker — Resource Constraints

روش اعمال محدودیت CPU و RAM و بررسی رفتار OOM در کانتینرها.

مشاهده راهنمای محدودیت منابع Docker

۴. Docker Compose — Services

مرجع گزینه‌های cpus، mem_limit، ports، volumes و restart.

مشاهده مستندات Docker Compose

۵. Docker — Packet Filtering and Firewalls

بررسی رفتار Docker در تنظیم Firewall و ارتباط آن با UFW.

مشاهده مستندات Docker Firewall

۶. systemd-cgtop

ابزار رسمی مشاهده مصرف CPU، RAM و I/O در سطح cgroup.

مشاهده مستندات systemd-cgtop

۷. Prometheus — Node Exporter

راهنمای رسمی جمع‌آوری شاخص‌های سخت‌افزار و سیستم‌عامل برای مانیتورینگ.

مشاهده مستندات Node Exporter

۸. restic — Backup and Restore

راهنمای تهیه Backup، مدیریت Snapshot و بازیابی فایل‌ها.

راهنمای تهیه Backup با restic

راهنمای بازیابی Backup با restic

اشتراک‌گذاری مقاله
گفت‌وگو درباره آموزش

دیدگاه‌ها (۰)

هنوز دیدگاهی ثبت نشده است.

دیدگاه یا سؤال خود را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *