【问题标题】:Check if jar running from shell检查 jar 是否从 shell 运行
【发布时间】:2013-12-08 17:15:01
【问题描述】:

我有一个 java jar 程序,我试图在我的机器启动时运行它。理想情况下,shell 脚本将每 60 秒检查一次以确保 jar 正在运行。如何检查 jar 是否在 centos 上运行,这似乎不起作用?

我当前的 .sh 文件:

#!/bin/bash

while [ true ]
do
    cnt=`ps -eaflc --sort stime | grep /home/Portal.jar |grep -v grep | wc -l`
    if(test $cnt -eq 3);
    then
        echo "Service already running..."
    else
        echo "Starting Service"
        java -jar /home/Portal.jar >> /dev/null &
    fi
    sleep 1m
done

到目前为止,我使用this 进行引用。

【问题讨论】:

  • 它似乎不起作用是什么意思?究竟是什么问题?
  • 它总是去启动服务。它无法检测程序是否已经在运行

标签: java shell sh executable-jar


【解决方案1】:

根据您的程序的功能,可能有或多或少的智能方法来检查它。例如,如果你有一些服务器,它会监听一个端口。

然后类似

netstat -an | fgrep tcp | fgrep LISTEN | fgrep :87654   # or whatever your port is

可以胜任。

然后是lsof,它也可以检测监听端口。

最后,您可以连接并发出伪请求。例如,对于 http 服务器,您可以使用 lynxcurl。对于具有非标准协议的服务器,您可以编写一个小型客户端程序,其唯一目的是连接到服务器,只是为了查看它是否存在。

【讨论】:

    【解决方案2】:

    将您的进程 ID 存储在文件中并检查此进程。

    #!/bin/bash
    
    while [ true ]
    do
        pid=$(cat /tmp/portal.pid)
        if [[ -n "$pid" && $(ps -p $pid | wc -l) -eq 2 ]]
        then
            echo "Service already running..."
        else
            echo "Starting Service"
            java -jar /home/Portal.jar >> /dev/null &
            echo $! > /tmp/portal.pid
        fi
        sleep 1m
    done
    

    /tmp 将在重启时被清除,在这种情况下可以。

    【讨论】:

    • 将 pid 存储在文件中不是很干净。其他一些进程可能会更改文件,文件可能会损坏,或者该进程甚至可能获得新的 pid。有很多事情可能会出错,所以我真的建议使用其他解决方案
    【解决方案3】:

    几个月前我也做过同样的事情。我的任务是确保 jar 分布式 java 程序在 Linux 服务器上 24/7 运行。 我的程序是基于控制台的,启动,做了一些事情然后停止了。 我做了一个 shell 脚本,它开始,等待结束,然后在无限循环中重新启动应用程序。 我安装了 runit,创建了一个服务并将这个脚本作为运行脚本提供。效果很好。 一般来说,shell 脚本确保 java 程序正在运行,而 runit 确保启动脚本(也就是我们的脚本)正在运行。

    您可以在这里找到有价值的信息:http://smarden.org/runit/faq.html

    【讨论】:

      【解决方案4】:

      与其让进程进入睡眠状态,我宁愿让它退出并使用 crontab 每 1 分钟运行一次进程;这将检查它是否正在运行,否则只是停止脚本。

      #!/bin/sh
      declare -a devId=( "/Path/To/TestJar.jar Test1" "/Path/To/TestJar.jar Test2" ) #jarfile with pathname and Test as argument
      # get length of an array
      arraylength=${#devId[@]}
      # use for loop to read all values and indexes
      for (( i=1; i<${arraylength}+1; i++ ));
      do
      y=${devId[$i-1]}
      cnt=`ps -eaflc --sort stime | grep "$y" |grep -v grep | wc -l`
      if [ $cnt = 0 ]
      then
      java -jar $y& > /dev/null
      b=$(basename $y)
      echo $b 
      #DO SOME OPERATION LIKE SEND AN EMAIL OR ADD TO LOG FILE
      continue
      elif [ $cnt != 0 ]
      then
      echo 'do nothing'
      fi
      done
      

      【讨论】:

        【解决方案5】:

        为什么你认为$cnt 应该等于3?如果进程已经在运行,它不应该等于1吗?

        【讨论】:

        • 在执行 pgrep java 时,它运行了 3 个进程
        • 问题似乎来自:test: -eq: unary operator expected
        • 但是pgrep java 并不是您的命令实际执行的操作!您正在寻找特定的应用程序!我会这样做if [ $cnt -eq 1 ]。您需要对脚本的某些部分进行试验,直到它们正常工作,而不仅仅是运行您的脚本并祈祷。
        【解决方案6】:

        您可以使用jps 命令。它返回系统中运行的 JVM。

        【讨论】:

          【解决方案7】:

          我创建了以下脚本来监控我的应用程序 jar 是否正在运行。 在这种情况下,我的应用程序 jar 正在端口 8080 上运行

          #!/bin/bash
          check=$(netstat -an | grep 8080 | wc -l)
          if [[ $check -eq 0 ]];then
              echo "jar is not running..."
              /usr/bin/java -jar /path/to/target/application.jar >> /dev/null &
          else
              echo "it is running"
          fi
          

          我正在使用 cronjob 通过每分钟执行一次 shell 脚本来监控 jar 应用程序。

          $ crontab -e
          

          在文件末尾

          * * * * * /bin/bash monitor-jar.sh /dev/null 2>&1
          

          【讨论】:

            猜你喜欢
            • 2017-08-01
            • 1970-01-01
            • 2014-09-12
            • 1970-01-01
            • 2011-06-04
            • 2010-12-08
            • 2012-08-23
            • 2017-10-17
            • 2012-11-14
            相关资源
            最近更新 更多