Spring Boot调用 Shell 脚本实现看门狗功能

需要实现看门狗功能,定时检测另外一个程序是否在运行,使用 crontab 仅可以实现检测程序是否正在运行,无法做到扩展,如:手动重启、程序升级(如果只需要实现自动升级功能可以使用 inotify)等功能;最后决定使用 Spring Boot 调用 Shell 脚本来实现

一、脚本

1.1 启动脚本

#!/bin/bash

ps -ef | grep "demo-app-0.0.1-SNAPSHOT.jar" | grep -v "grep"

if [ "$?" -eq 0 ]
then

# sleep
echo $(date "+%Y-%m-%d %H:%M:%S") "process already started!"

else

nohup java -jar -server /project/watchdog/demo-app-0.0.1-SNAPSHOT.jar &
echo $(date "+%Y-%m-%d %H:%M:%S") "process has been started!"

fi

1.2 重启脚本

#!/bin/bash

pid=`ps -ef | grep "demo-app-0.0.1-SNAPSHOT.jar" | grep -v "grep" | awk '{print $2}'`

for id in $pid
do
 kill -9 $id
 echo "killed $id"
done

nohup java -jar -server /project/watchdog/demo-app-0.0.1-SNAPSHOT.jar &
echo $(date "+%Y-%m-%d %H:%M:%S") "process has been restarted!"

二、功能实现

将脚本放置在程序的资源目录下,每次程序启动时将脚本读取到指定位置,然后再通过定时任务执行脚本

配置内容:

shell:
 directory: /project/watchdog
 startupFileName: startup.sh
 restartFileName: restart.sh
@Configuration
@ConfigurationProperties(prefix = "shell")
public class ShellProperties {

 private String directory;
 private String startupFileName;
 private String restartFileName;

 /* getter & setter */

 public String getFullName(String fileName) {
  return directory + File.separator + fileName;
 }
}

2.1 启动时将脚本读取到指定位置

@Component
public class InitRunner implements CommandLineRunner {

 @Autowired
 private ShellProperties shellProperties;

 @Autowired
 ResourceLoader resourceLoader;

 @Override
 public void run(String... args) throws Exception {
  generateFile(shellProperties.getStartupFileName());
  generateFile(shellProperties.getRestartFileName());
 }

 private void generateFile(String fileName) throws IOException {

  String fileFullName = shellProperties.getFullName(fileName);
  File file = new File(fileFullName);
  if(file.exists()) {
   return;
  }

  // 如果文件已存在,FileWriter 会先删除再新建
  FileWriter fileWriter = new FileWriter(fileFullName);

  Resource resource = resourceLoader.getResource("classpath:" + fileName);
  InputStream inputStream = resource.getInputStream();
  InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
  BufferedReader bufferedReader = new BufferedReader(inputStreamReader);

  String data;
  while ((data = bufferedReader.readLine()) != null) {
   fileWriter.write(data + "\n");
  }

  bufferedReader.close();
  inputStreamReader.close();
  inputStream.close();

  fileWriter.close();

  // 设置权限,否则会报 Permission denied
  file.setReadable(true);
  file.setWritable(true);
  file.setExecutable(true);
 }
}

2.2 定时任务定时任务执行脚本

@Component
public class ShellTask {

 private static final Logger logger = LoggerFactory.getLogger(ShellTask.class);

 @Autowired
 private ShellProperties shellProperties;

 @Scheduled(cron = "0/10 * * * * ? ")
 public void start() throws IOException {
  executeShell(shellProperties.getStartupFileName());
 }

 private void executeShell(String fileName) throws IOException {

  String fileFullName = shellProperties.getFullName(fileName);
  File file = new File(fileFullName);
  if(!file.exists()) {
   logger.error("file {} not existed!", fileFullName);
   return;
  }

  ProcessBuilder processBuilder = new ProcessBuilder(fileFullName);
  processBuilder.directory(new File(shellProperties.getDirectory()));

  Process process = processBuilder.start();

//  String input;
//  BufferedReader stdInput = new BufferedReader(new InputStreamReader(process.getInputStream()));
//  BufferedReader stdError = new BufferedReader(new InputStreamReader(process.getErrorStream()));
//  while ((input = stdInput.readLine()) != null) {
//   logger.info(input);
//  }
//  while ((input = stdError.readLine()) != null) {
//   logger.error(input);
//  }

  int runningStatus = 0;
  try {
   runningStatus = process.waitFor();
  } catch (InterruptedException e) {
   logger.error("shell", e);
  }

  if(runningStatus != 0) {
   logger.error("failed.");
  }else {
   logger.info("success.");
  }
 }
}

