【问题标题】:Linux: process into a serviceLinux:处理成服务
【发布时间】:2014-04-15 16:13:10
【问题描述】:

我正在尝试将 linux 可执行文件作为服务

我像下面这样执行我的程序

java -jar mytestprogram.jar

创建一个持续运行并为 REST 请求提供服务的进程。但我想将它作为我可以做的服务运行

service mytestprogram start
service mytestprogram stop
service mytestprogram status
chkconfig mytestprogram on

等等。最简单的方法是什么?

【问题讨论】:

  • 没有单一的方法可以做到这一点:这完全取决于特定的 Linux 发行版和它附带的服务管理守护进程。主要的是 System V、upstart 和按时间线划分的 systemd。选择与您的分布最匹配的一种。教程如下:digitalocean.com/community/tutorials/…

标签: linux service process


【解决方案1】:

在 Ubuntu 中,您可以按照上面的说明用几行代码创建文件,试一试,看看它是否适合您。

description "My prog"
 
 
start on (net-device-up
          and local-filesystems
          and runlevel [2345])

stop on runlevel [!2345]
 
respawn
respawn limit 10 5
 
setuid root
setgid shnmon
 
script
    /usr/local/bin/my_script -config.path /etc/myprog/yourconfig.xyz -children false >> /var/log/myprog.log 2>&1
end script

如果您有配置文件,则“-config.path /etc/myprog/yourconfig.xyz”是可选的。

您可以只编辑脚本部分并对其进行测试,并将其他部分保持默认并在此过程中编辑其余部分

【讨论】:

    【解决方案2】:

    这是一个示例 shell 脚本(确保将 MAT 名称替换为您的应用程序的名称):

    我用我的脚本的最新版本和一个简短的解释创建了一个 GitHubGist,以帮助那些需要它的人。 GitHub Gist link

    #!/bin/bash
    
    ### BEGIN INIT INFO
    # Provides:                 MATH
    # Required-Start:           $java
    # Required-Stop:            $java
    # Short-Description:        Start and stop MATH service.
    # Description:              -
    # Date-Creation:            -
    # Date-Last-Modification:   -
    # Author:                   -
    ### END INIT INFO
    
    # Variables
    PGREP=/usr/bin/pgrep
    JAVA=/usr/bin/java
    ZERO=0
    
    # Start the MATH
    start() {
        echo "Starting MATH..."
        #Verify if the service is running
        $PGREP -f MATH > /dev/null
        VERIFIER=$?
        if [ $ZERO = $VERIFIER ]
        then
            echo "The service is already running"
        else
            #Run the jar file MATH service
            $JAVA -jar /opt/MATH/MATH.jar > /dev/null 2>&1 &
            #sleep time before the service verification
            sleep 10
            #Verify if the service is running
            $PGREP -f MATH  > /dev/null
            VERIFIER=$?
            if [ $ZERO = $VERIFIER ]
            then
                echo "Service was successfully started"
            else
                echo "Failed to start service"
            fi
        fi
        echo
    }
    
    # Stop the MATH
    stop() {
        echo "Stopping MATH..."
        #Verify if the service is running
        $PGREP -f MATH > /dev/null
        VERIFIER=$?
        if [ $ZERO = $VERIFIER ]
        then
            #Kill the pid of java with the service name
            kill -9 $($PGREP -f MATH)
            #Sleep time before the service verification
            sleep 10
            #Verify if the service is running
            $PGREP -f MATH  > /dev/null
            VERIFIER=$?
            if [ $ZERO = $VERIFIER ]
            then
                echo "Failed to stop service"
            else
                echo "Service was successfully stopped"
            fi
        else
            echo "The service is already stopped"
        fi
        echo
    }
    
    # Verify the status of MATH
    status() {
        echo "Checking status of MATH..."
        #Verify if the service is running
        $PGREP -f MATH > /dev/null
        VERIFIER=$?
        if [ $ZERO = $VERIFIER ]
        then
            echo "Service is running"
        else
            echo "Service is stopped"
        fi
        echo
    }
    
    # Main logic
    case "$1" in
        start)
            start
            ;;
        stop)
            stop
            ;;
        status)
            status
            ;;
        restart|reload)
            stop
            start
            ;;
      *)
        echo $"Usage: $0 {start|stop|status|restart|reload}"
        exit 1
    esac
    exit 0
    

    【讨论】:

    • 前几行的 cmets 是否必要? (例如 #Required-Stop: $java )是否有一些 cmets 解析?或者,这是一个每个人都在遵循的好习惯,并且代码在没有 cmets 的情况下也能正常工作?
    • 这些 cmets 是很好的实践,也可以供其他人分析使用您的应用程序需要什么。它们是否与游戏的最低要求相同……它们是否至关重要?不会。但它可以帮助那些将要使用它的人知道它需要能够使用什么。
    【解决方案3】:

    这取决于您的系统管理员

    在 debian/ubuntu 上执行此操作的最常见方法是构建一个 initscript 并将其放置在 /etc/init.d/etc/rc/init.d 中,然后在其中放置一个名为 mytestprogram 的脚本。

    这是一个示例初始化脚本:

    #!/bin/sh
    ### BEGIN INIT INFO
    # Provides:          testone
    # Required-Start:    $local_fs
    # Required-Stop:     $local_fs
    # Default-Start:     2 3 4 5
    # Default-Stop:      0 1 6
    # X-Interactive:     false
    # Short-Description: Example init script
    # Description:       Start/stop an example script
    ### END INIT INFO
    
    DESC="test script"
    NAME=testone
    #DAEMON=
    
    do_start()
    {
       echo "starting!";
    }
    
    do_stop()
    {
       echo "stopping!"
    }
    
    
    case "$1" in
       start)
         do_start
         ;;
       stop)
         do_stop
         ;;
    esac
    
    exit 0
    

    我建议你看看那个目录下的一些脚本,如果你懂一点 bash 就很简单;)

    【讨论】:

    • 那行得通。谢谢。让我也试试它是否适用于centOS系统
    • 还要记得设置文件可执行chmod +x filename
    • 前几行的 cmets 是否必要? (例如 #Required-Stop: $java )是否有一些 cmets 解析?或者,这是一个每个人都在遵循的好习惯,并且代码在没有 cmets 的情况下也能正常工作吗?
    • chkconfig mytestprogram on 呢?
    • 是否需要重启机器才能使这个脚本生效?我创建了一个提到的脚本,但无法立即使用。