Golang에서 리눅스 서비스 예제

간단하게 로그파싱하는거 우분투 백그라운드 서비스로 만들다가 리눅스 서비스 프로그램 golang으로 만드는거 여기에 간단하게 정리합니다.

package main

import (
    "log"
    "os"
    "os/signal"
    "time"
    //"syscall"
)

func main() {
    sigs := make(chan os.Signal, 1)
    //모든 시그널을 수신한다.
    signal.Notify(sigs)
    //특정 시그널만 수신한다.
    //signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT)

    go func() {
        s := <-sigs
        log.Printf("받은 시그널: %s\n", s)
        AppCleanup()
        os.Exit(1)
    }()

    //------------------------------------------------------------
    for {
        log.Println("2초마다 한번씩 출력됩니다.")
        time.Sleep(time.Millisecond * time.Duration(2000))
    }

}
func AppCleanup() {
    log.Println("앱이 종료되기 전에 정리할 작업을 여기서 한다.")
}

golang 서비스로 사용할 간단한 실행파일용 예제입니다.
14라인을 보면 전체 시그널 수신하도록 했는데 실제 사용할땐 특정 시그널만 수신하던지 아님 수신된 시그널에 맞게 처리하도록 해야 합니다.
예제는  시그널 받으면 종료하게 해서 맨 위의 스샷처럼 몇초 돌다가 시그널 받고 종료한뒤 서비스가 재시작 되는걸 볼 수 있습니다.

sudo useradd exampleLinuxService -s /sbin/nologin -M 
-M : 홈디렉토리를 생성하지 않음.
-s /sbin/nologin : 해당계정으로 로그인 불가능하고 메세지는 반환됨. (ssh는 사용불가이고 ftp의 경우엔 가능합니다)

exampleLinuxService 계정을 추가합니다.
서비스를 돌릴때 보통 해당 프로세스용으로 계정을 추가 해서 돌리는데 (보안상) 저는 서비스 이름과 같은걸로 만들었습니다.

sudo chown exampleLinuxService:exampleLinuxService ./exampleLinuxService
sudo chmod 744 ./exampleLinuxService

위의 Golang 소스를 빌드하고 테스트 우분투 서버에 업로드 한 뒤 744 권한과 소유자 권한을 변경합니다.

exampleLinuxService 파일의 실제 위치는 위 스샷처럼 /home/linsoo에 있습니다.

[Unit]
#서비스 설명
Description=example Linux Service
#파일이 존재하는지 절대 경로로 된곳에 없으면 실패처리
ConditionPathExists=/home/linsoo/exampleLinuxService
#network가 커널에서 로드 된 이후
After=network.target

[Service]
#해당 서비스를 굴릴 계정과 그룹
User=exampleLinuxService
Group=exampleLinuxService

#restart 조건 (on-failure : 오류발생시 재시작, always : 항상)
Restart=on-failure
#재시작 간격 10초 (단위 표기가 없음 초단위, 5min 20s : 5분 20초, 100ms : 0.1초)
RestartSec=10

#작업경로
WorkingDirectory=/home/linsoo/
#실행파일 경로
ExecStart=/home/linsoo/exampleLinuxService
ExecStop=/home/linsoo/exampleLinuxService

#로그파일 생성에 관련된 설정
PermissionsStartOnly=true
ExecStartPre=/bin/mkdir -p /var/log/exampleLinuxService
ExecStartPre=/bin/chown syslog:adm /var/log/exampleLinuxService
ExecStartPre=/bin/chmod 755 /var/log/exampleLinuxService
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=exampleLinuxService

[Install]
WantedBy=multi-user.target

위 내용을 /lib/systemd/system/exampleLinuxService.service 파일로 저장합니다.

sudo chmod 644 /lib/systemd/system/exampleLinuxService.service

exampleLinuxService.service 파일에 644 권한을 줍니다

sudo systemctl enable exampleLinuxService.service 
sudo systemctl start exampleLinuxService

위 명령으로 서비스를 활성화 시킨뒤

sudo journalctl -f -u exampleLinuxService

위 명령을 내리면 맨 위의 스샷 처럼 서비스가 구동되는 모습을 볼 수 있습니다.

 

참고 : https://www.freedesktop.org/software/systemd/man/systemd.unit.html
https://fabianlee.org/2017/05/21/golang-running-a-go-binary-as-a-systemd-service-on-ubuntu-16-04/

크리에이티브 커먼즈 라이선스 Linsoo 의 저작물인 이 저작물은(는) 크리에이티브 커먼즈 저작자표시-동일조건변경허락 4.0 국제 라이선스에 따라 이용할 수 있습니다.

댓글 달기

이메일 주소는 공개되지 않습니다.

This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.