서비스(데몬) 자동 시작 설정 방법은 3가지가 있다.
- rc.local에 얹기
- 데몬 하나 정도는 괜찮지만 2개부터는 관리가 안됨
- systemctl에 새로 등록 (systemd)
- 해당 데몬을 위한 서비스를 새로 만들어서 관리
- CentOS7이상, Ubuntu에서 사용
- chkconfig에 등록
- CentOS6이하에서도 가능
나는 OS를 Rocky 8을 사용중이므로 systemctl에 서비스를 새로 등록하는 방법으로 진행하겠다.
- 목적 : 서버 재부팅 시 Root가 아닌 일반 사용자(jmpark)으로 서비스 데몬 자동 시작
- 테스트 OS : Rocky8.10
- 서비스 관리 명령어 : systemctl
- runServer.sh : 실행 파일을 위에서 설정한 환경 변수들을 인자로 전달하여 백그라운드에서 실행하는 스크립트
runServer.sh는 내가 사용하는 스크립트이므로
데몬 자동시작 테스트할 스크립트 rebootTest.sh를 만들어서 이해하면 좋을듯!
rebootTest.sh는 하단에 참고한 블로그에 나와있는 내용임을 밝힙니다.
# 데몬 자동시작 테스트할 스크립트 rebootTest.sh 작성
테스트 스크립트 작성
- 실제 스크립트를 만들기 전에 작동하는지 테스트하기 위한 스크립트를 작성
- /app/server/bin 위치에 rebootTest.sh 를 만듦 (위치는 알아서 상황에 맞게)
- 실행시 현재시간을 기록하는 스크립트 작성
[jmpark@localhost bin]$ cat rebootTest.sh
#!/bin/sh
date >> /logs/server/date_log.txt
- 스크립트 실행 권한 부여 (rw-r--r-- --> rwxr-xr--)
[jmpark@localhost bin]$ chmod 754 rebootTest.sh #chmod +x rebootTest.sh 로 권한 부여 가능
[jmpark@localhost bin]$ ll
합계 48
-rwxr-xr--. 1 jmpark jmpark 47 8월 2 12:55 rebootTest.sh
-rwxr-x---. 1 jmpark root 186 4월 15 22:14 restartServer.cmd
-rwxr-x---. 1 jmpark root 205 4월 15 22:14 restartServer.sh
-rwxr-x---. 1 jmpark root 9948 7월 27 00:06 rtim-server
-rwxr-x---. 1 jmpark root 7065 7월 27 00:06 rtim-server.bat
-rwxr-x---. 1 jmpark root 1090 4월 15 22:14 runServer.cmd
-rwxr-x---. 1 jmpark root 1155 4월 15 22:14 runServer.sh
-rwxr-x---. 1 jmpark root 183 4월 15 22:14 stopServer.cmd
-rwxr-x---. 1 jmpark root 202 4월 15 22:14 stopServer.sh
- 스크립트 실행
[jmpark@localhost bin]$ sh rebootTest.sh
[jmpark@localhost bin]$ cat /logs/server/date_log.txt
2024. 08. 02. (금) 13:21:55 KST
잘 실행된 걸 확인 할 수 있음!
# systemd에 등록하여 systemctl에서 관리가 가능하도록 설정
- systemd 경로 : /etc/systemd
- 서비스 이름 : server (서비스 이름은 알아서 정하면 됨)
- /etc/systemd/system 경로에 server.service를 만들고 설정 (만들 때 당연히 root 사용자로 파일 만들어야 함)
- systemd는 유닛 파일이 실행 가능한 파일이 되어서는 안됨
- 권한은 644를 기본으로 하며, 이와 다를 경우 보안상 취약한 상태
[root@localhost ~]# cd /etc/systemd/system/
[root@localhost system]# vi server.service
[Unit]
Description=Run RTIM Server as jmpark user
[Service]
Type=forking
User=jmpark
WorkingDirectory=/app/server/bin
ExecStart=/bin/bash /app/server/bin/runServer.sh
Restart=on-failure
[Install]
WantedBy=multi-user.target # 시스템 부팅 시 대부분의 서비스가 실행되는 기본 대상을 의미
## Service Type 설정
개인적인 생각이지만 service 타입 설정이 제일 중요한 듯, 구동시키는 스크립트가 어떤 기능을 하는지에 따라 설정해줘야 한다. 아니면 백날천날 안됨.
- simple:
- 기본값으로, ExecStart에 설정된 프로그램이 즉시 실행되고, 그 프로그램이 실행 중인 상태로 간주됩니다.
- 이 타입은 프로그램이 포그라운드에서 실행될 때 사용합니다. 만약 runServer.sh가 포그라운드에서 실행되고, 해당 프로세스가 종료되지 않는다면 이 타입을 사용할 수 있습니다.
- forking:
- ExecStart에서 실행된 프로세스가 자식 프로세스를 생성하고, 부모 프로세스가 종료되는 경우에 사용합니다.
- 만약 runServer.sh가 서버를 데몬 형태로 실행하고, 부모 프로세스가 종료되며 자식 프로세스가 계속 실행된다면 이 타입을 선택해야 합니다.
- oneshot:
- 주로 초기화 작업이나 설정을 위해 사용되며, 스크립트가 실행된 후 종료되더라도 서비스가 활성 상태로 간주되도록 합니다.
- 만약 runServer.sh가 서버를 실행한 후에 종료된다면 이 타입을 사용할 수 있지만, 일반적으로 서버 프로그램은 지속적으로 실행되므로 적합하지 않을 수 있습니다.
나의 경우는 runServer.sh가 rtim-server를 백그라운드에서 실행하는 방식으로 설정되어 있기 때문에,
'forking'으로 설정하는 것이 적합했다. forking은 부모 프로세스가 종료되고 자식 프로세스가 지속적으로 실행되기 때문..
단순한 로그를 남기는 rebootTest.sh는 'simple'을 사용하면 된다.
## User 설정
OS는 기본적으로 reboot시 root로 실행시키기 때문에 여기서 데몬을 구동시킬 사용자를 명시해주면 됨
- 물론 여기서 설정한 사용자는 WorkingDirectory나 ExecStart에서 설정한 경로와 스크립트에 접근 실행 권한을 모두 가지고 있어야 함, 필요에 따라 소유자도 변경
## ExecStart 설정
구동시킬 스크립트 적는 명령어
- Environment를 통해 환경변수를 설정하고 경로에 환경변수를 이용할 수 도 있고
/bin/bash -c "/app/server/bin/rebootTest.sh start"
이런 식으로 다양하게 적을 수 있음
## Restart 설정
Restart=on-failure는 서버가 의도치 않게 비정상적으로 종료되었을 때 자동으로 재시작하는 설정이고
비정상 종료된 기준이 궁금하면 접은 글 펴보세욥
- 프로세스가 비정상적으로 종료된 경우:
- 프로세스가 exit 코드 0이 아닌 값으로 종료되거나, SIGKILL (kill -9)와 같은 신호로 강제 종료된 경우를 말합니다. 즉, 프로세스가 예기치 않게 종료된 경우입니다.
- 예를 들어, kill -9 pid와 같은 명령어로 프로세스를 종료하면, systemd는 이를 비정상 종료로 간주합니다.
- 정상 종료와 비정상 종료:
- 정상적으로 종료된 경우는 exit 0 코드를 반환하는 경우입니다. 예를 들어, systemctl stop server.service를 통해 서비스가 정상적으로 중지되면 systemd는 이를 정상 종료로 간주합니다.
- reboot 명령어로 시스템이 재부팅될 경우에도 서비스는 비정상 종료로 간주되지 않습니다. systemd는 서비스가 시스템 종료 또는 재부팅 중에 중지되었음을 인식하고, 이를 정상적인 종료로 처리합니다.
- ExecStop과 관련된 스크립트:
- stopServer.sh와 같은 스크립트를 통해 서버를 정지하는 경우, 해당 스크립트가 정상적으로 실행되고 종료되면 systemd는 이를 정상 종료로 간주합니다. 이 경우, 스크립트가 종료 코드 0을 반환해야 합니다.
# workingDirecory
- 작업 디렉토리 설정:
- WorkingDirectory는 실행할 명령어가 사용해야 할 기본 작업 디렉토리를 지정합니다. 이는 명령어가 상대 경로로 파일을 찾거나 생성할 때 기준이 되는 디렉토리입니다.
- 예를 들어, ExecStart에 명시된 경로가 절대 경로일지라도, 실행 중에 발생하는 파일 작업은 WorkingDirectory에서 상대적으로 처리됩니다.
- 파일 접근 문제 방지:
- 명령어가 실행될 때, 해당 명령어가 사용하는 파일이나 리소스가 WorkingDirectory에 있을 경우, 상대 경로로 접근할 수 있습니다. 만약 WorkingDirectory가 설정되어 있지 않다면, 기본적으로 /(루트 디렉토리)에서 실행되므로 파일을 찾지 못할 수 있습니다.
- 스크립트나 프로그램의 통일성:
- 여러 스크립트나 프로그램이 동일한 작업 디렉토리를 사용해야 할 경우, WorkingDirectory를 통해 일관된 작업 환경을 제공할 수 있습니다. 이는 특히 복잡한 애플리케이션에서 유용합니다.
- WorkingDirectory=/app/server: 이 설정으로 인해, rtim-server가 실행될 때 기본 작업 디렉토리는 /app/server가 됩니다.
- ExecStart=/app/server/bin/rtim-server start: 이 경로는 명령어의 절대 경로입니다.
이 경우, 만약 rtim-server가 상대 경로로 파일에 접근해야 한다면, /app/server를 기준으로 하게 됩니다. 따라서, 파일 작업이 더 원활하게 이루어질 수 있습니다.
# 서비스 등록 여부 확인 및 자동시작 설정
- 등록한 서비스 보이는지 확인
[root@localhost system]# systemctl status server
● server.service - when reboot, server.service auto start to user
Loaded: loaded (/etc/systemd/system/server.service; disabled; vendor preset: disabled)
Active: inactive (dead)
[jmpark@localhost ~]$ systemctl enable server
# systemctl 명령어로 시스템 돌려보기
[jmpark@localhost ~] su -
암호:
[root@localhost ~]# systemctl start server
[root@localhost ~]# ps -ef | grep Main
jmpark 928 1 0 15:06 ? 00:00:08 java -Xms1024m -Xmx1024m -XX:NewSize=256m -XX:MaxNewSize=256m -XX:SurvivorRatio=8 -verbose:gc -Xloggc:../logs/gc.log -XX:+PrintGCTimeStamps -XX:-TraceClassUnloading -XX:+PrintHeapAtGC -Djava.net.preferIPv4Stack=true -DPROV -classpath /app/server/conf
구동 확인 됨. rebbot 해서 동일한 명령어로 다시 확인하면 끝!
나같은 경우는 Server 구동됬는지 ps -ef로 확인 했지만
rebootTest.sh로 설정한 사람들은 /logs/server/date_log.txt에 로그가 잘 쌓였는지 확인하면 됨
참고한 블로그 ( 그대로 따라해도 안되는 망고매직.. )
'OS' 카테고리의 다른 글
[Mac] 사용자 추가 및 홈 디렉토리 설정 (0) | 2024.08.04 |
---|