Как сделать сервис upstart для Rserve?

Мне нужно запустить и продолжить работу rserve с R.

У меня есть эти строки в моем файле rserve.r:

library(Rserve)
Rserve()

Итак, я пытаюсь сделать что-то подобное в своем сценарии выскочки:

description "Rserve service"
author      "Valter Silva"

start on filesystem or runlevel [2345]
stop on shutdown

respawn

script
    echo $$ > /var/run/rserve.pid
    exec /usr/bin/R /home/valter/R/rserve.R >> /home/valter/test2.log
end script


pre-start script
    echo "[`date`] Rserve Starting" >> /var/log/rserve.log
end script

pre-stop script
    rm /var/run/rserve.pid
    echo "[`date`] Rserve Stopping" >> /var/log/rserve.log
end script

Я знаю, что служба работает из-за вывода моего файла test2.log. Но запускается только один раз. Что мне делать, чтобы он продолжал работать?


person Valter Silva    schedule 09.09.2015    source источник
comment
Что вы имеете в виду, говоря, что он запускается только один раз?   -  person Steven Beaupré    schedule 09.09.2015
comment
@StevenBeaupré, если я запущу командную строку R и дам команды library(Rserve) и Rserve(); Rserve остается в списке процессов Linux. Но если я попытаюсь сделать это в своем выскочке, ничего не произойдет.   -  person Valter Silva    schedule 09.09.2015
comment
Попробуйте запустить его с помощью R CMD Rserve вместо этого? (см. rforge.net/Rserve/doc.html#start)   -  person Steven Beaupré    schedule 09.09.2015
comment
Я пробовал это, но это дает мне следующую ошибку: /usr/lib/R/bin/Rcmd: 62: exec: Rserve: not found.   -  person Valter Silva    schedule 09.09.2015
comment
@ValterHenrique проверьте этот вопрос: stackoverflow .com/questions/24370980/   -  person jangorecki    schedule 26.11.2015


Ответы (2)


Причина, по которой у вас (и у меня) столько проблем, заключается в том, что мы задаем неправильный вопрос. Правильный вопрос: «как мы можем запустить Rserve из нашего клиентского кода?». Java-клиенты (и большинство других) имеют возможность запускать Rserve.

Ответ на этот вопрос находится здесь для библиотеки Java: Как запустить Rserve автоматически из Java?

или здесь для библиотеки C#: https://github.com/SurajGupta/RserveCLI2/blob/master/RServeCLI2.Test/Rservice.cs


Другой подход — учиться у лучшего. Проект Rocker копирует supervisor.conf в /etc/supervisor/conf.d/ (см. https://github.com/rocker-org/rocker/blob/master/rstudio/Dockerfile#L61)

ваш supervisor.conf может добавить что-то вроде

[program:Rserve]
command=/usr/bin/Rserve.sh
stdout_logfile=/var/log/supervisor/%(program_name)s.log
stderr_logfile=/var/log/supervisor/%(program_name)s.log
user=myuser
startsecs=0
autorestart=false
exitcodes=0

НО... Я разобрался. Итак, вот ответ. Прошу прощения, что немного коряво и расплывчато. Для меня самым большим препятствием было размещение моих сценариев запуска/остановки в папке /usr/bin (см. обсуждение ниже).

/etc/init/Rserve.conf

description "Rserve service"
author "Victor I. Wood"
version "0.01"

# based on
# https://stackoverflow.com/questions/32485131/how-to-make-an-upstart-service-to-rserve

env STARTSCRIPT=/usr/bin/Rserve.sh
env STOPSCRIPT=/usr/bin/Rserve.stop
env LOGFILE=/var/log/Rserve.log


start on runlevel [2345]
stop on runlevel [!2345]

console output

respawn

# tell upstart we're creating a daemon
# upstart manages PID creation for you.
expect fork


pre-start script
    echo "[`date`] Rserve Starting" >> $LOGFILE
    echo $$ > /var/run/Rserve.pid
end script

pre-stop script
    rm /var/run/Rserve.pid
    echo "[`date`] Rserve Stopping" >> $LOGFILE
    exec $STOPSCRIPT >> $LOGFILE
end script


script
        # My startup script, plain old shell scripting here.
        exec $STARTSCRIPT >> $LOGFILE
#       echo $$ > /var/run/rserve.pid
end script

/usr/bin/Rserve.sh

#!/bin/sh
sudo --login --set-home --user=myuser bash -c '~/Rserve.sh >~/Rserve.log 2>&1'

/usr/bin/Rserve.stop

#!/bin/sh
pkill -U myuser Rserve

/home/myuser/Rserve.sh

#!/bin/sh

# launch new Rserve process
R CMD Rserve --RS-conf /home/myuser/Rserve.conf --no-save >~/Rserve.log 2>&1

https://askubuntu.com/questions/62812/why-isnt-my-upstart-service-starting-on-system-boot?lq=1

Я начал со сценария по адресу https://askubuntu.com/questions/62729/how-do-i-set-up-a-service?lq=1 и отметил начало initctl, которое может пригодиться для отладки.

https://askubuntu.com/questions/62812/why-isnt-my-upstart-service-starting-on-system-boot?lq=1 отметил, что скрипт должен находиться в /bin (но я использовал /usr/bin) и должен принадлежать root . Некоторым людям нравится использовать ссылку на скрипт в другом месте для скрипта i /bin

как люди здесь, в Как сделать службу upstart для Rserve? предложил, я использую команду запуска Rserve, которую я нашел в документации rServe

R CMD Rserve

хотя я расширил свой до

R CMD Rserve --RS-conf /home/myuser/Rserve.conf --no-save >~/Rserve.log 2>&1

Я не экспортирую правильный pid, поэтому я останавливаю его с помощью pkill. Более изящный подход был бы

RSshutdown(rsc)

Как я могу корректно закрыть Rserve?

stdout и stderr сбивают с толку выскочку, поэтому перенаправьте весь вывод с помощью 2>&1 Как перенаправить stdout и stderr в файл

Я примерно понял это к тому времени, когда нашел https://www.digitalocean.com/community/tutorials/the-upstart-event-system-what-it-is-and-how-to-use-it и https://geeknme.wordpress.com/2009/10/15/getting-started-with-upstart-in-ubuntu/ http://blog.joshsoftware.com/2012/02/14/upstart-scripts-in-ubuntu/, но для тех, кто просто хочет начать, это более практичная отправная точка, чем официальная документация.


Обновлять

Это решение предполагает Upstart, который был первоначальным вопросом, но Upstart больше не является диспетчером служб по умолчанию. Если вы хотите сделать это в системах после 16.04, вернитесь к Upstart с помощью

sudo apt-get install upstart-sysv
sudo update-initramfs -u
sudo apt-get purge systemd

(из http://notesofaprogrammer.blogspot.com/2016/09/running-upstart-on-ubuntu-1604-lts.html)

person woodvi    schedule 01.02.2016

Как говорится в общедоступной документации Rserve, вы можете запустить демон Rserve из сценария оболочки.

Просто создайте скрипт, который выполняет следующую команду:

echo 'library(Rserve);Rserve(FALSE,args="--no-save --slave --RS-conf <your_own_path>/rserve.conf")'|<R_bin_path>/R --no-save --slave

Например, на моем компьютере с MacOS я могу запустить Rserve, выполнив эту строку:

/bin/sh -c "echo 'library(Rserve);Rserve(FALSE,args=\"--slave\")'|/Library/Frameworks/R.framework/Versions/3.2/Resources/bin/exec/R --no-save --slave"

Эта команда выводит что-то вроде этого:

Starting Rserve:
  /Library/Frameworks/R.framework/Resources/bin/R CMD /Library/Frameworks/R.framework/Versions/3.2/Resources/library/Rserve/libs//Rserve --slave 

Rserv started in daemon mode.

Обязательно укажите параметр «--slave» при запуске Rserve.

Вы можете создать сценарий оболочки (или сценарий Windows) и указать ОС выполнять этот сценарий во время процесса запуска.

person jfcorugedo    schedule 23.09.2015