server: game-optimize.sh + README с сравнением vpn vs игры
This commit is contained in:
@@ -0,0 +1,49 @@
|
||||
# server/
|
||||
|
||||
Скрипты оптимизации Debian 12 под разные сценарии.
|
||||
|
||||
## vpn-optimize.sh
|
||||
|
||||
Полная оптимизация под VPN/X-Ray: BBR, большие буферы, высокий бэклог, nofile, systemd, x-ui.
|
||||
|
||||
```bash
|
||||
curl -fsSL https://gitea.creative-tg1.ru/CREATIVE_tg1/for-servers/raw/branch/main/server/vpn-optimize.sh | sudo bash
|
||||
```
|
||||
|
||||
**Приоритет:** пропускная способность, много одновременных соединений.
|
||||
|
||||
---
|
||||
|
||||
## game-optimize.sh
|
||||
|
||||
Полная оптимизация под игровые серверы / игровой ПК: минимальный пинг, борьба с bufferbloat, NIC-тюнинг, IRQ affinity.
|
||||
|
||||
```bash
|
||||
curl -fsSL https://gitea.creative-tg1.ru/CREATIVE_tg1/for-servers/raw/branch/main/server/game-optimize.sh | sudo bash
|
||||
```
|
||||
|
||||
**Приоритет:** минимальная задержка (latency), быстрый отклик.
|
||||
|
||||
**Что делает:**
|
||||
- `cake` qdisc — активная борьба с bufferbloat
|
||||
- `busy_poll=50` — снижает latency ценой CPU
|
||||
- NIC coalescing выключен (`rx-usecs=0`) — главный буст пинга
|
||||
- IRQ распределены по ядрам
|
||||
- Маленькие буферы по умолчанию
|
||||
|
||||
---
|
||||
|
||||
## Разница
|
||||
|
||||
| Параметр | VPN | Игры |
|
||||
|---|---|---|
|
||||
| qdisc | fq | **cake** |
|
||||
| rmem/wmem_default | 262144 | **212992** (дефолт) |
|
||||
| netdev_max_backlog | 250000 | **5000** |
|
||||
| tcp_fastopen | 1 | 1 |
|
||||
| busy_poll | — | **50** |
|
||||
| NIC coalescing | — | **выключен** |
|
||||
| IRQ affinity | — | **по ядрам** |
|
||||
| x-ui override | ✅ | — |
|
||||
|
||||
**Не смешивать:** VPN и игры требуют противоположных настроек. Если сервер делает и то и другое — компромисс невозможен, нужно выбирать приоритет.
|
||||
Executable
+202
@@ -0,0 +1,202 @@
|
||||
#!/bin/bash
|
||||
# game-optimize.sh — оптимизация Debian 12 под игровые серверы / игровой ПК
|
||||
# Минимальный пинг, низкий bufferbloat, быстрые прерывания
|
||||
# Запуск: bash game-optimize.sh
|
||||
|
||||
set -e
|
||||
|
||||
LIMIT_NOFILE=65535
|
||||
|
||||
echo "============================================"
|
||||
echo " Game Server Optimization — Debian 12"
|
||||
echo "============================================"
|
||||
echo ""
|
||||
|
||||
# ── 1. Сеть (sysctl) ─────────────────────────────────────
|
||||
|
||||
echo "[1/5] Сетевые оптимизации (sysctl)..."
|
||||
|
||||
cat >/etc/sysctl.d/99-game-network.conf <<SYSEOF
|
||||
#################################################
|
||||
# Queueing + Congestion Control
|
||||
# cake активнее борется с bufferbloat, BBR для TCP
|
||||
#################################################
|
||||
net.core.default_qdisc = cake
|
||||
net.ipv4.tcp_congestion_control = bbr
|
||||
|
||||
#################################################
|
||||
# Socket buffers — маленькие, без bufferbloat
|
||||
#################################################
|
||||
net.core.rmem_default = 212992
|
||||
net.core.wmem_default = 212992
|
||||
net.core.rmem_max = 16777216
|
||||
net.core.wmem_max = 16777216
|
||||
|
||||
#################################################
|
||||
# Network backlog — умеренный
|
||||
#################################################
|
||||
net.core.netdev_max_backlog = 5000
|
||||
net.core.somaxconn = 4096
|
||||
|
||||
#################################################
|
||||
# TCP buffers — сбалансированные
|
||||
#################################################
|
||||
net.ipv4.tcp_rmem = 4096 87380 16777216
|
||||
net.ipv4.tcp_wmem = 4096 65536 16777216
|
||||
|
||||
#################################################
|
||||
# UDP buffers — для игрового трафика
|
||||
#################################################
|
||||
net.ipv4.udp_rmem_min = 16384
|
||||
net.ipv4.udp_wmem_min = 16384
|
||||
|
||||
#################################################
|
||||
# busy_poll — не ждём прерываний, опрашиваем
|
||||
# ценой CPU (50 мкс), снижает latency на 20-50%
|
||||
#################################################
|
||||
net.core.busy_poll = 50
|
||||
net.core.busy_read = 50
|
||||
|
||||
#################################################
|
||||
# TCP low latency
|
||||
#################################################
|
||||
net.ipv4.tcp_low_latency = 1
|
||||
net.ipv4.tcp_notsent_lowat = 16384
|
||||
|
||||
#################################################
|
||||
# Security / routing
|
||||
#################################################
|
||||
net.ipv4.conf.all.accept_redirects = 0
|
||||
net.ipv4.conf.default.accept_redirects = 0
|
||||
net.ipv4.conf.all.send_redirects = 0
|
||||
net.ipv4.conf.default.send_redirects = 0
|
||||
|
||||
#################################################
|
||||
# Keepalive — быстрее обнаруживать разрыв
|
||||
#################################################
|
||||
net.ipv4.tcp_keepalive_time = 120
|
||||
net.ipv4.tcp_keepalive_intvl = 30
|
||||
net.ipv4.tcp_keepalive_probes = 5
|
||||
|
||||
#################################################
|
||||
# Ephemeral ports
|
||||
#################################################
|
||||
net.ipv4.ip_local_port_range = 1024 65535
|
||||
|
||||
#################################################
|
||||
# TCP fastopen — только клиент
|
||||
#################################################
|
||||
net.ipv4.tcp_fastopen = 1
|
||||
|
||||
#################################################
|
||||
# FIN timeout — быстрее освобождать сокеты
|
||||
#################################################
|
||||
net.ipv4.tcp_fin_timeout = 10
|
||||
|
||||
#################################################
|
||||
# SYN backlog + retries — меньше ретраев, быстрее фейл
|
||||
#################################################
|
||||
net.ipv4.tcp_max_syn_backlog = 8192
|
||||
net.ipv4.tcp_syn_retries = 2
|
||||
net.ipv4.tcp_synack_retries = 2
|
||||
SYSEOF
|
||||
|
||||
sysctl --system >/dev/null 2>&1
|
||||
echo " OK"
|
||||
|
||||
# ── 2. NIC — txqueuelen + coalescing ─────────────────────
|
||||
|
||||
echo "[2/5] Сетевые интерфейсы (NIC)..."
|
||||
|
||||
for iface in $(ls /sys/class/net/ | grep -v lo); do
|
||||
# Короткая очередь на интерфейсе
|
||||
ip link set dev "$iface" txqueuelen 1000 2>/dev/null || true
|
||||
|
||||
# Выключаем coalescing прерываний (rx-usecs=0) — главный буст для пинга
|
||||
ethtool -C "$iface" rx-usecs 0 2>/dev/null || true
|
||||
ethtool -C "$iface" tx-usecs 0 2>/dev/null || true
|
||||
|
||||
# Увеличиваем кольцевой буфер NIC (если поддерживается)
|
||||
ethtool -G "$iface" rx 4096 2>/dev/null || true
|
||||
ethtool -G "$iface" tx 4096 2>/dev/null || true
|
||||
|
||||
echo " $iface OK"
|
||||
done
|
||||
|
||||
# ── 3. ulimit ────────────────────────────────────────────
|
||||
|
||||
echo "[3/5] Лимиты файловых дескрипторов (limits.d)..."
|
||||
|
||||
cat >/etc/security/limits.d/90-nofile.conf <<LIMEOF
|
||||
* soft nofile ${LIMIT_NOFILE}
|
||||
* hard nofile ${LIMIT_NOFILE}
|
||||
root soft nofile ${LIMIT_NOFILE}
|
||||
root hard nofile ${LIMIT_NOFILE}
|
||||
LIMEOF
|
||||
|
||||
echo " OK"
|
||||
|
||||
# ── 4. systemd DefaultLimitNOFILE ────────────────────────
|
||||
|
||||
echo "[4/5] Лимиты systemd (DefaultLimitNOFILE)..."
|
||||
|
||||
for conf in /etc/systemd/system.conf /etc/systemd/user.conf; do
|
||||
if grep -q "^#DefaultLimitNOFILE=" "$conf" 2>/dev/null; then
|
||||
sed -i "s/^#DefaultLimitNOFILE=.*/DefaultLimitNOFILE=${LIMIT_NOFILE}/" "$conf"
|
||||
elif ! grep -q "^DefaultLimitNOFILE=" "$conf" 2>/dev/null; then
|
||||
echo "DefaultLimitNOFILE=${LIMIT_NOFILE}" >> "$conf"
|
||||
else
|
||||
sed -i "s/^DefaultLimitNOFILE=.*/DefaultLimitNOFILE=${LIMIT_NOFILE}/" "$conf"
|
||||
fi
|
||||
done
|
||||
|
||||
systemctl daemon-reload
|
||||
echo " OK"
|
||||
|
||||
# ── 5. IRQ affinity (если CPU > 1 ядро) ─────────────────
|
||||
|
||||
echo "[5/5] IRQ affinity..."
|
||||
|
||||
CPU_COUNT=$(nproc)
|
||||
if [ "$CPU_COUNT" -gt 1 ]; then
|
||||
# Распределяем сетевые прерывания по ядрам
|
||||
for iface in $(ls /sys/class/net/ | grep -v lo); do
|
||||
irqs=$(grep "$iface" /proc/interrupts 2>/dev/null | awk -F: '{print $1}' || true)
|
||||
core=0
|
||||
for irq in $irqs; do
|
||||
irq_num="${irq//[^0-9]/}"
|
||||
[ -z "$irq_num" ] && continue
|
||||
if [ -f "/proc/irq/$irq_num/smp_affinity_list" ]; then
|
||||
echo "$core" > "/proc/irq/$irq_num/smp_affinity_list" 2>/dev/null || true
|
||||
core=$(( (core + 1) % CPU_COUNT ))
|
||||
fi
|
||||
done
|
||||
done
|
||||
echo " Распределено по $CPU_COUNT ядрам"
|
||||
else
|
||||
echo " 1 ядро — пропущено"
|
||||
fi
|
||||
|
||||
# ── Итоги ─────────────────────────────────────────────────
|
||||
|
||||
echo ""
|
||||
echo "============================================"
|
||||
echo " Итог"
|
||||
echo "============================================"
|
||||
echo ""
|
||||
echo "Очередь:"
|
||||
sysctl net.core.default_qdisc
|
||||
echo "Контроль перегрузки:"
|
||||
sysctl net.ipv4.tcp_congestion_control
|
||||
echo "busy_poll:"
|
||||
sysctl net.core.busy_poll
|
||||
echo "Soft ulimit: $(ulimit -Sn)"
|
||||
echo "Hard ulimit: $(ulimit -Hn)"
|
||||
echo ""
|
||||
echo "NIC:"
|
||||
for iface in $(ls /sys/class/net/ | grep -v lo); do
|
||||
echo " $iface: txqueuelen=$(cat /sys/class/net/$iface/tx_queue_len 2>/dev/null || echo '?')"
|
||||
done
|
||||
echo ""
|
||||
echo "Готово."
|
||||
echo "После перезагрузки сессии / машины — ulimit -n покажет ${LIMIT_NOFILE}"
|
||||
Reference in New Issue
Block a user