JAVA 定时启停 nginx

本文介绍了如何使用Java编写一个定时任务脚本来自动管理Nginx服务,根据设定的时间(工作日9点启动,18点关闭)执行启停操作。代码中包含获取当前日期、判断工作日以及执行Nginx命令等功能,确保服务按需运行。
摘要由CSDN通过智能技术生成


前言

由于业务需求,需要在固定时间启动关闭nginx,现要求上班时间每天早上9点启动nginx,下午18点关停nginx,周末都是关停。我就想着用原生java 来写个定时任务。
本项目只有一个java 单文件,简单发布运行。


一、准备环境

使用 idea 新建一个普通java 项目,代码见文章末尾, idea 一般会自动编译后在工程目录生成 out 目录(编译后的class文件),如果没有可以手动编译。
在这里插入图片描述

二、使用步骤

1.打包发布

把编译后的目录 dingshi_rw 压缩上传到 nginx 服务器后解压。
在这里插入图片描述

2.编写启动脚本

进入 dingshi_rw 目录编写启动脚本 start.sh。
脚本内容是:

nohup java cn.com.liyx.dingshi.Dingshi > dingshi.log &

在这里插入图片描述
在这里插入图片描述

3. 运行

运行脚本如果提示 Could not find or load main class … 有可能是环境变量 CLASSPATH 配置有问题。

在这里插入图片描述

3.1 CLASSPATH 环境变量

在/etc/profile 文件添加 CLASSPATH 配置(有很多种配置方式,这是其一)
在这里插入图片描述
在这里插入图片描述

4.最终效果

星期五下午 18 点关闭 nginx
在这里插入图片描述
星期一 早上9 点启动 nginx
在这里插入图片描述

总结

本代码的星期几获取片段是参考网上的,看着挺复杂。
本逻辑没有每次都去检查运行状态,是为了有时候需要手动启停一段时间时,不会冲突。
启停环节和状态检查环节没有在同一轮周期,状态检查环节是在启停环节的下一个周期,为了避免脚本执行后,nginx 状态没有及时更新造成信息不一致。
使用一个内部类作为 状态 信息存储。

代码

package cn.com.liyx.dingshi;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.text.SimpleDateFormat;
import java.util.*;

public class Dingshi {
    private static final int upTimeBegin = 9;  // 运行开始时间
    private static final int upTimeEnd = 18;   // 运行结束时间
    private static final String PS =  " ps aux | grep nginx ";  // 查看进程
    private static final String runNginx = "/usr/local/nginx/sbin/nginx" ;  // 启动 nginx
    private static final SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    public static void main(String[] args) {

        new Timer().schedule(new TimerTask() {
            @Override
            public void run() {
                Date date = new Date();
                String format = sf.format(date);
                Calendar now = Calendar.getInstance();

                //一周第一天是否为星期天
                boolean isFirstSunday = (now.getFirstDayOfWeek() == Calendar.SUNDAY);
                //获取周几
                int weekDay = now.get(Calendar.DAY_OF_WEEK);
                int hour = now.get(Calendar.HOUR_OF_DAY);
                //若一周第一天为星期天,则-1
                if(isFirstSunday){
                    weekDay = weekDay - 1;
                    if(weekDay == 0){
                        weekDay = 7;
                    }
                }
                System.out.println("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
                System.out.println("当前时间:"+ format + " 星期:" + weekDay + "; "+ hour + " 时, " + "当前 nginx 运行线程ID: " + StateInfo.pid);
                /* -------------------------- */
                checkUpTimeNow(hour, weekDay);
                if(StateInfo.needCheck){
                    System.out.println(" 需要检查运行状态! ");
                    checkUpStateNow();
                    StateInfo.needCheck = false;     // 不用再检查
                }else {
                    System.out.println(" 不需要检查运行状态! ");
                    if(StateInfo.upTimeNow && !StateInfo.upStateNow){
                        // 启动
                        System.out.println("开始启动!");
                        startUp();        // 启动
                        StateInfo.needCheck = true;  // 需要重新检查运行状态
                    }
                    if(!StateInfo.upTimeNow && StateInfo.upStateNow){
                        // 关闭
                        System.out.println("开始关闭!");
                        checkUpStateNow();  // 关闭之前进行进程检查, 避免其他方式重启应用, 进程ID变化
                        shutDown(StateInfo.pid);
                        StateInfo.needCheck = true;  // 需要重新检查运行状态
                    }
                }
            }
        },0, 60 * 1000);   // 60 秒执行一次
    }

    /**
     *
     * @param hour
     *
     */
    public static void checkUpTimeNow(int hour, int week){
        boolean ct = false;
        if(week != 6 && week != 7){   // 排除周末
            if(Dingshi.upTimeBegin <= hour && hour < Dingshi.upTimeEnd){
                ct = true;
            }
        }
        System.out.println(" checkUpTimeNow 是否运行时间 " + ct);
        StateInfo.upTimeNow = ct;
    }

    public static void checkUpStateNow(){
        boolean r = false;  // 是否运行
        String p = "";  // 线程id
        try {
            String[] cmd = new String[]{"/bin/sh", "-c", Dingshi.PS};
            Process ps = Runtime.getRuntime().exec(cmd);

            BufferedReader br = new BufferedReader(new InputStreamReader(ps.getInputStream()));
            StringBuffer sb = new StringBuffer();
            String line;
            while ((line = br.readLine()) != null) {
                if(line.contains(Dingshi.runNginx) && line.contains("master")){
                    r = true;   // 已启动
                    String[] split = line.split("\\s+");
                    p = split[1];   // 获取线程id
                }
                //执行结果加上回车
                sb.append(line).append("\n");
            }
            String result = sb.toString();
            System.out.println("方法 checkUpStateNow 结果:\n" + result + "\n当前是否运行 " + r + " 线程id: " + p);

        } catch (Exception e) {
            e.printStackTrace();
        }
        StateInfo.pid = p;
        StateInfo.upStateNow = r;
    }

    public static void startUp(){
        String[] cmd = new String[]{"/bin/sh", "-c", Dingshi.runNginx};
        try {
            Process ps = Runtime.getRuntime().exec(cmd);
        } catch (IOException e) {
            e.printStackTrace();
        }
        System.out.println("+++++++++++++++++ startUp 启动完成 ");
    }

    /**
     *
     * @param pid  线程 id
     */
    public static void shutDown(String pid){
        String[] cmd = new String[]{"/bin/sh", "-c", " kill " + pid};
        try {
            Process ps = Runtime.getRuntime().exec(cmd);
        } catch (IOException e) {
            e.printStackTrace();
        }
        System.out.println("+++++++++++++++++ shutDown 关闭完成 pid : " + pid);

    }

}

/**
 * 状态信息对象
 */
class StateInfo {
    public static boolean needCheck = true;  // 是否需要检查状态
    public static boolean upTimeNow = false;  // 当前是否运行时间
    public static boolean upStateNow = false; // 当前是否是运行状态
    public static String pid = "";  // 运行的线程id

}

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值