帮忙出一个 多线程在实际项目中的示例
下文笔者讲述使用多线程处理日志文件压缩和移动的示例分享
日志文件压缩和移动
项目结构 log-processing/ ├── src/ │ └── main/ │ └── java/ │ └── com/ │ └── example/ │ └── logprocessing/ │ ├── LogProcessor.java │ ├── LogTask.java │ └── MainApp.java ├── logs/ │ └── access_20231010.log ├── target/ │ └── logs/ │ └── access_20231010.log.tar.gz └── pom.xml
1.`LogTask.java`
`LogTask`类实现`Callable`接口 用于处理单个日志文件的压缩和移动操作 package com.example.logprocessing; import java.io.File; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.concurrent.Callable; import java.util.zip.GZIPOutputStream; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; public class LogTask implements Callable<Boolean> { private final File logFile; private final Path targetDir; public LogTask(File logFile, Path targetDir) { this.logFile = logFile; this.targetDir = targetDir; } @Override public Boolean call() throws Exception { try { // 构建压缩文件名 Path compressedFilePath = targetDir.resolve(logFile.getName() + ".tar.gz"); // 压缩文件 compressFile(logFile.toPath(), compressedFilePath); // 删除原日志文件 if (logFile.delete()) { System.out.println("Deleted original log file: " + logFile.getAbsolutePath()); return true; } else { System.err.println("Failed to delete original log file: " + logFile.getAbsolutePath()); return false; } } catch (IOException e) { System.err.println("Error processing log file: " + logFile.getAbsolutePath()); e.printStackTrace(); return false; } } private void compressFile(Path source, Path target) throws IOException { try (ZipOutputStream zos = new ZipOutputStream(new GZIPOutputStream(Files.newOutputStream(target)))) { ZipEntry zipEntry = new ZipEntry(source.getFileName().toString()); zos.putNextEntry(zipEntry); byte[] bytes = Files.readAllBytes(source); zos.write(bytes, 0, bytes.length); zos.closeEntry(); } } }
2.`LogProcessor.java`
`LogProcessor`类负责管理线程池 分配任务并监控任务的执行情况
package com.example.logprocessing; import java.io.File; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.Arraylist; import java.util.List; import java.util.concurrent.*; public class LogProcessor { private final Path logDir; private final Path targetDir; private final ExecutorService executorService; public LogProcessor(String logDirPath, String targetDirPath, int threadPoolSize) { this.logDir = Paths.get(logDirPath); this.targetDir = Paths.get(targetDirPath); this.executorService = Executors.newFixedThreadPool(threadPoolSize); } public void processLogs() { try { // 获取前一天的日期 String yesterday = java.time.LocalDate.now(). minusDays(1).format(java.time.format.DateTimeFormatter.ofPattern("yyyyMMdd")); // 创建目标目录(如果不存在) Files.createDirectories(targetDir); // 获取前一天的日志文件 File[] logFiles = logDir.toFile(). listFiles((dir, name) -> name.contains(yesterday)); if (logFiles == null || logFiles.length == 0) { System.out.println("No log files found for " + yesterday); return; } // 提交任务到线程池 List<Future<Boolean>> futures = new ArrayList<>(); for (File logFile : logFiles) { LogTask task = new LogTask(logFile, targetDir); futures.add(executorService.submit(task)); } // 等待所有任务完成 for (Future<Boolean> future : futures) { try { if (future.get()) { System.out.println("Log file processed successfully."); } else { System.err.println("Log file processing failed."); } } catch (InterruptedException | ExecutionException e) { System.err.println("Error processing log file."); e.printStackTrace(); } } } catch (IOException e) { System.err.println("Error creating target directory."); e.printStackTrace(); } finally { executorService.shutdown(); } } }
3.`MainApp.java`
`MainApp` 类是应用程序的入口 负责初始化`LogProcessor` 并调用`processLogs`方法 package com.example.logprocessing; public class MainApp { public static void main(String[] args) { // 定义日志目录和目标目录 String logDirPath = "/usr/local/tomcat/DCH_CUBE/logs"; String targetDirPath = "/data/nasdisk/applogs/DCH_CUBE"; // 定义线程池大小 int threadPoolSize = 5; // 初始化 LogProcessor LogProcessor logProcessor = new LogProcessor(logDirPath, targetDirPath, threadPoolSize); // 处理日志文件 logProcessor.processLogs(); } }
4.`pom.xml`(Maven 项目)
使用Maven来管理项目 可添加以下`pom.xml`文件
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.example</groupId> <artifactId>log-processing</artifactId> <version>1.0-SNAPSHOT</version> <properties> <maven.compiler.source>11</maven.compiler.source> <maven.compiler.target>11</maven.compiler.target> </properties> <dependencies> <!-- 添加必要的依赖项 --> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.8.1</version> </plugin> </plugins> </build> </project>
5.配置cron任务
使用 cron 任务每天凌晨运行该脚本。 1.编辑cron任务: sudo crontab -e 2.添加cron任务: 0 1 * * * /usr/bin/java -cp /path/to/log-processing.jar com.example.logprocessing.MainApp >> /var/log/log_processing.log 2>&1 - `0 1 * * *`:每天凌晨1点运行脚本。 - `/usr/bin/java -cp /path/to/log-processing.jar com.example.logprocessing.MainApp`: 运行 Java 应用程序。 - `>> /var/log/log_processing.log 2>&1`:将标准输出和标准错误输出重定向到日志文件。 3.保存并退出: - 在 `vi` 或 `nano` 中保存并退出编辑器
版权声明
本文仅代表作者观点,不代表本站立场。
本文系作者授权发表,未经许可,不得转载。