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();
    }
}
相关推荐
&白帝&37 分钟前
JAVA JDK7时间相关类
java·开发语言·python
2301_8187320640 分钟前
用layui表单,前端页面的样式正常显示,但是表格内无数据显示(数据库连接和获取数据无问题)——已经解决
java·前端·javascript·前端框架·layui·intellij idea
狄加山6751 小时前
系统编程(线程互斥)
java·开发语言
星迹日1 小时前
数据结构:二叉树—面试题(二)
java·数据结构·笔记·二叉树·面试题
组合缺一1 小时前
solon-flow 你好世界!
java·solon·oneflow
HHhha.1 小时前
JVM深入学习(二)
java·jvm
叩叮ING1 小时前
正则表达式中常见的贪婪词
java·服务器·正则表达式
组合缺一2 小时前
Solon Cloud Gateway 开发:熟悉 Completable 响应式接口
java·gateway·reactor·solon
组合缺一2 小时前
Solon Cloud Gateway 开发:Route 的配置与注册方式
java·gateway·reactor·solon
娶个名字趴2 小时前
Redis(5,jedis和spring)
数据库·redis·缓存