서버 프로세스를 관리하는 올바른 방법
웹 사이트 개발을 완료하고 서비스할 프로덕션을 서버에 배치할 때 고민하게 되는 문제 중 하나가 서버에서 띄워야 하는 여러 가지 프로세스들을 어떻게 띄울 것인가 하는 문제다.
프로세스라 죽으면 다시 띄우는 것도 물론 필요하다.
init
올바른 방법은 OS의 init 시스템, 혹은 그와 유사한 대안 시스템을 사용하는 것이다.
init은 유닉스에서 부팅될 때 첫번째로 만들어지는 프로세스다.
그래서 프로세스 번호가 1이고, 이후 모든 프로세스는 init 프로세스의 자손이고, 시스템이 부팅될 때 뜨는 모든 프로세스는 init 프로세스가 띄우게 된다.
그렇기에 서버에 프로레스를 띄워야 한다면 init에 맡기는 것이 자연스럽다.
하지만 init 시스템은 낡고 문제점이 있어 사라져 가고 있다. 이미 init → upstart → systemd로 방향을 잡았다.
upstart
upstart는 /etc/init에 스크립트를 넣으면 실행할 수 있다.
# 태스크 큐로 널리 쓰이는 celery의 예
celery -A myapp.tasks worker -1 INFO -E
# /etc/init/celery.conf
===============
# Celery
description "Celery Worker"
start on runlevel [2345]
stop on runlevel [06]
respawn limit 10 5
script
chdir /home/ubuntu/myproject
exec sudo -uwebuser celery -A myapp.tasks worker -l INFO -E > /home/ubuntu/logs/celery.log 2>&1
end script
# init과 달리 실행 권한을 줄 필요 없다.
sudo start[stop/restart] celery
systemd
# /etc/systemd/system/redis.service
========================
[Unit]
Description=Redis In Memory Data store
After=network.target
[Service]
User=root
Group=root
ExecStart=/opt/redis/redis-5.0.7/src/redis-server /opt/redis/redis.conf
ExecStop=/opt/redis/redis-5.0.7/src/redis-cli shutdown
Restart=always
Type=notify
[Install]
WantedBy=multi-user.target
sudo systemctl start[stop/restart] redis
systemd 등장 이유
init의 가장 큰 단점은 태스크가 병렬로 실행된다는 것이다. 그래서 I/O가 있는 작업이 많으면 부팅 속도가 느려졌다.
그래서 upstart는 이벤트 기반으로 작성되어 비동기로 작업을 처리한다.
upstart는 의존성을 설정할 수 있어서 서비스 간에 의존성이 설정되어 있으면 의존성 순서대로 실행이 된다.
기껏 비동기 로직을 적용했는데 결국 직렬화를 해야 하니 성능상의 이득이 줄어든다.
그리고, 당장 필요하지 않은 서비스도 올려두게 되므로 처음부터 많은 프로세스가 뜨게 된다.
systemd는 많은 서비스가 on-demand로 뜰 수 있다.
예를 들어 sshd는 부팅할 때 띄우지 않고 있다가 22번 포트로 요청이 오면 그때 띄우는 것이다.
의존성도 이런 식으로 설정된다. 그러니까 부팅 속도도 빠르고, 불필요한 서비스는 올라가지 않아서 시스템 자원도 아낀다.
systemd service 파일 작성
[Install]
Install 섹션은 systemctl enable [service name]으로 VM 구동 시 서비스가 자동으로 구동되도록 할 때 이용하는 섹션이다.
- WantedBy : 이 서비스가 어떤 전제조건 하에서 실행되는 지를 결정하는 프로퍼티이다.
[Service]
- Type : 서비스가 어떤 형태로 구동될 것인가를 결정
- simple : default value. ExecStart로 구동시 해당 서비스의 메인 프로세스로 구동된다
- forking : ExecStart로 구동시 자식 프로세스를 생성하고, 자식 프로세스가 해당 서비스의 메인 프로세스로 구동된다. 부모 프로세스는 완전히 구동될 때까지만 존재한다.
'Develope > Linux' 카테고리의 다른 글
[Ubuntu Linux] MAC에서 Ubuntu Linux 설치하기 (0) | 2021.01.29 |
---|