2.3 扩展

本例只实现了定时检测程序是否运行,如果没有运行则启动程序;如有需要可以添加接口,调用接口重启程序;或者添加定时任务定时检测程序是否有更新,如果有更新则下载新的 jar 包然后重启程序

看门狗程序自己可以使用 crontab 定时检测是否正在运行,模仿上面的启动脚本编写看门狗的启动脚本,然后添加定时任务:

crontab -e
*/10 * * * * /project/watchdog/watchdog.sh
sudo systemctl reload crond.service

完整代码:GitHub

参考:java去调用并执行shell脚本以及问题总结

总结

到此这篇关于Spring Boot调用 Shell 脚本实现看门狗功能的文章就介绍到这了,更多相关spring boot 看门狗内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 详解spring boot 以jar的方式启动常用shell脚本

    用spring boot框架做的项目,将第三方包全部打在jar里面,通过shell脚本启动和停止服务,常用的shell脚本模板如下: #!/bin/bash JAVA_OPTIONS_INITIAL=-Xms128M JAVA_OPTIONS_MAX=-Xmx512M _JAR_KEYWORDS=monitor-alarm-task-1.0-SNAPSHOT.jar APP_NAME=monitor-alarm-task APPLICATION_FILE=/opt/scpip_monitor/a

  • Linux 启动停止SpringBoot jar 程序部署Shell 脚本的方法

    废话不多说了,先给大家上代码,具体代码如下所示: #!/bin/bash cd `dirname $0` CUR_SHELL_DIR=`pwd` CUR_SHELL_NAME=`basename ${BASH_SOURCE}` #修改这里jar包名即可 JAR_NAME="xxxxxxxxxxxx.jar" JAR_PATH=$CUR_SHELL_DIR/$JAR_NAME #JAVA_MEM_OPTS=" -server -Xms1024m -Xmx1024m -XX:Pe

  • springboot打包不同环境配置以及shell脚本部署的方法

    前言 本篇和大家分享的是springboot打包并结合shell脚本命令部署,重点在分享一个shell程序启动工具,希望能便利工作: profiles指定不同环境的配置 maven-assembly-plugin打发布压缩包 分享shenniu_publish.sh程序启动工具 linux上使用shenniu_publish.sh启动程序 profiles指定不同环境的配置 通常一套程序分为了很多个部署环境:开发,测试,uat,线上 等,我们要想对这些环境区分配置文件,可以通过两种方式: 通过a

  • Spring Boot调用 Shell 脚本实现看门狗功能

    需要实现看门狗功能,定时检测另外一个程序是否在运行,使用 crontab 仅可以实现检测程序是否正在运行,无法做到扩展,如:手动重启.程序升级(如果只需要实现自动升级功能可以使用 inotify)等功能:最后决定使用 Spring Boot 调用 Shell 脚本来实现 一.脚本 1.1 启动脚本 #!/bin/bash ps -ef | grep "demo-app-0.0.1-SNAPSHOT.jar" | grep -v "grep" if [ "$

  • 利用Python+Java调用Shell脚本时的死锁陷阱详解

    前言 最近有一项需求,要定时判断任务执行条件是否满足并触发 Spark 任务,平时编写 Spark 任务时都是封装为一个 Jar 包,然后采用 Shell 脚本形式传入所需参数执行,考虑到本次判断条件逻辑复杂,只用 Shell 脚本完成不利于开发测试,所以调研使用了 Python 和 Java 分别调用 Spark 脚本的方法. 使用版本为 Python 3.6.4 及 JDK 8 Python 主要使用 subprocess 库.Python 的 API 变动比较频繁,在 3.5 之后新增了

  • Java远程调用Shell脚本并获取输出信息【推荐】

    1.添加依赖 <dependency> <groupId>ch.ethz.ganymed</groupId> <artifactId>ganymed-ssh2</artifactId> <version>262</version> </dependency> <dependency> <groupId>commons-io</groupId> <artifactId&g

  • Spring boot调用Oracle存储过程的两种方式及完整代码

    前言 因工作需要将公司SSH项目改为Spingboot项目,将项目中部分需要调用存储过程的部分用entityManagerFactory.unwrap(SessionFactory.class).openSession()来获取Session实现后发现项目访问数据库超过十次就会挂掉,原因是Springboot连接池数量默认为10,猜测是每次访问数据库后连接未释放导致的,手动关闭session后问题解决. 解决问题的过程中又发现了另外两种调用方式: 直接用EntityManager的createS

  • java调用shell脚本及注意事项说明

    目录 需求 问题 介绍 1.通过ProcessBuilder进行调度 2.直接通过系统的Runtime类执行shell 遇到的问题 1.没权限运行 2.调用shell脚本提示:No such file or directory 3.shell脚本输出太大,程序卡死问题 下面提供工具类和自己的shell脚本 工具类 shell脚本 需求 get方法下载远程zip包,然后zip包解压,取出第一级目录再次进行压缩获取新的压缩zip包. 问题 如果选择使用java代码的IO流操作,在不确定zip包大小的

  • 常用的Spring Boot调用外部接口方式实现数据交互

    目录 springboot调用外部接口常用的方式 1.使用原始httpClient请求 2.使用RestTemplate请求 1.get请求 2.post请求 3.使用Feign请求 4.小结 springboot调用外部接口常用的方式 在系统开发过程中,免不了要去调用第三方接口,springboot为我们提供了几种调用第三方接口的方法 1.使用原始httpClient请求 <dependency> <groupId>org.apache.httpcomponents</gr

  • Spring Boot + thymeleaf 实现文件上传下载功能

    最近同事问我有没有有关于技术的电子书,我打开电脑上的小书库,但是邮件发给他太大了,公司又禁止用文件夹共享,于是花半天时间写了个小的文件上传程序,部署在自己的Linux机器上. 提供功能: 1 .文件上传 2.文件列表展示以及下载 原有的上传那块很丑,写了点js代码优化了下,最后界面显示如下图: 先给出成果,下面就一步步演示怎么实现. 1.新建项目 首先当然是新建一个spring-boot工程,你可以选择在网站初始化一个项目或者使用IDE的Spring Initialier功能,都可以新建一个项目

  • Spring Boot 利用WebUploader进行文件上传功能

    Web Uploader简介 WebUploader是由Baidu WebFE(FEX)团队开发的一个简单的以HTML5为主,FLASH为辅的现代文件上传组件.在现代的浏览器里面能充分发挥HTML5的优势,同时又不摒弃主流IE浏览器,沿用原来的FLASH运行时,兼容IE6+,iOS 6+, android 4+.两套运行时,同样的调用方式,可供用户任意选用.采用大文件分片并发上传,极大的提高了文件上传效率. 我们这里使用官网的一个例子来实现我们个人头像的上传. 我们的重点是在Spring Boo

  • Spring Boot/Angular整合Keycloak实现单点登录功能

    Keycloak Keycloak为现代应用和服务提供开源的认证和访问管理,即通常所说的认证和授权.Keycloak支持OpenID.OAuth 2.0和SAML 2.0协议:支持用户注册.用户管理.权限管理:支持代理OpenID.SAML 2.0 IDP,支持GitHub.LinkedIn等第三方登录,支持整合LDAP和Active Directory:支持自定义认证流程.自定义用户界面,支持国际化. Keycloak支持Java.C#.Python.Android.iOS.JavaScrip

  • spring boot实现自动输出word文档功能的实例代码

    spring boot实现自动输出word文档功能 本文用到Apache POI组件 组件依赖在pom.xml文件中添加 <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>4.1.0</version> </dependency> <dependency> <groupId&

随机推荐