Java项目启动检测 Redis 是否启动,未启动则启动(macOS 版本)

文章目录

一、概述

启动项目时,检测macos 上 Redis 是否启动,未启动,则启动。

二、代码

java 复制代码
/**
 * 用途: 项目启动时检查 redis,未启动则启动(开发环境)
 *
 * @author: ADAM
 * @create: 2024/04/28 14:45
 * @version: 1.0
 */
@Slf4j
@Component
@Profile("dev")
public class RedisServiceChecker implements CommandLineRunner {

    @Override
    public void run(String... args) throws Exception {
        boolean flag = isRedisRunning();
        log.info("Redis启动状态:" + flag);
        if (!flag) {
            startRedis();
        }
    }

    /**
     * 功能:检测 redis 是否启动
     * @param
     * @return: boolean
     * @author: ADAM
     * @date: 2024/4/28 15:15
     */
    private boolean isRedisRunning() {
        boolean hasRedis = false;
        try {
            // 整个命令作为一个List传给Runtime.getRuntime().exec(),避免字符串中嵌套引号和转义字符的问题
            String[] cmd = {"/bin/bash", "-c", "ps aux | grep redis-server"};
            Process process = Runtime.getRuntime().exec(cmd);

            // 读取命令的输出和错误输出
            BufferedReader stdoutReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
            BufferedReader stderrReader = new BufferedReader(new InputStreamReader(process.getErrorStream()));

            String line;

            // 同时读取输出和错误流
            while ((line = stdoutReader.readLine()) != null || (line = stderrReader.readLine()) != null) {
                if (line != null) {
                    log.info("line: " + line); // 打印出来帮助调试,看是否有预期的输出
                    if (line.trim().contains("redis-server") && !line.trim().contains("grep redis-server")) {
                        hasRedis = true;
                        break; // 找到有效Redis进程行,可以提前结束循环
                    }
                }
            }

            // 确保流关闭
            stdoutReader.close();
            stderrReader.close();

            // 检查是否找到Redis进程
            if (hasRedis) {
                log.info("Redis服务正在运行");
            } else {
                log.info("未找到Redis服务运行");
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        // 如果没有找到Redis进程,则认为Redis没有运行
        return hasRedis;
    }

    private void startRedis() throws IOException, InterruptedException {
        log.info("尝试启动Redis服务...");

        String redisBinaryPath = "redis-server";
        String[] command = {redisBinaryPath, "--daemonize", "yes"};

        ProcessBuilder pb = new ProcessBuilder(command);
        pb.redirectErrorStream(true); // 将错误输出重定向到标准输出,以便统一处理

        // 设置环境,以便sudo不提示输入密码(需要提前配置sudoers文件)
        Map<String, String> env = pb.environment();
        env.put("PASSWORD", "");

        // 启动进程
        Process process = pb.start();

        // 读取输出和错误流,用于日志或进一步处理
        BufferedReader stdoutReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
        BufferedReader stderrReader = new BufferedReader(new InputStreamReader(process.getErrorStream()));

        String line;
        while ((line = stdoutReader.readLine()) != null) {
            log.info("STDOUT: " + line);
        }
        while ((line = stderrReader.readLine()) != null) {
            log.error("STDERR: " + line);
        }

        // process.waitFor()的作用是阻塞当前线程,直到子进程(即启动的Redis服务)结束。
        int exitCode = process.waitFor();

        if (exitCode == 0) {
            log.info("Redis服务启动成功!");
        } else {
            log.error("Redis服务启动失败,退出码: " + exitCode);
        }

        // 确保流关闭
        stdoutReader.close();
        stderrReader.close();
    }
}
相关推荐
广州灵眸科技有限公司1 小时前
瑞芯微RV1126B开发板(EASY-EAI-PI2) INI文件操作
java·前端·javascript·网络·人工智能
库克克2 小时前
【C++ 】内联函数
java·开发语言·c++
zh_xuan2 小时前
java 虚拟线程
java·开发语言·虚拟线程
jason成都2 小时前
RTKLIB Java 移植踩坑复盘:卡尔曼滤波核心逻辑修复与滑坡场景实测验证
java·开发语言
Hyyy2 小时前
为什么 macOS 应用一换 Bundle ID,之前授予的权限就全失效了?
macos·electron
老毛肚3 小时前
juc线程通信
java·开发语言·jvm
p似笑非笑3 小时前
实战验证——把 SDK 塞进一个 macOS 原生 Agent 应用
macos
花颜yyds3 小时前
Java 开发基础速查手册
java
没钥匙的锁14 小时前
05-Java面向对象构造器与封装
java·开发语言
aaPIXa6224 小时前
C++采样引导优化SPGO——比PGO更智能的编译器决策新方案
java·c++·人工智能