관리 메뉴

HAMA 블로그

Go 프로그램을 서비스로 만들기 (우분투16) 본문

Go

Go 프로그램을 서비스로 만들기 (우분투16)

[하마] 이승현 (wowlsh93@gmail.com) 2018. 2. 14. 15:50


[요약번역] https://fabianlee.org/2017/05/21/golang-running-a-go-binary-as-a-systemd-service-on-ubuntu-16-04/

1. SleepService  예제 만들기 

  1. package main
  2. import (
  3. "time"
  4. "log"
  5. "flag"
  6. "math/rand"
  7. "os"
  8. "os/signal"
  9. //"syscall"
  10. )
  11. func main() {
  12. // load command line arguments
  13. name := flag.String("name","world","name to print")
  14. flag.Parse()
  15. log.Printf("Starting sleepservice for %s",*name)
  16. // setup signal catching
  17. sigs := make(chan os.Signal, 1)
  18. // catch all signals since not explicitly listing
  19. signal.Notify(sigs)
  20. //signal.Notify(sigs,syscall.SIGQUIT)
  21. // method invoked upon seeing signal
  22. go func() {
  23. s := <-sigs
  24. log.Printf("RECEIVED SIGNAL: %s",s)
  25. AppCleanup()
  26. os.Exit(1)
  27. }()
  28. // infinite print loop
  29. for {
  30. log.Printf("hello %s",*name)
  31. // wait random number of milliseconds
  32. Nsecs := rand.Intn(3000)
  33. log.Printf("About to sleep %dms before looping again",Nsecs)
  34. time.Sleep(time.Millisecond * time.Duration(Nsecs))
  35. }
  36. }
  37. func AppCleanup() {
  38. log.Println("CLEANUP APP BEFORE EXIT!!!")
  39. }

$ ./sleepservice

이렇게 포그라운드에서 실행 시키면 SSH 터미널을 닫거나 하면 프로그램도 같이 죽어버린다.

2. systemd 서비스로 SleepService 만들기 

systemd 를 이용해서 서비스로 만들기 위해서는 “/lib/systemd/system/sleepservice.service” 아래에
다음과 같은 것을 만든다. 

[Unit]
Description=Sleep service
ConditionPathExists=/home/ubuntu/work/src/sleepservice/sleepservice
After=network.target
 
[Service]
Type=simple
User=sleepservice
Group=sleepservice
LimitNOFILE=1024

Restart=on-failure
RestartSec=10
startLimitIntervalSec=60

WorkingDirectory=/home/ubuntu/work/src/sleepservice
ExecStart=/home/ubuntu/work/src/sleepservice/sleepservice --name=foo

# make sure log directory exists and owned by syslog
PermissionsStartOnly=true
ExecStartPre=/bin/mkdir -p /var/log/sleepservice
ExecStartPre=/bin/chown syslog:adm /var/log/sleepservice
ExecStartPre=/bin/chmod 755 /var/log/sleepservice
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=sleepservice
 
[Install]
WantedBy=multi-user.target

위의 파일에서 사용된 패스들은 여러분의 경로에 맞게 수정 하면 될 것 이다.  
물론 sleepservice 라는 서비스 이름 자체도 말이다.

해당 프로그램 전용 사용자를 만들고 , 깃헙에서 만들어 둔것이 있으면 제대로 된 위치로 옮기고, 755 권한을 준다.

$ cd /tmp
$ sudo useradd sleepservice -s /sbin/nologin -M
$ wget https://raw.githubusercontent.com/fabianlee/blogcode/master/golang/sleepservice/systemd/sleepservice.service
$ sudo mv sleepservice.service /lib/systemd/system/.
$ sudo chmod 755 /lib/systemd/system/sleepservice.service

 systemctl 를 이용해서 sleepservice.service 를  enable 시키고 시작시키고, journalctl 을 통해 제대로 시작되는지 확인한다.

$ sudo systemctl enable sleepservice.service

$ sudo systemctl start sleepservice

$ sudo journalctl -f -u sleepservice

May 21 16:20:43 xenial1 sleepservice[4037]: 2017/05/21 16:20:43 hello foo
May 21 16:20:43 xenial1 sleepservice[4037]: 2017/05/21 16:20:43 About to sleep 1526ms before looping again
May 21 16:20:45 xenial1 sleepservice[4037]: 2017/05/21 16:20:45 hello foo
May 21 16:20:45 xenial1 sleepservice[4037]: 2017/05/21 16:20:45 About to sleep 196ms before looping again


번외) 

기존의 etc/init.d 를 이용해서 할 수도 있다. 

1) /etc/init.d 아래 스크립트 작성 (Golang 프로그램을 시작시키거나 멈추는 run 스크립트를 부팅시 호출 해준다.

#! /bin/sh
# /etc/init.d/myservice


USERNAME=who??
COMMAND_MYSERVICE_SCRIPT="/home/$USERNAME/myservice/run"


case "$1" in
  start)
    echo "Starting myservice .."
    sudo -u $USERNAME $COMMAND_MYSERVICE_SCRIPTstart
  
    echo "Done!!"
    ;;
  stop)
    echo "Stopping myservice .."
    sudo -u $USERNAME $COMMAND_MYSERVICE_SCRIPTstop
    echo "Done!!"
    ;;
  *)
    echo "Usage: /etc/init.d/myservice {start|stop}"
    exit 1
    ;;
esac

exit 0

권한설정

* sudo chmod 755 myservice

* update-rc.d 로 설정   ( sudo update-rc.d myservice defaults) 



Comments