팰월드 24시간 서버 만들기: 자동 실행, 자동 복구, 예약 재시작
팰월드 24시간 서버를 만들려면 서로 다른 세 가지가 다 있어야 해요. 부팅 시 자동 실행, 꺼졌을 때 자동 복구, 매일 예약 재시작. systemd 유닛이 어디까지 막아 주고 어디서부터 못 막는지, 끊긴 걸 어떻게 알아채는지까지 정리했어요.
팰월드 서버를 24시간 켜둔다는 건 설정 한 줄이 아니라 서로 다른 세 가지 장치예요. 부팅할 때 알아서 뜨는 것, 죽었을 때 다시 뜨는 것, 그리고 아직 죽지 않았는데 미리 껐다 켜는 것. 셋 중 하나를 빼놓으면 정확히 그 자리에서 끊겨요. 서버를 아직 안 만들었다면 구축 가이드를 먼저 보고 오세요. 이 글은 이미 떠 있는 서버를 계속 켜두는 이야기예요.
서버를 24시간 열어 놓으려면 세 가지가 다 있어야 해요
"계속 켜두기"가 실패하는 방식은 세 가지고, 각각 다른 장치가 막아요.
| 끊기는 상황 | 필요한 것 | 어디서 |
|---|---|---|
| 커널 업데이트나 정전 뒤 머신이 재부팅됨 | 부팅 시 자동 실행 | systemd의 enable |
| 메모리 부족으로 프로세스가 죽거나 엔진이 크래시함 | 꺼짐 자동 복구 | 유닛의 Restart |
| 아무것도 안 죽었는데 점점 무거워짐 | 매일 예약 재시작 | 타이머 또는 cron |
세 줄이 서로를 대신하지 못해요. Restart=on-failure는 부팅과 아무 상관이 없고(그건 enable이 하는 일), enable은 죽은 프로세스를 살려 주지 않으며, 둘 다 메모리가 차오르는 동안에는 아무 일도 하지 않아요. "자동 재시작 해 놨는데 왜 꺼져 있냐"는 대부분 셋 중 안 해 둔 하나에서 나와요.
여기에 사람 손이 필요한 네 번째가 하나 더 있어요. 끊긴 걸 알아채는 것. 앞의 셋을 다 해 둬도 세 개가 동시에 실패하는 날은 오고, 그날 누가 먼저 아느냐가 남아요.
systemd 유닛이 막아 주는 것과 막지 못하는 것
유닛 파일은 구축 가이드에 있는 것에 [Unit] 섹션 두 줄만 더하면 돼요. 여기서 볼 줄은 이것들이에요.
[Unit]
StartLimitIntervalSec=600
StartLimitBurst=5
[Service]
Restart=on-failure
RestartSec=10
[Install]
WantedBy=multi-user.target
WantedBy=multi-user.target과 sudo systemctl enable palworld가 짝이 되어 부팅 시 자동 실행을 만들어요. 가이드에 나오는 enable --now에서 --now는 "지금도 켜라"는 뜻일 뿐이에요. enable 없이 start만 해 두면 지금은 잘 돌아가는데 재부팅하면 안 올라와요. 그리고 이건 머릿속으로 확인이 안 되는 종류라, 사람이 없는 시간에 한 번은 진짜로 sudo reboot을 해서 저절로 올라오는지 봐야 해요.
Restart=on-failure가 막아 주는 것은 0이 아닌 종료 코드, 그리고 시그널로 죽은 경우예요. 메모리가 꽉 차서 커널이 프로세스를 죽이는 경우도 여기 들어가요.
막지 못하는 것은 셋이에요.
- 정상 종료(코드 0). REST API로 내린 서버는 깨끗하게 끝나기 때문에
on-failure가 손대지 않아요. 스크립트로 재시작을 돌리는데 서버가 안 올라온다면 열에 아홉은 이거예요. - 프로세스는 살아 있는데 응답이 없는 상태. systemd가 보는 건 프로세스지 게임이 아니에요. 접속은 되는데 아무도 못 움직이는 상황에서 유닛은 여전히
active예요. - 반복되는 실패.
StartLimit두 줄을 넣어 두면 10분 안에 5번 시작에 실패했을 때 systemd가 포기하고failed로 남아요. systemd 자체 기본값은 "10초 안에 5번"이라,RestartSec=10으로 매번 10초씩 기다리는 유닛은 절대 거기 닿지 않아요. 두 줄이 없으면 매번 같은 이유로 죽는 서버는activating (auto-restart)상태로 끝없이 재시도해요.systemctl status palworld에 "start request repeated too quickly"가 보이면 자동 복구가 고장 난 게 아니라, 매번 같은 이유로 죽고 있으니 로그부터 보라는 뜻이에요.
이 세 번째 경우를 두 줄을 지우거나 StartLimitIntervalSec=0으로 꺼서 덮지 마세요. 세이브가 깨져서 못 뜨는 서버를 10초마다 영원히 재시도하게 될 뿐이고, 그동안 진짜 원인은 로그 수천 줄 아래로 밀려나요. journalctl -u palworld -n 100으로 마지막 실패 이유를 먼저 읽는 게 언제나 빨라요.
매일 예약 재시작은 선택이 아니에요
팰월드 서버는 메모리 누수 때문에 프로세스가 살아 있는 채로 다 같이 느려지는 구간이 오고, 죽기 전의 그 구간에는 Restart=on-failure가 아무 일도 하지 않아서 매일 한 번 잘라 내는 예약 재시작이 따로 필요해요. 왜 그런지와 재시작 주기를 정하는 기준은 메모리 누수와 예약 재시작에, 그 재시작에 업데이트를 묶는 방법은 팰월드 서버 업데이트 방법에 있어요.
거는 방법은 cron이 가장 짧고, 그 스크립트는 메모리 누수 글에 그대로 있어요. systemd만 쓰고 싶다면 타이머로도 돼요.
# /etc/systemd/system/palworld-restart.timer
[Unit]
Description=Restart Palworld daily
[Timer]
OnCalendar=*-*-* 04:00:00
[Install]
WantedBy=timers.target
같은 이름의 palworld-restart.service(Type=oneshot)가 실제 스크립트를 부르고, sudo systemctl enable --now palworld-restart.timer로 켜요. 다음 실행 시각은 systemctl list-timers로 확인해요. Persistent=true는 넣지 마세요. 머신이 꺼져 있어서 지나간 실행을 부팅 직후에 따라잡는 옵션인데, 방금 켜진 서버를 곧바로 다시 재시작할 이유는 없어요.
시각은 사람이 없는 새벽으로 잡고, 그 시각이 백업이 도는 시각과 겹치지 않게만 신경 쓰면 돼요.
그냥 죽이지 말고 공지, 카운트다운, 강제 저장 순서로
kill이나 systemctl kill로 내리는 건 매일 크래시를 하나씩 만드는 것과 같아요. 자동 저장 간격만큼의 진행이 사라지고, 운이 나쁘면 저장 중에 맞아서 Level.sav가 반만 써져요. 반만 써진 세이브는 다음 시작 때에야 드러나고, 그때는 이미 하루가 지나 있어요.
정상 종료의 순서는 공지 → 카운트다운 → 강제 저장 → 정지예요. 네 단계 전부 공식 REST API에 있어요(켜는 법과 인증은 REST API 사용법에).
PW='충분히 긴 비밀번호'
API='http://127.0.0.1:8212/v1/api'
# 저장을 먼저 확실히 해 두고
curl -s -u "admin:$PW" -X POST "$API/save"
# 공지와 60초 카운트다운은 API가 대신 해 줘요
curl -s -u "admin:$PW" -X POST "$API/shutdown" \
-H 'Content-Type: application/json' \
-d '{"waittime":60,"message":"Server is going down in 60 seconds"}'
message는 채팅창에 올라왔다 금방 밀려나는 한 줄이 아니에요. 모든 플레이어 화면 한가운데에 배너로 떠요:

