# fileupload **Repository Path**: xiaoyis/fileupload ## Basic Information - **Project Name**: fileupload - **Description**: FileUpload是一个高性能、可配置的自动化文件上传监控系统,专为企业级文件传输场景设计。该系统能够实时监控指定目录及其子目录下的文件变化,自动识别符合条件的文件并上传至配置的远程服务器,同时提供完整的日志记录和异常处理机制。 - **Primary Language**: Java - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 0 - **Created**: 2025-10-28 - **Last Updated**: 2025-11-02 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # FileUpload - 自动文件上传系统 ## 项目概述 FileUpload是一个高性能、可配置的自动化文件上传监控系统,专为企业级文件传输场景设计。该系统能够实时监控指定目录及其子目录下的文件变化,自动识别符合条件的文件并上传至配置的远程服务器,同时提供完整的日志记录和异常处理机制。 ## 核心功能与特性 - **实时文件监控**:高效监控指定目录及其子目录的文件变化 - **多协议支持**:同时支持FTP和SFTP两种远程传输协议 - **多服务器配置**:支持配置多个远程服务器,实现负载均衡或备份传输 - **智能文件过滤**:基于文件后缀名灵活筛选需要上传的文件 - **可靠的上传机制**:完善的连接管理、自动重连和上传失败重试机制 - **灵活的后处理策略**:支持上传完成后删除、移动文件或创建完成标记文件 - **高性能批处理**:使用批量处理优化数据库操作性能 - **多存储策略**:支持MySQL和Redis等多种日志存储方式 - **完整的日志记录**:详细记录所有上传操作,包括文件信息、上传状态、耗时统计等 - **可配置的性能参数**:支持调整批处理大小、延迟时间、处理速率等性能参数 - **服务器分配策略**:支持轮询等多种服务器分发模式 - **安全的凭证管理**:支持配置多服务器的认证信息 ## 系统架构 系统采用模块化设计,主要包含以下核心模块: 1. **监控模块** - 负责监控本地目录,发现新文件 2. **上传模块** - 负责将文件上传到远程服务器 3. **线程管理** - 统一管理监控和上传线程 4. **文件处理** - 处理上传完成后的文件(删除或移动) 5. **异常处理** - 提供统一的异常处理和重试机制 6. **日志记录** - 记录上传详情到数据库 ## 技术栈 - Java 1.8+ - Spring Boot 2.7.13 - MyBatis(数据库操作) - Redis(缓存支持) - Disruptor(高性能队列) - SLF4J + Logback(日志) - Lombok(代码简化) - MySQL(数据库) - FTP/SFTP(文件传输协议) - JUnit 5 + Mockito(单元测试) ## 核心功能 ### 1. 文件监控 - 支持监控多个目录 - 基于文件匹配模式过滤文件 - 可配置的监控间隔 ### 2. 多服务器支持 - 支持配置多个远程服务器 - 服务器故障时自动切换备用服务器 - 可定制的服务器连接参数 ### 3. 可靠上传 - 上传失败自动重试机制 - 指数退避策略 - 详细的上传日志记录 - 支持FTP/SFTP协议 ### 4. 文件处理 - 上传成功后自动删除源文件 - 上传成功后移动源文件到指定目录 - 可配置的完成标记文件 ### 5. 线程管理 - 统一的线程池管理 - 任务提交和取消功能 - 线程生命周期管理 ### 6. 批量日志处理 - 高性能批量日志收集 - 异步批量插入数据库 - 可配置的批处理参数 ### 7. REST API接口 - 文件上传日志查询接口 - 监控状态管理接口 - 上传任务管理接口 ### 8. Redis缓存支持 - 用于提升系统性能 - 支持分布式部署场景 ## 快速开始 ### 环境要求 - JDK 1.8 或更高版本 - Maven 3.6+ 或 Gradle 7+ - 支持的数据库(MySQL为主) - Redis(可选,用于缓存和分布式场景) ### 配置说明 系统支持通过 `application.yml` 或 `fileupload.yml` 进行配置。以下是详细的配置文件示例: #### 1. application.yml 示例 ```yaml spring: datasource: url: jdbc:mysql://localhost:3306/fileupload?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai username: root password: password driver-class-name: com.mysql.cj.jdbc.Driver redis: host: localhost port: 6379 password: database: 0 server: port: 8080 servlet: context-path: /fileupload # 应用配置 fileupload: # 日志配置 log: database-enabled: true storage-strategy: mysql # 可选: mysql, redis # 批量处理配置 batch: enabled: true interval-minutes: 1 record-threshold: 100 max-batch-size: 1000 max-retry-count: 3 retry-interval-ms: 1000 ``` #### 2. fileupload.yml 示例 ```yaml fileupload: servers: # FTP/SFTP服务器列表 - name: CDRsrv1 # 服务器名称 addr: 10.0.3.193 # IP地址和端口 username: idcltgxb # 用户名 passwd: idcltgxb # 密码 protocol: ftp # 上传协议(填写ftp或者sftp) ftp-mode: passive # 服务器模式(填写passive或者initiative)(仅作用于protocol为ftp时) dir: /data/ftpsite # 上传目录(sftp必须填写绝对路径,ftp可以填写绝对路径或相对路径) finish-flag: ok # 上传完成标记文件 file-suffix: info # 上传完成后文件名 archive: date # 上传子目录(目录不存在时会自动创建) monitor-group: # 监控列表 - name: CDRmonitor-1 # 监控组名 enable: yes # 是否启用(填写yes或者no) monitor-dir: /home/data # 监控目录(包括子目录的文件) monitor-file-suffix: ok,txt # 监控文件后缀 upload-file-suffix: txt # 上传文件后缀 servers-primer: CDRsrv1 # 上传服务器 finish-act: delete # 上传完成后文件处理(delete:删除文件,keep:保留文件,same-move:相同目录移动,time-based:基于时间的相同目录移动,relative-path:基于相对路径的相同目录移动,diff-move:不同目录移动,diff-move-time:基于时间的不同目录移动,diff-move-path:基于相对路径的不同目录移动) move-to: /home/backup/ # 上传完成后文件存放路径 batch: insert: enabled: true # 是否启用批量插入功能 interval-minutes: 1 # 批量插入时间间隔(分钟) record-threshold: 100 # 批量插入记录数阈值 max-batch-size: 1000 # 单次批量插入的最大记录数 max-retry-count: 3 # 插入失败时的最大重试次数 retry-interval-ms: 1000 # 重试间隔时间(毫秒) log: log-type: mysql # 日志类型(mysql或redis) enabled: true # 是否启用日志入库功能 ``` #### 3. 数据库表结构 系统启动时会自动创建必要的数据库表,也可以手动执行 `src/main/resources/schema.sql` 文件创建数据库表: ```sql CREATE TABLE IF NOT EXISTS `file_upload_log` ( `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID', `task_id` varchar(64) DEFAULT NULL COMMENT '任务ID', `monitor_name` varchar(64) DEFAULT NULL COMMENT '监控组名', `upload_file_name` varchar(255) DEFAULT NULL COMMENT '上传文件名', `local_file_path` varchar(500) DEFAULT NULL COMMENT '本地文件路径', `remote_file_path` varchar(500) DEFAULT NULL COMMENT '远程文件路径', `server_name` varchar(64) DEFAULT NULL COMMENT '服务器名称', `status` varchar(20) DEFAULT NULL COMMENT '上传状态', `file_size` bigint(20) DEFAULT NULL COMMENT '文件大小(字节)', `upload_time` bigint(20) DEFAULT NULL COMMENT '上传开始时间', `finish_time` bigint(20) DEFAULT NULL COMMENT '上传完成时间', `cost_time` bigint(20) DEFAULT NULL COMMENT '耗时(毫秒)', `error_message` varchar(500) DEFAULT NULL COMMENT '错误信息', `retry_count` int(11) DEFAULT NULL COMMENT '重试次数', `insert_time` bigint(20) DEFAULT NULL COMMENT '记录插入时间', PRIMARY KEY (`id`), INDEX `idx_monitor_name` (`monitor_name`), INDEX `idx_status` (`status`), INDEX `idx_server_name` (`server_name`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='文件上传日志表'; ``` #### 4. 配置文件优先级说明 - 如果同时存在 `application.yml` 和 `fileupload.yml`,系统会加载两个文件的配置 - `fileupload.yml` 主要用于配置服务器和监控信息 - `application.yml` 主要用于配置Spring Boot相关信息(数据源、Redis、服务器端口等) - 可以通过启动参数 `--spring.config.location` 指定自定义配置文件路径: ```bash java -jar file-upload-monitor-1.0-SNAPSHOT.jar --spring.config.location=/path/to/custom/application.yml,/path/to/custom/fileupload.yml ``` ### 运行系统 #### 1. 编译打包 ```bash # 编译打包(跳过测试) mvn clean package -DskipTests # 编译打包(包含测试) mvn clean package ``` #### 2. 启动系统 ```bash # 基本启动方式 java -jar target/file-upload-monitor-1.0-SNAPSHOT.jar # 指定自定义配置文件启动 java -jar file-upload-monitor-1.0-SNAPSHOT.jar --spring.config.location=/path/to/application.yml,/path/to/fileupload.yml # 设置JVM参数启动 java -Xms512m -Xmx1024m -jar file-upload-monitor-1.0-SNAPSHOT.jar # 在后台运行 nohup java -jar file-upload-monitor-1.0-SNAPSHOT.jar > upload.log 2>&1 & # 使用Maven直接运行 mvn spring-boot:run ``` #### 3. 验证系统运行状态 系统启动成功后,可以通过以下方式验证: 1. 查看日志输出,确认监控器正常启动 2. 访问健康检查接口(如果已配置):`http://localhost:8080/fileupload/actuator/health` 3. 在监控目录下创建符合条件的文件,检查是否自动上传到远程服务器 4. 查看数据库中的上传日志记录 ## API 使用示例 ### 启动监控器 ```java MonitorConfig config = new MonitorConfig(); config.setName("monitor-1"); config.setMonitorDir("/path/to/monitor"); config.setMonitorFileSuffix(".txt"); config.setServersPrimer("server1"); monitorManager.startMonitor(config); ``` ### 停止监控器 ```java monitorManager.stopMonitor("monitor-1"); ``` ### 手动上传文件 ```java File file = new File("/path/to/file.txt"); MonitorConfig config = new MonitorConfig(); config.setServersPrimer("server1"); fileUploadService.uploadFile(file, config); ``` ## 配置项说明 ### 1. 监控配置 | 配置项 | 说明 | 默认值 | |-------|------|-------| | name | 监控组名 | - | | enable | 是否启用(yes或no) | - | | monitorDir | 监控目录 | - | | monitorFileSuffix | 监控文件后缀 | - | | uploadFileSuffix | 上传文件后缀 | - | | serversPrimer | 上传服务器 | - | | serverDispatchMode | 上传服务器分配模式 | - | | finishAct | 上传完成后文件处理(delete、move) | delete | | moveTo | 上传完成后文件存放路径 | - | | maxRetries | 最大重试次数 | 3 | | retryDelay | 重试延迟时间(毫秒) | 1000 | | createFinishFlag | 是否创建完成标记文件 | false | | batchSize | 批处理大小 | 50 | | batchDelayMs | 批处理延迟(毫秒) | 100 | | maxProcessRate | 每秒最大处理事件数 | 100 | | maxDepth | 最大监控深度 | 5 | | maxDirectories | 最大监控目录数 | 1000 | | incrementalScanInterval | 增量扫描间隔(秒) | 60 | #### 1.1 finishAct 说明 - DeleteFileStrategy ("delete"): - 功能:删除文件 - 效果:直接删除源文件 - 特点:操作简单,不依赖targetDir参数 - KeepFileStrategy ("keep"): - 功能:保留文件 - 效果:不做任何操作,直接返回成功 - 特点:默认策略,不依赖targetDir参数 - SameMoveFileStrategy ("same-move"): - 功能:相同目录结构移动 - 效果:将文件移动到目标目录,但实际上没有保留目录结构,只是简单移动文件 - 特点:使用StandardCopyOption.REPLACE_EXISTING覆盖已存在的文件 - DiffMoveFileStrategy ("diff-move"): - 功能:不同目录移动 - 效果:将文件移动到目标目录,实现和SameMoveFileStrategy几乎相同 - 特点:使用FileUtils.ensureDirectoryExists创建目录,不使用REPLACE_EXISTING选项 - DiffMovePathFileStrategy ("diff-move-path"): - 功能:基于相对路径的不同目录移动 - 效果:将文件移动到目标目录,并保留原始相对路径结构 - 特点:会根据监控目录计算相对路径,保留部分目录结构 - DiffMoveTimeFileStrategy ("diff-move-time"): - 功能:基于时间的不同目录移动 - 效果:将文件移动到目标目录下的日期子目录中 - 特点:使用LocalDate.now()创建YYYY-MM-DD格式的子目录 - TimeBasedMoveFileStrategy ("time-based"): - 功能:基于时间的移动 - 效果:将文件移动到目标目录下的时间结构子目录中 - 特点:使用yyyy/MM/dd/HH格式的时间目录结构 - RelativePathMoveFileStrategy ("relative-path"): - 功能:基于相对路径的移动 - 效果:将文件移动到目标目录,并完全保留原始相对路径结构 - 特点:保留完整的相对路径结构 ### 2. 服务器配置 | 配置项 | 说明 | 默认值 | |-------|------|----------------| | name | 服务器名称 | - | | addr | IP地址和端口 | - | | username | 用户名 | - | | passwd | 密码 | - | | protocol | 上传协议(ftp或sftp) | - | | ftpMode | 服务器模式(仅FTP有效,passive或initiative) | - | | dir | 上传目录 | - | | finishFlag | 上传完成标记文件 | - | | finishFlagContent | 上传完成标记文件内容 | - | | fileSuffix | 上传完成后文件名 | - | | compress | 压缩格式 | - | | archive | 上传子目录 | date、path、具体目录 | | remoteBasePath | 远程基础路径 | - | #### 2.1 archive 说明 - date:根据当前日期创建子目录,格式为YYYY-MM-DD - path:根据文件路径创建子目录,保留原始路径结构 比如说:监控目录是/home/data/,上传到服务器的dir:/data/xiaoyi/ /home/data/123/456/1.txt 到服务器会自动创建123/456目录 最终为/data/xiaoyi/123/456/1.txt - 具体目录:指定一个具体的目录作为上传子目录 ### 3. 批量日志处理配置 | 配置项 | 说明 | 默认值 | |-------|------|-------| | enabled | 是否启用批量插入功能 | true | | intervalMinutes | 定时任务执行的时间间隔(分钟) | 1 | | recordThreshold | 触发批量插入的记录数阈值 | 100 | | maxBatchSize | 批量插入的最大记录数限制 | 1000 | | maxRetryCount | 重试次数 | 3 | | retryIntervalMs | 重试间隔(毫秒) | 1000 | | logStorageStrategy | 日志存储策略(mysql、redis等) | mysql | | logDatabaseEnabled | 是否启用日志数据库存储 | true ### 4. 日志配置 | 配置项 | 说明 | 默认值 | |-------|------|-------| | log-type | 日志类型,指定日志存储方式 | mysql、redis | | enabled | 是否启用日志入库功能 | true、false | ## 故障排除 ### 常见问题 1. **监控器启动失败**:检查监控目录是否存在且有读写权限 2. **上传失败**:检查远程服务器配置和网络连接 3. **数据库连接问题**:验证数据库连接字符串和凭据 4. **Redis连接问题**:检查Redis服务是否运行以及连接配置是否正确 5. **批量日志处理异常**:检查批处理配置参数是否合理 ### 日志说明 系统使用SLF4J记录日志,主要日志包括: - 监控事件日志 - 文件上传日志 - 错误和异常日志 - 连接状态日志 ## 开发指南 ### 项目结构 ``` src/main/java/com/fileupload/ ├── FileUploadApplication.java # 应用程序入口类 ├── common/ # 公共组件和工具类 │ ├── FileUtils.java # 文件操作工具类 │ └── Result.java # 统一响应结果类 ├── config/ # 配置类 │ ├── ApplicationConfig.java # Spring应用配置 │ ├── BatchInsertConfig.java # 批量日志插入配置 │ ├── ConfigReader.java # 配置读取器 │ ├── MonitorConfig.java # 监控配置 │ └── ServerConfig.java # 服务器配置 ├── exception/ # 异常处理 │ ├── FileUploadException.java # 文件上传异常 │ └── RetryUtil.java # 重试工具类 ├── mapper/ # MyBatis映射器 │ └── FileUploadLogMapper.java # 上传日志映射器 ├── model/ # 数据模型 │ └── entity/ # 实体类 │ ├── FileUploadLog.java # 文件上传日志实体 │ └── UploadStatus.java # 上传状态枚举 ├── monitor/ # 文件监控 │ ├── FileChangeListener.java # 文件变更监听器 │ ├── FileMonitor.java # 文件监控接口 │ ├── MonitorManager.java # 监控管理器 │ ├── NioFileMonitor.java # NIO实现的文件监控(使用JDK WatchService) │ └── UploadFileChangeListener.java # 上传文件变更监听器 ├── process/ # 文件处理 │ ├── FileAction.java # 文件操作接口 │ ├── FileProcessService.java # 文件处理服务接口 │ ├── FileProcessServiceImpl.java # 文件处理服务实现 │ └── strategy/ # 文件处理策略 ├── server/ # 服务器连接 │ ├── Connection.java # 连接接口 │ ├── ConnectionFactory.java # 连接工厂 │ ├── ConnectionManager.java # 连接管理器 │ ├── FtpConnection.java # FTP连接实现 │ ├── ProtocolType.java # 协议类型枚举 │ └── SftpConnection.java # SFTP连接实现 ├── thread/ # 线程管理 │ └── ThreadManager.java # 线程管理器 └── upload/ # 文件上传 ├── FileUploadService.java # 文件上传服务接口 ├── FileUploadServiceImpl.java # 文件上传服务实现 └── log/ # 上传日志及相关API ├── BatchLogCollectorService.java # 批量日志收集服务 ├── BatchLogInsertTask.java # 批量日志插入任务 ├── FileUploadLogController.java # 上传日志控制器 ├── FileUploadLogService.java # 上传日志服务接口 ├── FileUploadLogServiceImpl.java # 上传日志服务实现 └── strategy/ # 日志存储策略 ├── LogStorageStrategy.java # 日志存储策略接口 ├── LogStorageStrategyFactory.java # 日志存储策略工厂 ├── MysqlLogStorageStrategy.java # MySQL存储策略 └── RedisLogStorageStrategy.java # Redis存储策略 ``` ### 测试 运行单元测试: ```bash mvn test ``` ### 构建 构建项目: ```bash mvn clean package ``` 生成的JAR包位于 `target` 目录下,文件名为 `file-upload-monitor-1.0-SNAPSHOT.jar` ## 许可证 [MIT License](LICENSE) ## 贡献 欢迎提交Issue和Pull Request!贡献前请确保代码风格一致并添加适当的测试用例。 ## 版本历史 - 1.0.0-SNAPSHOT(当前版本) - 初始版本发布 - 支持FTP/SFTP协议上传 - 实现文件监控和自动上传 - 支持批量日志处理 - 支持多种日志存储策略