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

 更新时间:2020年06月12日 17:27:10   作者:VictorBu  
这篇文章主要介绍了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 看门狗内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 基于jdbc处理Clob的使用介绍

    基于jdbc处理Clob的使用介绍

    本篇文章是对jdbc处理Clob的使用进行了分析介绍,需要的朋友参考下
    2013-05-05
  • 一起聊聊Java中的自定义异常

    一起聊聊Java中的自定义异常

    在学习Java的过程中,想必大家都一定学习过异常这个篇章,异常的基本特性和使用这里就不再多讲了。本文就来和大家讲讲如何自定义异常
    2022-08-08
  • Java8中Stream流求最大值最小值的实现示例

    Java8中Stream流求最大值最小值的实现示例

    本文主要介绍了Java8中Stream流求最大值最小值的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-04-04
  • idea离线使用jrebel的超详细教程

    idea离线使用jrebel的超详细教程

    IDEA上原生是不支持热部署的,一般更新了 Java 文件后要手动重启 Tomcat 服务器,才能生效,下面通过本文给大家分享idea离线使用jrebel的超详细教程(亲测有效),感兴趣的朋友一起看看吧
    2020-12-12
  • SpringBoot中的声明式事务详解

    SpringBoot中的声明式事务详解

    这篇文章主要介绍了SpringBoot中的声明式事务详解,Spring采用统一的机制来处理不同的数据访问技术的事务, Spring的事务提供一个PlatformTransactionManager的接口,不同的数据访问技术使用不同的接口实现,需要的朋友可以参考下
    2023-08-08
  • idea构建web项目的超级详细教程

    idea构建web项目的超级详细教程

    好多朋友在使用IDEA创建项目时,总会碰到一些小问题,下面这篇文章主要给大家介绍了关于idea构建web项目的超级详细教程,文中通过图文介绍的非常详细,需要的朋友可以参考下
    2023-03-03
  • 细说Springcloud eureka的几种主动下线服务的方式

    细说Springcloud eureka的几种主动下线服务的方式

    这篇文章主要介绍了细说Springcloud eureka的几种主动下线服务的方式,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-09-09
  • Java实现AOP代理的三种方式详解

    Java实现AOP代理的三种方式详解

    AOP是一种设计思想,是软件设计领域中的面向切面编程,它是面向对象编程的一种补充和完善。本文将用Java实现AOP代理的三种方式,需要的可以参考一下
    2022-07-07
  • Java实现一个简易聊天室流程

    Java实现一个简易聊天室流程

    这篇文章主要介绍了我的java课程设计一个多人聊天室(socket+多线程)本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-11-11
  • java实现MapReduce对文件进行切分的示例代码

    java实现MapReduce对文件进行切分的示例代码

    本文主要介绍了java实现MapReduce对文件进行切分的示例代码,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-01-01

最新评论