/stop은 예고 없이 즉시 끊는 쪽이니 정기 운영에는 쓰지 마세요. /shutdown은 지정한 시간을 기다렸다가 내려가요.
그리고 여기서 앞 절의 함정이 그대로 걸려요. /shutdown으로 내려간 프로세스는 정상 종료라서 Restart=on-failure가 다시 띄워 주지 않아요. 목적이 재시작이라면 API로는 저장과 공지까지만 하고, 마지막 한 줄은 sudo systemctl restart palworld로 넘기세요. 목적이 진짜 정지(점검, 이사)라면 /shutdown으로 충분해요. 이 구분을 안 해서 "새벽에 꺼지고 안 켜지는" 서버가 가장 흔해요.
서버가 꺼진 걸 알아채는 가장 싼 방법
기본값은 "플레이어가 알려 준다"인데, 이 알림은 금요일 밤 열 시에 다섯 명이 기다리는 형태로 도착해요. 더 싼 방법이 세 가지 있어요.
상태 한 줄. systemctl is-active palworld는 active나 failed만 뱉어요. 이유까지 보려면 오늘 로그에서 종료 기록만 뽑아요.
systemctl is-active palworld
journalctl -u palworld --since today | grep -i "main process exited"
포트. 게임 포트는 UDP 8211이라 브라우저로 열어 볼 수가 없어요. 실제로 듣고 있는지는 ss -lunp | grep 8211로 봐요.
1분 심박. 로컬 cron이 1분마다 /metrics를 찔러 보고, 실패하면 내가 실제로 보는 곳으로 한 줄 보내게 하세요. cron은 셸에서 정한 PW를 물려받지 않으니, 비밀번호는 작은 스크립트에 적고 crontab 줄은 그 스크립트만 부르게 해요.
#!/bin/bash
# /home/palserver/heartbeat.sh: cron이 1분마다 불러요
PW='충분히 긴 비밀번호'
curl -sf -m 10 -u "admin:$PW" http://127.0.0.1:8212/v1/api/metrics >/dev/null || /home/palserver/alert.sh
-m 10을 붙여 두면 살아 있는데 응답이 없는 서버도 꺼진 것으로 잡혀요. 스크립트에 관리자 비밀번호가 들어 있으니 chmod 700 /home/palserver/heartbeat.sh로 본인만 읽게 한 뒤 cron에 걸어요.
* * * * * /home/palserver/heartbeat.sh
외부 감시 서비스에 맡기려고 8212를 공개 인터넷에 여는 건 하지 마세요. 개발사가 그러지 말라고 못 박은 포트라, 감시를 얻는 대신 서버 관리 권한 전체를 내놓는 거래가 돼요. 심박은 머신 안에서 돌리고, 나가는 건 알림 한 줄만 나가면 돼요.
집 컴퓨터에는 넘을 수 없는 두 가지가 있어요
정전. 한 번 나가면 그건 kill -9 한 번이에요. UPS는 몇 분을 사 줄 뿐이라, 실제로 필요한 건 "전원이 끊기면 순서대로 내려가는 것"이에요. UPS 감시 데몬이 정전을 감지했을 때 위의 정지 스크립트를 부르도록 연결해야 의미가 생겨요. 그리고 전기가 돌아온 뒤에 머신이 저절로 켜지는지는 운영체제가 아니라 BIOS의 전원 복구 설정에 달려 있어요. 이것도 한 번은 정말로 코드를 뽑아서 확인해야 하는 항목이에요.
유동 IP. 가정용 회선의 공인 IP는 예고 없이 바뀌고, 바뀌는 순간 친구들이 저장해 둔 주소:포트는 전부 죽은 주소가 돼요. DDNS로 도메인 하나가 따라다니게 할 수는 있지만, 팰월드 클라이언트에 남는 건 입력한 문자열이라 한 번은 다 같이 새로 입력해야 해요. 여기에 공유기 재부팅, 상향 대역폭, 통신사 쪽 주소 공유까지 겹치면 원인 찾기가 길어지는데, 그 순서는 접속 문제 해결에 정리해 뒀어요.
두 가지 다 "설정을 더 잘하면" 넘는 문제가 아니라 회선과 전기의 문제예요. 집 컴퓨터로 며칠 켜두는 건 되지만, 몇 달을 무인으로 켜두는 건 이 두 가지가 매번 걸려요.
자주 묻는 질문
팰월드 서버를 24시간 계속 켜두려면 어떻게 하나요?
세 가지를 따로 해 두면 돼요. systemd 유닛을 enable 해서 부팅 시 자동 실행되게 하고, 유닛에 Restart=on-failure를 넣어 꺼짐 자동 복구를 만들고, 타이머나 cron으로 매일 한 번 예약 재시작을 걸어요. 셋 중 하나만 하면 나머지 두 상황에서는 그대로 꺼져 있어요.
서버가 자꾸 꺼지는데 자동으로 다시 켜지게 할 수 있나요?
유닛의 [Service]에 Restart=on-failure와 RestartSec=10을 넣으면 크래시나 메모리 부족으로 죽었을 때 10초 뒤에 다시 떠요. [Unit]에 StartLimitIntervalSec=600과 StartLimitBurst=5도 넣어 두면, 매번 같은 이유로 죽는 서버가 끝없이 돌지 않고 10분 안에 5번 실패한 시점에서 멈춰요. 다만 이건 원인을 고치는 게 아니라 시간을 벌어 주는 거예요. 하루에 몇 번씩 죽는다면 메모리 쪽을 먼저 보세요.
자동 재시작을 걸어놨는데 서버가 안 올라와요. 뭘 봐야 하나요?
systemctl status palworld를 먼저 보세요. "start request repeated too quickly"면 10분 안에 5번 실패해서 systemd가 포기한 거라 로그에서 진짜 원인을 찾아야 하고, 고친 뒤에는 sudo systemctl reset-failed palworld로 횟수를 초기화한 다음 시작해요. 상태가 activating (auto-restart)에서 안 바뀐다면 StartLimit 두 줄이 빠져서 재시도만 반복하는 중이에요. 아무 기록 없이 inactive면 정상 종료라 on-failure가 손대지 않은 경우예요. 그렇다면 스크립트 마지막 줄을 systemctl restart로 바꾸면 돼요.
집 컴퓨터로 팰월드 서버를 24시간 돌려도 되나요?
며칠은 돼요. 오래 가면 정전과 유동 IP에서 막혀요. 정전은 예고 없는 강제 종료라 세이브가 깨질 수 있고, 공인 IP가 바뀌면 저장해 둔 주소가 전부 무효가 돼요. 둘 다 설정으로 넘는 문제가 아니라서, 상시로 갈 거면 전원과 회선이 따로 관리되는 머신이 필요해요.
호스팅에서는 이 셋이 각각 어디에 있나
위의 셋을 하나씩 옮겨 보면 이렇게 돼요.
첫째, 부팅 시 자동 실행은 아예 할 일이 아니에요. 머신과 게임 프로세스를 같이 맡기는 형태라 enable을 빼먹을 자리가 없어요. 둘째, 튕긴 프로세스는 자동으로 다시 떠요. 셋째, 매일 예약 재시작은 콘솔의 내 서버 상세에 스위치와 시각 두 칸으로 있어요. 시각을 새벽으로 잡아 두면 그 뒤로는 타이머 파일도, Persistent도 신경 쓸 게 없어요.
재시작 직전에 일어나는 일도 이 글에서 손으로 짠 순서 그대로예요. 게임 안에 서버 공지가 먼저 뜨고, 카운트다운이 끝나면 강제 저장을 하고 나서 내려가요. 그리고 세지 않았던 네 번째, 끊긴 걸 알아채는 쪽도 같은 페이지에 있어요. 프레임률과 접속 인원이 1분마다 기록되고 멈춰 있던 구간은 선이 끊겨서 보이니까, 어젯밤 몇 시에 무슨 일이 있었는지는 로그를 뒤지지 않아도 눈으로 확인돼요.
KeepWorlds의 팰월드 전용 서버에서 이 항목들이 놓인 자리가 그래요. 직접 구축하는 쪽을 택해도 확인할 목록은 똑같아요. enable 한 번, Restart 한 줄, 타이머 하나, 그리고 끊긴 걸 알아챌 수단 하나. 이 네 개를 각각 짚어 두면 적어도 "왜 꺼져 있는지 모르겠다"에서는 벗어나요.
반대로 아무도 없는 시간에 월드가 굳이 돌아가야 하느냐는 쪽이 질문이라면, 자동 일시정지와 그 대가에 정리해 뒀어요.