在Linux上作为服务运行Java应用程序

在Linux上作为服务运行Java应用程序,java,linux,service,Java,Linux,Service,我已经编写了一个Java服务器应用程序,它运行在一个标准的虚拟托管Linux解决方案上。应用程序一直在运行,监听套接字连接并为其创建新的处理程序。它是客户机-服务器应用程序的服务器端实现 我启动它的方式是将它包含在服务器的startup rc.local脚本中。但是,一旦启动,我不知道如何访问它来停止它,如果我想安装更新,所以我必须重新启动服务器才能重新启动应用程序 在windows PC上,对于这种类型的应用程序,我可以创建一个windows服务,然后根据需要停止和启动它。Linux机器上是否

我已经编写了一个Java服务器应用程序,它运行在一个标准的虚拟托管Linux解决方案上。应用程序一直在运行,监听套接字连接并为其创建新的处理程序。它是客户机-服务器应用程序的服务器端实现

我启动它的方式是将它包含在服务器的startup rc.local脚本中。但是,一旦启动,我不知道如何访问它来停止它,如果我想安装更新,所以我必须重新启动服务器才能重新启动应用程序

在windows PC上,对于这种类型的应用程序,我可以创建一个windows服务,然后根据需要停止和启动它。Linux机器上是否有类似的东西,这样如果我启动这个应用程序,我就可以停止并重新启动它,而无需完全重新启动服务器

我的应用程序名为WebServer.exe。它是在服务器启动时通过将其包含在my rc.local中启动的,如下所示:


我在Linux上有点不修边幅,所以任何文章中的例子都会受到欢迎。但是,我有SSH和完全的FTP访问权,可以安装任何更新,也可以访问Plesk面板。

另一种选择,也是非常流行的是。这在OSS社区中也非常流行

然而,一旦开始,我不知道如何访问它来阻止它

您可以编写一个简单的停止脚本,用于greps您的java进程、提取PID并对其调用kill。这不是幻想,而是直截了当的。 这样的事情可能会有帮助:

#!/bin/bash
PID = ps ax | grep "name of your app" | cut -d ' ' -f 1
kill $PID

Linux服务初始化脚本存储在
/etc/init.d
中。您可以复制和自定义
/etc/init.d/skeleton
文件,然后调用

service [yourservice] start|stop|restart

看。它适用于Debian(也适用于Ubuntu),但更适合发行版。

一个简单的解决方案是创建一个脚本start.sh,通过nohup运行Java,然后将PID存储到一个文件中:

nohup java -jar myapplication.jar > log.txt 2> errors.txt < /dev/null &
PID=$!
echo $PID > pid.txt

当然,我省略了一些细节,比如检查进程是否存在,如果完成了,则删除
pid.txt

您可以使用Java服务或与Java服务通信。

我在这里编写了另一个简单的包装:

#!/bin/sh
SERVICE_NAME=MyService
PATH_TO_JAR=/usr/local/MyProject/MyJar.jar
PID_PATH_NAME=/tmp/MyService-pid
case $1 in
    start)
        echo "Starting $SERVICE_NAME ..."
        if [ ! -f $PID_PATH_NAME ]; then
            nohup java -jar $PATH_TO_JAR /tmp 2>> /dev/null >> /dev/null &
            echo $! > $PID_PATH_NAME
            echo "$SERVICE_NAME started ..."
        else
            echo "$SERVICE_NAME is already running ..."
        fi
    ;;
    stop)
        if [ -f $PID_PATH_NAME ]; then
            PID=$(cat $PID_PATH_NAME);
            echo "$SERVICE_NAME stoping ..."
            kill $PID;
            echo "$SERVICE_NAME stopped ..."
            rm $PID_PATH_NAME
        else
            echo "$SERVICE_NAME is not running ..."
        fi
    ;;
    restart)
        if [ -f $PID_PATH_NAME ]; then
            PID=$(cat $PID_PATH_NAME);
            echo "$SERVICE_NAME stopping ...";
            kill $PID;
            echo "$SERVICE_NAME stopped ...";
            rm $PID_PATH_NAME
            echo "$SERVICE_NAME starting ..."
            nohup java -jar $PATH_TO_JAR /tmp 2>> /dev/null >> /dev/null &
            echo $! > $PID_PATH_NAME
            echo "$SERVICE_NAME started ..."
        else
            echo "$SERVICE_NAME is not running ..."
        fi
    ;;
