缘故:有一台服务器上有个mysql,外部访问不到,另外此服务器性能不好,原本使用jdbc游标批量将数据拉出处理,可执行一段时间就出线连接过多、tmp等问题。最后采用mysql将数据导出到csv,再读取csv处理后结束,性能直接提示多少倍,爽!
Java执行命令程序
package com.funmz.vos2gaid2black.task;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import java.io.File;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
@Slf4j
public class ShellExecutor {
public static boolean executeMysqlToCsv(String tableName) {
try {
// 定义命令数组
String[] cmd = {
"bash", "-c",
// 因为此服务器封闭,且无外部端口开放,此数据也没有设置密码等安全问题。
"mysql -N -u root -Nse \"SELECT DISTINCT SUBSTR(calleee164, LENGTH(calleee164) - 10) AS tphone FROM vos3000." + tableName + " WHERE endreason = -93\" | sed 's/^/\"/;s/$/\"/' > /root/taskjar/tempcsv/" + tableName + ".csv"
};
log.info("执行命令:{}", JSON.toJSONString(cmd));
// 创建 ProcessBuilder 实例
ProcessBuilder processBuilder = new ProcessBuilder(cmd);
processBuilder.directory(new File("/root/taskjar/tempcsv")); // 设置工作目录(可选)
// 合并错误流到标准输出(可选)
processBuilder.redirectErrorStream(true);
// 启动进程
Process process = processBuilder.start();
// 等待命令执行完成
// int exitCode = process.waitFor();
boolean waitFor = process.waitFor(1L, TimeUnit.MINUTES);
if (!waitFor) {
log.error("执行超时,请检查命令是否正确。");
}
// System.out.println("Shell command exited with code: " + exitCode);
// System.out.println("Shell command exited with waitFor: " + waitFor);
log.info("Shell command exited with waitFor: " + waitFor);
return waitFor;
// if (exitCode == 0) {
// System.out.println("CSV 文件生成成功!");
// } else {
// System.err.println("执行失败,请检查 MySQL 连接或权限问题。");
// }
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
return false;
}
}