ops: 把 systemd unit 纳入版本控制,统一 timeout/限流/资源限制

背景:
  生产机 /etc/systemd/system/socks-manager.service 长期脱管:参数跟
  README 文档不一致(-w 2 vs -w 1), 也没有 -w 4 的孤儿 gunicorn 抢占
  5000 端口、 systemd 启不来服务。已删孤儿, 改用本仓库的 unit 作为
  唯一权威源。

变更:
  + deploy/socks-manager.service  单元文件唯一权威源
  + deploy/install.sh              一键同步: install + daemon-reload +
                                  enable + restart + 验证 active
  M README.md                      部署章节改为引用 deploy/, 删除内联
                                  unit 代码(避免再次漂移)

调优:
  - --timeout 30            网络扫描器半截请求占满 worker, 30s 及时回收
  - --max-requests 1000     周期性回收 worker, 防内存泄漏
  - --limit-request-line    防御大请求行导致 worker 长时间阻塞
  - MemoryMax=512M          cgroup 硬上限, 防单 worker 把整台 1GB VPS
                            拖死再拖到 OOM
  - LimitNOFILE=65535       SOCKS5 大并发客户端连接所需
  - Type=notify + 保留 Restart=always / RestartSec=5
This commit is contained in:
cnbugs
2026-08-10 23:06:28 +08:00
parent 70b6da45c2
commit f948a410b6
3 changed files with 136 additions and 43 deletions
+43
View File
@@ -0,0 +1,43 @@
#!/usr/bin/env bash
# 把 deploy/socks-manager.service 同步到生产机并重启。
#
# 使用: 在生产机 /opt/socks-manager 下执行
# bash deploy/install.sh
#
# 假定: 仓库已 git pull 到最新,当前在 /opt/socks-manager 工作目录下。
set -euo pipefail
SERVICE_FILE="deploy/socks-manager.service"
DEST="/etc/systemd/system/socks-manager.service"
if [[ ! -f "$SERVICE_FILE" ]]; then
echo "ERROR: $SERVICE_FILE not found. Run from /opt/socks-manager." >&2
exit 1
fi
echo "[1/5] install unit -> $DEST"
install -m 0644 "$SERVICE_FILE" "$DEST"
echo "[2/5] daemon-reload"
systemctl daemon-reload
echo "[3/5] enable (开机自启)"
systemctl enable socks-manager.service
echo "[4/5] restart"
systemctl restart socks-manager.service
echo "[5/5] wait for active (max 15s)"
for i in $(seq 1 15); do
if systemctl is-active --quiet socks-manager.service; then
echo "active after ${i}s"
systemctl status socks-manager.service --no-pager | head -15
exit 0
fi
sleep 1
done
echo "ERROR: service did not become active in 15s" >&2
journalctl -u socks-manager.service -n 80 --no-pager >&2
exit 1