歡迎您光臨本站 註冊首頁

Spring Boot調用 Shell 腳本實現看門狗功能

←手機掃碼閱讀     qp18502452 @ 2020-06-13 , reply:0

需要實現看門狗功能,定時檢測另外一個程序是否在運行,使用 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 + " ");   }     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

                                

   


[qp18502452 ] Spring Boot調用 Shell 腳本實現看門狗功能已經有242次圍觀

http://coctec.com/docs/linux/show-post-238378.html