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
Spring Boot 实现看门狗功能 (调用 Shell 脚本)的更多相关文章
- spring boot实现ssm(2)功能
spring 和 mybatis 整合的那篇: ssm(2) . 配置文件比ssm(1) 更多, 在做项目的时候, 配置文件是一个让人头大的事情. 那么在spring boot中, 实现相同功能, 需 ...
- Java 调用 shell 脚本详解
这一年的项目中,有大量的场景需要Java 进程调用 Linux的bash shell 脚本实现相关功能. 从之前的项目中拷贝的相关模块和网上的例子来看,有个别的“陷阱”造成调用shell 脚本在某些特 ...
- 【原】Gradle调用shell脚本和python脚本并传参
最近由于项目自动化构建的需要,研究了下gradle调用脚本并传参的用法,在此作个总结. Pre build.gradle中定义了$jenkinsJobName $jenkinsBuild两个Jenki ...
- 调用shell脚本,IP处理
//调用shell脚本,IP处理 package com.letv.sdns.web.utils; import org.slf4j.Logger; import org.slf4j.LoggerFa ...
- C程序调用shell脚本共有三种方法
C程序调用shell脚本共有三种法子 :system().popen().exec系列函数call_exec1.c ,内容为:system() 不用你自己去产生进程,它已经封装了,直接加入自己的命令e ...
- python调用shell脚本时需要切换目录
最近遇到了一个问题,就是python代码调用shell脚本时,发现输入输出的文件,总是和自己预想的有偏差,但是单独在linux下执行命令的时候,却没有错误.后来发现是相对路径的问题,因为执行pytho ...
- python调用shell脚本
# coding=utf-8 //设置文本格式import os //导入os方法print('hello')n=os.system('/home/csliyb/kjqy_x ...
- Centos下使用php调用shell脚本
我们在实际项目中或许会遇到php调用shell脚本的需求.下面就用简单案例在Centos环境下实践 准备 查看php.ini中配置是否打开安全模式 //php.ini safe_mode = //这个 ...
- Android应用程序如何调用shell脚本(一)
转自: Android应用程序如何调用shell脚本(一) 一般来说, Android 下的应用程序可以“直接”得到的最大的权限为 system ,但是如果我们需要在程序中执行某些需要 root 权限 ...
随机推荐
- 转载-Eclipse无法打开Eclipse MarketPlace的解决办法
问题描述: Eclipse点击 help-->Eclipse MarketPlace 后无任何反应,无报错,打不开 解决方法: 重新安装一下 epp MarketPlace help--> ...
- vscode实现远程linux服务器上Python开发
最近需要训练一个生成对抗网络模型,然后开发接口,不得不在一台有显卡的远程linux服务器上进行,所以,趁着这个机会研究了下怎么使用vscode来进行远程开发. 1 配置免密登录¶ (1)在 ...
- leetcode147median-of-two-sorted-arrays
题目描述 有两个大小分别为m和n的有序数组A和B.请找出这两个数组的中位数.你需要给出时间复杂度在O(log (m+n))以内的算法. There are two sorted arrays A an ...
- [.Net Core 3.0+/.Net 5] System.Text.Json中时间格式化
简介 .Net Core 3.0开始全新推出了一个名为System.Text.Json的Json解析库,用于序列化和反序列化Json,此库的设计是为了取代Json.Net(Newtonsoft.Jso ...
- Spring源码解析之BeanFactoryPostProcessor(一)
BeanFactoryPostProcessor 在前面几个章节,笔者有介绍过BeanFactoryPostProcessor,在spring在解析BeanDefinition之后,正式初始化bean ...
- 中介者模式及在NetCore中的使用MediatR来实现
在现实生活中,常常会出现好多对象之间存在复杂的交互关系,这种交互关系常常是"网状结构",它要求每个对象都必须知道它需要交互的对象.例如,每个人必须记住他(她)所有朋友的电话:而且, ...
- 简单STL
string: string s="5418340"; sort(s.begin(),s.end()); cout<<s; /**begin是头迭代器,end是尾迭代器 ...
- 变强——GitHub 热点速览 Vol.46
作者:HelloGitHub-小鱼干 网络不通怎么办?Ping 就是你的调试大招,而 gping 则是 Ping 的内功,终端可视化显示 Ping 结果,一眼看明数据接收情况.前端调试大招又是什么呢? ...
- ubuntu13.04修改默认启动内核
ubuntu下面的启动内核选项跟其他操作系统不一样,有个子菜单,比如我在默认的ubuntu13.04上安装了一个新的内核3.14.5,那么默认的第一项是3.14.5内核,第二项是一个子菜单,第二项里面 ...
- [原题复现]-HITCON 2016 WEB《babytrick》[反序列化]
前言 不想复现的可以访问榆林学院信息安全协会CTF训练平台找到此题直接练手 HITCON 2016 WEB -babytrick(复现) 原题 index.php 1 <?php 2 3 inc ...