esac 
您可以阅读init.d和systemd(ubuntu 16+)的完整教程

如果需要输出日志,请更换
2

nohup java -jar $PATH_TO_JAR /tmp 2>> /dev/null >> /dev/null &
排队等候

nohup java -jar $PATH_TO_JAR >> myService.out 2>&1&

从中,我可以推荐基于Python的
supervisord
应用程序。有关更多信息,请参阅堆栈溢出问题。它的设置非常简单。

可能不是最好的开发运营解决方案,但适合于局域网或类似组织的服务器的一般使用

使用
screen
在中运行服务器,然后在注销前分离,这将保持进程运行,然后您可以随时重新连接

工作流:

启动屏幕:
屏幕

启动您的服务器:
java-jar minecraft server.jar

按分离:
Ctl-a
d

重新连接:
屏幕-r


这里有更多信息:

也指的是,我会选择
systemd
版本,因为它是最简单、最不冗长、最适合集成到现代发行版(甚至是CentOS 7.x等不太现代的发行版)中的版本。

最简单的方法是使用
supervisords
。详情请参阅:

更多信息:


其他答案可以根据您的平台提供自定义脚本和设置。除此之外,以下是我所知道的成熟的特殊用途项目:

  • 来自TanukiSoftware的JSW
  • 是上面的开源克隆。它是用Java编写的,是一个保姆进程,根据配置管理子进程(您的代码)。适用于windows/linux
  • 是本机应用程序。它也是一个保姆流程,但它通过JNI调用您的子应用程序,而不是作为子流程

    • 这是一个示例shell脚本(请确保用应用程序的名称替换数学名称):


      要将Java代码作为守护进程(服务)运行,您可以编写基于JNI的存根

      对于基于JNI的示例代码。在本例中,您将作为Java启动的代码守护,主循环用C执行。但也可以将主、守护程序的服务循环放在Java中

      享受JNI带来的乐趣

      来自

      作为init.d服务安装(SystemV) 只需将jar符号链接到
      init.d
      ,即可支持标准的
      启动
      停止
      重启
      状态
      命令。 假设您在/var/myapp中安装了Spring引导应用程序,要将Spring引导应用程序作为init.d服务安装,只需创建一个符号链接:

      $ sudo ln -s /var/myapp/myapp.jar /etc/init.d/myapp
      
      安装后,您可以按常规方式启动和停止服务。例如,在基于Debian的系统上:

      $ service myapp start
      
      如果应用程序无法启动,请检查写入
      /var/log/的日志文件,以了解如何保护已部署的服务

      按照所写的方式执行后,我发现我的服务无法启动,日志中有以下错误消息:。我通过创建一个包含以下内容的配置文件
      /var/myapp/myapp.conf
      来修复它

      USE_START_STOP_DAEMON=false
      

      可以将war作为Linux服务运行,您可能希望在打包之前强制输入pom.xml文件,因为某些发行版可能无法在自动模式下识别。为此,在SpringBootMaven插件中添加以下属性

                          <embeddedLaunchScriptProperties>
                              <mode>service</mode>
                          </embeddedLaunchScriptProperties>
      
      你就能跑了

      service myapp start|stop|restart
      

      您还可以在中找到许多其他选项,包括Windows服务。

      我有Netty java应用程序,我想将其作为systemd的服务运行。不幸的是,无论我使用的是哪种类型,应用程序都会停止。最后,我在屏幕中包装了java start。以下是配置文件:

      服务

      [Unit]
      Description=Netty service
      After=network.target
      [Service]
      User=user
      Type=forking
      WorkingDirectory=/home/user/app
      ExecStart=/home/user/app/start.sh
      TimeoutStopSec=10
      Restart=on-failure
      RestartSec=5
      [Install]
      WantedBy=multi-user.target
      
      开始

      #/垃圾箱/垃圾箱
      /usr/bin/screen-L-dmS netty_app java-cp app.jar类路径
      
                          <embeddedLaunchScriptProperties>
                              <mode>service</mode>
                          </embeddedLaunchScriptProperties>
      
      ln -s myapp.war /etc/init.d/myapp
      
      service myapp start|stop|restart
      
      [Unit]
      Description=Netty service
      After=network.target
      [Service]
      User=user
      Type=forking
      WorkingDirectory=/home/user/app
      ExecStart=/home/user/app/start.sh
      TimeoutStopSec=10
      Restart=on-failure
      RestartSec=5
      [Install]
      WantedBy=multi-user.target