文章目录
一、概述
启动项目时,检测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();
}
}