Rubby 스크립트의 서비스화(systemd+rvm+사용자 권한으로 실행)

10544 단어 Ruby

개시하다


Raspberry Pi3 소프트웨어 UART 활용에서 제작된 GPS 로그용 스크립트가 예상외로 불안정해 예외적으로 프로그램이 끝나도 재부팅systemd을 시도했다.

전제 조건

  • rvm환경
  • 사용자 권한 서비스 루비 스크립트 사용

  • 활용 systemd
  • Goal

  • 예기치 않은 오류로 GPS 로그용 스크립트가 떨어져도 재부팅
  • rvm 공식 문서 보기


    '보글'은 공식 아래 페이지인데 너무 대략적인 설명을 해서 잘 모르겠어요. 그래서 제가 더듬어 봤어요.
    또한 정식 순서는 크론 등에서도 사용할 수 있을 것 같다

    절차.


    기본적으로 다음과 같은 절차다.
  • rvm를 제작한 wrapper
  • 시스템에 대한 Unit 정의 파일 생성
  • wrapper를 통해 ExecStart에서 스크립트 실행
  • rvm를 만드는 wrapper


    우선 rmv의 경로를 확인하세요.
    pi@raspberrypi:~ $ echo $rvm_path
    /home/pi/.rvm
    
    그 경로 아래에 있는 wrappers 새 Gem 그룹?, 신중을 기하기 위해 먼저 봅시다.
    pi@raspberrypi:~ $ ll ~/.rvm/wrappers/
    total 0
    lrwxrwxrwx 1 pi pi 33 Jul 18 16:22 default -> /home/pi/.rvm/wrappers/ruby-2.7.1
    lrwxrwxrwx 1 pi pi 38 Jul 18 16:22 ruby-2.7.1 -> /home/pi/.rvm/gems/ruby-2.7.1/wrappers
    lrwxrwxrwx 1 pi pi 45 Jul 18 16:22 ruby-2.7.1@global -> /home/pi/.rvm/gems/ruby-2.7.1@global/wrappers
    
    다음 명령을 사용하여 Gem 세트를 생성합니다.이번에 gps라는 이름으로 만들어 봤어요.공식 기록에 따르면 왜 gps와 응용명 지정에 두 개가 필요한지 모르겠다...
    pi@raspberrypi:~ $ rvm alias create gps ruby-2.7.1@gps
    Gemset 'gps' does not exist, 'rvm ruby-2.7.1 do rvm gemset create gps' first, or append '--create'.
    Creating alias gps for ruby-2.7.1.....
    
    역시 오류는 있겠지만 아래 방법대로 잘 만들어졌으니 그만두자
    pi@raspberrypi:~ $ ll ~/.rvm/wrappers/
    total 0
    lrwxrwxrwx 1 pi pi 33 Jul 18 16:22 default -> /home/pi/.rvm/wrappers/ruby-2.7.1
    lrwxrwxrwx 1 pi pi 33 Jul 19 20:01 gps -> /home/pi/.rvm/wrappers/ruby-2.7.1
    lrwxrwxrwx 1 pi pi 38 Jul 18 16:22 ruby-2.7.1 -> /home/pi/.rvm/gems/ruby-2.7.1/wrappers
    lrwxrwxrwx 1 pi pi 45 Jul 18 16:22 ruby-2.7.1@global -> /home/pi/.rvm/gems/ruby-2.7.1@global/wrappers
    

    시스템용 Unit 정의 파일 만들기


    나머지는 보통대로 만드는 것뿐이다.이번 내용은 다음과 같다.WorkingDirectory에서 스크립트가 있는 디렉터리를 지정하고 ExecStart에서 wrapper를 통해 bundle 명령을 실행합니다.Restart=always 중요
    pi@raspberrypi:~ $ cat /etc/systemd/system/gps.service
    [Unit]
    Description=Gps Service
    After=network.target
    
    [Service]
    Type=simple
    User=pi
    Group=pi
    WorkingDirectory=/home/pi/project/gps
    ExecStart=/home/pi/.rvm/wrappers/gps/bundle exe ruby main.rb
    Restart=always
    
    [Install]
    WantedBy=multi-user.target
    

    스크립트를 살짝 수정합니다.


    가공 작업에 logger와 예외적인 드랍 처리를 추가했습니다.
    require 'serialport'
    require 'nmea_plus'
    require 'logger'
    
    logger = Logger.new('gps.log')
    
    logger.info '起動したよ'
    
    puts `sudo rmmod soft_uart.ko`
    sleep 0.1
    puts `cd ~/project/soft_uart && sudo insmod soft_uart.ko`
    
    sp = SerialPort.new('/dev/ttySOFT0', 9600, 8, 1, 0) # see: https://rubydoc.info/gems/serialport/SerialPort#set_modem_params-instance_method
    
    trap 'SIGINT' do
      sp.close if sp
      exit
    end
    
    count = 0
    
    source_decorder = NMEAPlus::SourceDecoder.new(sp)
    source_decorder.each_complete_message do |message|
      # カウントアップ
      count +=1
    
      # see: https://github.com/ianfixes/nmea_plus/blob/master/lib/nmea_plus/message/nmea/rmc.rb
      if 'GPRMC' == message.data_type
        logger.info message.utc_time
        logger.info message.active? # false: データ無効
        logger.info message.latitude
        logger.info message.longitude
        logger.info message.faa_mode # A: 単独測位(精度3m程度), D: 相対測位(精度0.4m程度) 
      end
    
      if count >= 10
        sp.close # とりあえず閉じてみる
        logger.error '落とすよ'
        raise '強引なエラー' 
      end
    end
    
    

    확인


    시스템 자체를 다시 불러온 다음 서비스를 시작합니다.
    sudo systemctl daemon-reload
    sudo systemctl start gps.service
    
    일지.. 괜찮은 것 같아!
    이렇게 불안정한 각본이 좀 강한 아이가 됐어요.
    pi@raspberrypi:~ $ tail -f ./project/gps/gps.log
    I, [2020-07-19T20:59:05.521956 #6437]  INFO -- : 起動したよ
    I, [2020-07-19T20:59:06.651867 #6437]  INFO -- : 2020-07-19 11:59:06 +0000
    I, [2020-07-19T20:59:06.652419 #6437]  INFO -- : true
    I, [2020-07-19T20:59:06.652937 #6437]  INFO -- : 33.725631666666665
    I, [2020-07-19T20:59:06.653450 #6437]  INFO -- : 131.64383833333332
    I, [2020-07-19T20:59:06.654003 #6437]  INFO -- : A
    I, [2020-07-19T20:59:07.652485 #6437]  INFO -- : 2020-07-19 11:59:07 +0000
    I, [2020-07-19T20:59:07.653032 #6437]  INFO -- : true
    I, [2020-07-19T20:59:07.653515 #6437]  INFO -- : 33.725631666666665
    I, [2020-07-19T20:59:07.654019 #6437]  INFO -- : 131.64384
    I, [2020-07-19T20:59:07.654624 #6437]  INFO -- : A
    E, [2020-07-19T20:59:07.694013 #6437] ERROR -- : 落とすよ
    I, [2020-07-19T20:59:12.530348 #6460]  INFO -- : 起動したよ
    I, [2020-07-19T20:59:13.660674 #6460]  INFO -- : 2020-07-19 11:59:13 +0000
    I, [2020-07-19T20:59:13.661174 #6460]  INFO -- : true
    I, [2020-07-19T20:59:13.661502 #6460]  INFO -- : 33.72563
    I, [2020-07-19T20:59:13.661792 #6460]  INFO -- : 131.64383666666666
    I, [2020-07-19T20:59:13.662027 #6460]  INFO -- : A
    I, [2020-07-19T20:59:14.660078 #6460]  INFO -- : 2020-07-19 11:59:14 +0000
    I, [2020-07-19T20:59:14.660613 #6460]  INFO -- : true
    I, [2020-07-19T20:59:14.660962 #6460]  INFO -- : 33.72562833333333
    I, [2020-07-19T20:59:14.661288 #6460]  INFO -- : 131.64383666666666
    I, [2020-07-19T20:59:14.661528 #6460]  INFO -- : A
    E, [2020-07-19T20:59:14.662166 #6460] ERROR -- : 落とすよ
    

    감상

  • rbenv와 rvm 중 어느 것이 더 편리합니까?
  • 정식 문서가 너무 대략적이어서 모르는 점이 있다...
  • 좋은 웹페이지 즐겨찾기